summaryrefslogtreecommitdiffstats
path: root/contrib/file/src
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2014-12-11 06:52:10 +0000
committerdelphij <delphij@FreeBSD.org>2014-12-11 06:52:10 +0000
commit504cc95e05d4edf7e1615ae450c370f6cc7a96ae (patch)
treeaa6fb81cc2801f9f2db10c5217ec3c495278f249 /contrib/file/src
parent6eef5a7d4dabee1d90f7bb9993b3f7f438e5aba5 (diff)
parent2e5be0fdd11aef0d2cb0d88c71946b953019f313 (diff)
downloadFreeBSD-src-504cc95e05d4edf7e1615ae450c370f6cc7a96ae.zip
FreeBSD-src-504cc95e05d4edf7e1615ae450c370f6cc7a96ae.tar.gz
MFV r275696: file 5.21.
MFC after: 2 weeks
Diffstat (limited to 'contrib/file/src')
-rw-r--r--contrib/file/src/Makefile.in8
-rw-r--r--contrib/file/src/apprentice.c230
-rw-r--r--contrib/file/src/ascmagic.c5
-rw-r--r--contrib/file/src/cdf.c115
-rw-r--r--contrib/file/src/cdf.h23
-rw-r--r--contrib/file/src/compress.c38
-rw-r--r--contrib/file/src/elfclass.h8
-rw-r--r--contrib/file/src/encoding.c3
-rw-r--r--contrib/file/src/file.c65
-rw-r--r--contrib/file/src/file.h29
-rw-r--r--contrib/file/src/file_opts.h1
-rw-r--r--contrib/file/src/fsmagic.c10
-rw-r--r--contrib/file/src/funcs.c22
-rw-r--r--contrib/file/src/getline.c16
-rw-r--r--contrib/file/src/magic.c63
-rw-r--r--contrib/file/src/magic.h12
-rw-r--r--contrib/file/src/magic.h.in10
-rw-r--r--contrib/file/src/pread.c15
-rw-r--r--contrib/file/src/readcdf.c95
-rw-r--r--contrib/file/src/readelf.c21
-rw-r--r--contrib/file/src/softmagic.c143
-rw-r--r--contrib/file/src/vasprintf.c12
22 files changed, 737 insertions, 207 deletions
diff --git a/contrib/file/src/Makefile.in b/contrib/file/src/Makefile.in
index 970ff0b..f1779f9 100644
--- a/contrib/file/src/Makefile.in
+++ b/contrib/file/src/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -81,9 +81,9 @@ build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = file$(EXEEXT)
subdir = src
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am pread.c \
- ctime_r.c getline.c vasprintf.c asprintf.c asctime_r.c \
- fmtcheck.c strlcpy.c getopt_long.c strcasestr.c strlcat.c \
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am strcasestr.c \
+ pread.c strlcpy.c vasprintf.c getopt_long.c asctime_r.c \
+ strlcat.c ctime_r.c getline.c asprintf.c fmtcheck.c \
$(top_srcdir)/depcomp $(include_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
diff --git a/contrib/file/src/apprentice.c b/contrib/file/src/apprentice.c
index 71e9af6..cfea6be 100644
--- a/contrib/file/src/apprentice.c
+++ b/contrib/file/src/apprentice.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.211 2014/06/03 19:01:34 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.227 2014/11/28 02:46:39 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -86,6 +86,10 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.211 2014/06/03 19:01:34 christos Exp $")
#define ALLOC_CHUNK (size_t)10
#define ALLOC_INCR (size_t)200
+#define MAP_TYPE_MMAP 0
+#define MAP_TYPE_MALLOC 1
+#define MAP_TYPE_USER 2
+
struct magic_entry {
struct magic *mp;
uint32_t cont_count;
@@ -101,6 +105,7 @@ struct magic_entry_set {
struct magic_map {
void *p;
size_t len;
+ int type;
struct magic *magic[MAGIC_SETS];
uint32_t nmagic[MAGIC_SETS];
};
@@ -131,7 +136,10 @@ private uint16_t swap2(uint16_t);
private uint32_t swap4(uint32_t);
private uint64_t swap8(uint64_t);
private char *mkdbname(struct magic_set *, const char *, int);
+private struct magic_map *apprentice_buf(struct magic_set *, struct magic *,
+ size_t);
private struct magic_map *apprentice_map(struct magic_set *, const char *);
+private int check_buffer(struct magic_set *, struct magic_map *, const char *);
private void apprentice_unmap(struct magic_map *);
private int apprentice_compile(struct magic_set *, struct magic_map *,
const char *);
@@ -396,10 +404,11 @@ add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
{
struct mlist *ml;
+ mlp->map = idx == 0 ? map : NULL;
if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL)
return -1;
- ml->map = idx == 0 ? map : NULL;
+ ml->map = NULL;
ml->magic = map->magic[idx];
ml->nmagic = map->nmagic[idx];
@@ -416,13 +425,11 @@ add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
private int
apprentice_1(struct magic_set *ms, const char *fn, int action)
{
-#ifndef COMPILE_ONLY
- struct mlist *ml;
-#endif /* COMPILE_ONLY */
struct magic_map *map;
#ifndef COMPILE_ONLY
+ struct mlist *ml;
size_t i;
-#endif /* COMPILE_ONLY */
+#endif
if (magicsize != FILE_MAGICSIZE) {
file_error(ms, 0, "magic element size %lu != %lu",
@@ -451,22 +458,29 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
for (i = 0; i < MAGIC_SETS; i++) {
if (add_mlist(ms->mlist[i], map, i) == -1) {
file_oomem(ms, sizeof(*ml));
- apprentice_unmap(map);
- return -1;
+ goto fail;
}
}
if (action == FILE_LIST) {
for (i = 0; i < MAGIC_SETS; i++) {
- printf("Set %zu:\nBinary patterns:\n", i);
+ printf("Set %" SIZE_T_FORMAT "u:\nBinary patterns:\n",
+ i);
apprentice_list(ms->mlist[i], BINTEST);
printf("Text patterns:\n");
apprentice_list(ms->mlist[i], TEXTTEST);
}
}
-#endif /* COMPILE_ONLY */
-
return 0;
+fail:
+ for (i = 0; i < MAGIC_SETS; i++) {
+ mlist_free(ms->mlist[i]);
+ ms->mlist[i] = NULL;
+ }
+ return -1;
+#else
+ return 0;
+#endif /* COMPILE_ONLY */
}
protected void
@@ -510,6 +524,10 @@ file_ms_alloc(int flags)
ms->mlist[i] = NULL;
ms->file = "unknown";
ms->line = 0;
+ ms->indir_max = FILE_INDIR_MAX;
+ ms->name_max = FILE_NAME_MAX;
+ ms->elf_shnum_max = FILE_ELF_SHNUM_MAX;
+ ms->elf_phnum_max = FILE_ELF_PHNUM_MAX;
return ms;
free:
free(ms);
@@ -521,17 +539,21 @@ apprentice_unmap(struct magic_map *map)
{
if (map == NULL)
return;
- if (map->p != NULL) {
+
+ switch (map->type) {
#ifdef QUICK
- if (map->len)
+ case MAP_TYPE_MMAP:
+ if (map->p)
(void)munmap(map->p, map->len);
- else
+ break;
#endif
+ case MAP_TYPE_MALLOC:
free(map->p);
- } else {
- uint32_t j;
- for (j = 0; j < MAGIC_SETS; j++)
- free(map->magic[j]);
+ break;
+ case MAP_TYPE_USER:
+ break;
+ default:
+ abort();
}
free(map);
}
@@ -550,21 +572,70 @@ mlist_alloc(void)
private void
mlist_free(struct mlist *mlist)
{
- struct mlist *ml;
+ struct mlist *ml, *next;
if (mlist == NULL)
return;
- for (ml = mlist->next; ml != mlist;) {
- struct mlist *next = ml->next;
+ ml = mlist->next;
+ for (ml = mlist->next; (next = ml->next) != NULL; ml = next) {
if (ml->map)
apprentice_unmap(ml->map);
free(ml);
- ml = next;
+ if (ml == mlist)
+ break;
}
- free(ml);
}
+#ifndef COMPILE_ONLY
+/* void **bufs: an array of compiled magic files */
+protected int
+buffer_apprentice(struct magic_set *ms, struct magic **bufs,
+ size_t *sizes, size_t nbufs)
+{
+ size_t i, j;
+ struct mlist *ml;
+ struct magic_map *map;
+
+ if (nbufs == 0)
+ return -1;
+
+ if (ms->mlist[0] != NULL)
+ file_reset(ms);
+
+ init_file_tables();
+
+ for (i = 0; i < MAGIC_SETS; i++) {
+ mlist_free(ms->mlist[i]);
+ if ((ms->mlist[i] = mlist_alloc()) == NULL) {
+ file_oomem(ms, sizeof(*ms->mlist[i]));
+ goto fail;
+ }
+ }
+
+ for (i = 0; i < nbufs; i++) {
+ map = apprentice_buf(ms, bufs[i], sizes[i]);
+ if (map == NULL)
+ goto fail;
+
+ for (j = 0; j < MAGIC_SETS; j++) {
+ if (add_mlist(ms->mlist[j], map, j) == -1) {
+ file_oomem(ms, sizeof(*ml));
+ goto fail;
+ }
+ }
+ }
+
+ return 0;
+fail:
+ for (i = 0; i < MAGIC_SETS; i++) {
+ mlist_free(ms->mlist[i]);
+ ms->mlist[i] = NULL;
+ }
+ return -1;
+}
+#endif
+
/* const char *fn: list of magic files and directories */
protected int
file_apprentice(struct magic_set *ms, const char *fn, int action)
@@ -590,11 +661,9 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
mlist_free(ms->mlist[i]);
if ((ms->mlist[i] = mlist_alloc()) == NULL) {
file_oomem(ms, sizeof(*ms->mlist[i]));
- if (i != 0) {
- --i;
- do
- mlist_free(ms->mlist[i]);
- while (i != 0);
+ while (i-- > 0) {
+ mlist_free(ms->mlist[i]);
+ ms->mlist[i] = NULL;
}
free(mfn);
return -1;
@@ -1317,7 +1386,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
* the sign extension must have happened.
*/
case FILE_BYTE:
- v = (char) v;
+ v = (signed char) v;
break;
case FILE_SHORT:
case FILE_BESHORT:
@@ -2069,8 +2138,14 @@ out:
}
private int
+goodchar(unsigned char x, const char *extra)
+{
+ return (isascii(x) && isalnum(x)) || strchr(extra, x);
+}
+
+private int
parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
- off_t off, size_t len, const char *name, int nt)
+ off_t off, size_t len, const char *name, const char *extra, int nt)
{
size_t i;
const char *l = line;
@@ -2091,9 +2166,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
}
EATAB;
- for (i = 0; *l && ((isascii((unsigned char)*l) &&
- isalnum((unsigned char)*l)) || strchr("-+/.", *l)) &&
- i < len; buf[i++] = *l++)
+ for (i = 0; *l && i < len && goodchar(*l, extra); buf[i++] = *l++)
continue;
if (i == len && *l) {
@@ -2103,14 +2176,18 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
file_magwarn(ms, "%s type `%s' truncated %"
SIZE_T_FORMAT "u", name, line, i);
} else {
+ if (!isspace((unsigned char)*l) && !goodchar(*l, extra))
+ file_magwarn(ms, "%s type `%s' has bad char '%c'",
+ name, line, *l);
if (nt)
buf[i] = '\0';
}
if (i > 0)
return 0;
- else
- return -1;
+
+ file_magerror(ms, "Bad magic entry '%s'", line);
+ return -1;
}
/*
@@ -2123,7 +2200,7 @@ parse_apple(struct magic_set *ms, struct magic_entry *me, const char *line)
struct magic *m = &me->mp[0];
return parse_extra(ms, me, line, offsetof(struct magic, apple),
- sizeof(m->apple), "APPLE", 0);
+ sizeof(m->apple), "APPLE", "!+-./", 0);
}
/*
@@ -2136,7 +2213,7 @@ parse_mime(struct magic_set *ms, struct magic_entry *me, const char *line)
struct magic *m = &me->mp[0];
return parse_extra(ms, me, line, offsetof(struct magic, mimetype),
- sizeof(m->mimetype), "MIME", 1);
+ sizeof(m->mimetype), "MIME", "+-/.", 1);
}
private int
@@ -2697,6 +2774,28 @@ eatsize(const char **p)
}
/*
+ * handle a buffer containing a compiled file.
+ */
+private struct magic_map *
+apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len)
+{
+ struct magic_map *map;
+
+ if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
+ file_oomem(ms, sizeof(*map));
+ return NULL;
+ }
+ map->len = len;
+ map->p = buf;
+ map->type = MAP_TYPE_USER;
+ if (check_buffer(ms, map, "buffer") != 0) {
+ apprentice_unmap(map);
+ return NULL;
+ }
+ return map;
+}
+
+/*
* handle a compiled file.
*/
@@ -2705,12 +2804,8 @@ apprentice_map(struct magic_set *ms, const char *fn)
{
int fd;
struct stat st;
- uint32_t *ptr;
- uint32_t version, entries, nentries;
- int needsbyteswap;
char *dbname = NULL;
struct magic_map *map;
- size_t i;
fd = -1;
if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
@@ -2742,6 +2837,7 @@ apprentice_map(struct magic_set *ms, const char *fn)
file_error(ms, errno, "cannot map `%s'", dbname);
goto error;
}
+ map->type = MAP_TYPE_MMAP;
#else
if ((map->p = CAST(void *, malloc(map->len))) == NULL) {
file_oomem(ms, map->len);
@@ -2751,16 +2847,39 @@ apprentice_map(struct magic_set *ms, const char *fn)
file_badread(ms);
goto error;
}
- map->len = 0;
+ map->type = MAP_TYPE_MALLOC;
#define RET 1
#endif
(void)close(fd);
fd = -1;
+
+ if (check_buffer(ms, map, dbname) != 0)
+ goto error;
+
+ free(dbname);
+ return map;
+
+error:
+ if (fd != -1)
+ (void)close(fd);
+ apprentice_unmap(map);
+ free(dbname);
+ return NULL;
+}
+
+private int
+check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
+{
+ uint32_t *ptr;
+ uint32_t entries, nentries;
+ uint32_t version;
+ int i, needsbyteswap;
+
ptr = CAST(uint32_t *, map->p);
if (*ptr != MAGICNO) {
if (swap4(*ptr) != MAGICNO) {
file_error(ms, 0, "bad magic in `%s'", dbname);
- goto error;
+ return -1;
}
needsbyteswap = 1;
} else
@@ -2773,15 +2892,14 @@ apprentice_map(struct magic_set *ms, const char *fn)
file_error(ms, 0, "File %s supports only version %d magic "
"files. `%s' is version %d", VERSION,
VERSIONNO, dbname, version);
- goto error;
+ return -1;
}
- entries = (uint32_t)(st.st_size / sizeof(struct magic));
- if ((off_t)(entries * sizeof(struct magic)) != st.st_size) {
- file_error(ms, 0, "Size of `%s' %" INT64_T_FORMAT "u is not "
+ entries = (uint32_t)(map->len / sizeof(struct magic));
+ if ((entries * sizeof(struct magic)) != map->len) {
+ file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not "
"a multiple of %" SIZE_T_FORMAT "u",
- dbname, (unsigned long long)st.st_size,
- sizeof(struct magic));
- goto error;
+ dbname, map->len, sizeof(struct magic));
+ return -1;
}
map->magic[0] = CAST(struct magic *, map->p) + 1;
nentries = 0;
@@ -2797,20 +2915,12 @@ apprentice_map(struct magic_set *ms, const char *fn)
if (entries != nentries + 1) {
file_error(ms, 0, "Inconsistent entries in `%s' %u != %u",
dbname, entries, nentries + 1);
- goto error;
+ return -1;
}
if (needsbyteswap)
for (i = 0; i < MAGIC_SETS; i++)
byteswap(map->magic[i], map->nmagic[i]);
- free(dbname);
- return map;
-
-error:
- if (fd != -1)
- (void)close(fd);
- apprentice_unmap(map);
- free(dbname);
- return NULL;
+ return 0;
}
/*
diff --git a/contrib/file/src/ascmagic.c b/contrib/file/src/ascmagic.c
index ca26665..78a6dbb 100644
--- a/contrib/file/src/ascmagic.c
+++ b/contrib/file/src/ascmagic.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.88 2014/02/12 23:20:53 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.91 2014/11/28 02:46:39 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -147,7 +147,8 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf,
== NULL)
goto done;
if ((rv = file_softmagic(ms, utf8_buf,
- (size_t)(utf8_end - utf8_buf), 0, TEXTTEST, text)) == 0)
+ (size_t)(utf8_end - utf8_buf), 0, NULL,
+ TEXTTEST, text)) == 0)
rv = -1;
}
diff --git a/contrib/file/src/cdf.c b/contrib/file/src/cdf.c
index 106fc7a..9e3cf9f 100644
--- a/contrib/file/src/cdf.c
+++ b/contrib/file/src/cdf.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.63 2014/06/09 13:04:37 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.69 2014/12/04 15:56:46 christos Exp $")
#endif
#include <assert.h>
@@ -73,6 +73,8 @@ static union {
#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x)))
#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x)))
#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x)))
+#define CDF_TOLE(x) (sizeof(x) == 2 ? CDF_TOLE2(x) : (sizeof(x) == 4 ? \
+ CDF_TOLE4(x) : CDF_TOLE8(x)))
#define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
@@ -461,6 +463,12 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
/ sizeof(maxsector));
DPRINTF(("Chain:"));
+ if (sid == CDF_SECID_END_OF_CHAIN) {
+ /* 0-length chain. */
+ DPRINTF((" empty\n"));
+ return 0;
+ }
+
for (j = i = 0; sid >= 0; i++, j++) {
DPRINTF((" %d", sid));
if (j >= CDF_LOOP_LIMIT) {
@@ -817,13 +825,18 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
goto out;
for (i = 0; i < sh.sh_properties; i++) {
size_t tail = (i << 1) + 1;
+ size_t ofs;
if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t),
__LINE__) == -1)
goto out;
- size_t ofs = CDF_GETUINT32(p, tail);
+ ofs = CDF_GETUINT32(p, tail);
q = (const uint8_t *)(const void *)
((const char *)(const void *)p + ofs
- 2 * sizeof(uint32_t));
+ if (q < p) {
+ DPRINTF(("Wrapped around %p < %p\n", q, p));
+ goto out;
+ }
if (q > e) {
DPRINTF(("Ran of the end %p > %p\n", q, e));
goto out;
@@ -985,6 +998,54 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
}
+#define extract_catalog_field(f, l) \
+ memcpy(&ce[i].f, b + (l), sizeof(ce[i].f)); \
+ ce[i].f = CDF_TOLE(ce[i].f)
+
+int
+cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst,
+ cdf_catalog_t **cat)
+{
+ size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ?
+ CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h);
+ const char *b = CAST(const char *, sst->sst_tab);
+ const char *eb = b + ss * sst->sst_len;
+ size_t nr, i, k;
+ cdf_catalog_entry_t *ce;
+ uint16_t reclen;
+ const uint16_t *np;
+
+ for (nr = 0; b < eb; nr++) {
+ memcpy(&reclen, b, sizeof(reclen));
+ reclen = CDF_TOLE2(reclen);
+ if (reclen == 0)
+ break;
+ b += reclen;
+ }
+ *cat = CAST(cdf_catalog_t *,
+ malloc(sizeof(cdf_catalog_t) + nr * sizeof(*ce)));
+ (*cat)->cat_num = nr;
+ ce = (*cat)->cat_e;
+ b = CAST(const char *, sst->sst_tab);
+ for (i = 0; i < nr; i++) {
+ extract_catalog_field(ce_namlen, 0);
+ extract_catalog_field(ce_num, 2);
+ extract_catalog_field(ce_timestamp, 6);
+ reclen = ce[i].ce_namlen;
+ ce[i].ce_namlen =
+ sizeof(ce[i].ce_name) / sizeof(ce[i].ce_name[0]) - 1;
+ if (ce[i].ce_namlen > reclen - 14)
+ ce[i].ce_namlen = reclen - 14;
+ np = CAST(const uint16_t *, (b + 16));
+ for (k = 0; k < ce[i].ce_namlen; k++) {
+ ce[i].ce_name[k] = np[k];
+ CDF_TOLE2(ce[i].ce_name[k]);
+ }
+ ce[i].ce_name[ce[i].ce_namlen] = 0;
+ b += reclen;
+ }
+ return 0;
+}
int
cdf_print_classid(char *buf, size_t buflen, const cdf_classid_t *id)
@@ -1068,6 +1129,15 @@ cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts)
return len;
}
+char *
+cdf_u16tos8(char *buf, size_t len, const uint16_t *p)
+{
+ size_t i;
+ for (i = 0; i < len && p[i]; i++)
+ buf[i] = (char)p[i];
+ buf[i] = '\0';
+ return buf;
+}
#ifdef CDF_DEBUG
void
@@ -1093,7 +1163,7 @@ cdf_dump_header(const cdf_header_t *h)
for (i = 0; i < __arraycount(h->h_master_sat); i++) {
if (h->h_master_sat[i] == CDF_SECID_FREE)
break;
- (void)fprintf(stderr, "%35.35s[%.3zu] = %d\n",
+ (void)fprintf(stderr, "%35.35s[%.3" SIZE_T_FORMAT "u] = %d\n",
"master_sat", i, h->h_master_sat[i]);
}
}
@@ -1288,7 +1358,7 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
return;
(void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order);
(void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff,
- ssi.si_os_version >> 8);
+ ssi.si_os_version >> 8);
(void)fprintf(stderr, "Os %d\n", ssi.si_os);
cdf_print_classid(buf, sizeof(buf), &ssi.si_class);
(void)fprintf(stderr, "Class %s\n", buf);
@@ -1297,6 +1367,27 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst)
free(info);
}
+
+void
+cdf_dump_catalog(const cdf_header_t *h, const cdf_stream_t *sst)
+{
+ cdf_catalog_t *cat;
+ cdf_unpack_catalog(h, sst, &cat);
+ const cdf_catalog_entry_t *ce = cat->cat_e;
+ struct timespec ts;
+ char tbuf[64], sbuf[256];
+ size_t i;
+
+ printf("Catalog:\n");
+ for (i = 0; i < cat->cat_num; i++) {
+ cdf_timestamp_to_timespec(&ts, ce[i].ce_timestamp);
+ printf("\t%d %s %s", ce[i].ce_num,
+ cdf_u16tos8(sbuf, ce[i].ce_namlen, ce[i].ce_name),
+ cdf_ctime(&ts.tv_sec, tbuf));
+ }
+ free(cat);
+}
+
#endif
#ifdef TEST
@@ -1309,6 +1400,7 @@ main(int argc, char *argv[])
cdf_stream_t sst, scn;
cdf_dir_t dir;
cdf_info_t info;
+ const cdf_directory_t *root;
if (argc < 2) {
(void)fprintf(stderr, "Usage: %s <filename>\n", getprogname());
@@ -1342,7 +1434,8 @@ main(int argc, char *argv[])
if (cdf_read_dir(&info, &h, &sat, &dir) == -1)
err(1, "Cannot read dir");
- if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1)
+ if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst, &root)
+ == -1)
err(1, "Cannot read short stream");
#ifdef CDF_DEBUG
cdf_dump_stream(&h, &sst);
@@ -1355,9 +1448,17 @@ main(int argc, char *argv[])
if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
&scn) == -1)
- err(1, "Cannot read summary info");
+ warn("Cannot read summary info");
+#ifdef CDF_DEBUG
+ else
+ cdf_dump_summary_info(&h, &scn);
+#endif
+ if (cdf_read_catalog(&info, &h, &sat, &ssat, &sst, &dir,
+ &scn) == -1)
+ warn("Cannot read catalog");
#ifdef CDF_DEBUG
- cdf_dump_summary_info(&h, &scn);
+ else
+ cdf_dump_catalog(&h, &scn);
#endif
(void)close(info.i_fd);
diff --git a/contrib/file/src/cdf.h b/contrib/file/src/cdf.h
index 910fb95..64e3648 100644
--- a/contrib/file/src/cdf.h
+++ b/contrib/file/src/cdf.h
@@ -267,6 +267,19 @@ typedef struct {
size_t i_len;
} cdf_info_t;
+
+typedef struct {
+ uint16_t ce_namlen;
+ uint32_t ce_num;
+ uint64_t ce_timestamp;
+ uint16_t ce_name[256];
+} cdf_catalog_entry_t;
+
+typedef struct {
+ size_t cat_num;
+ cdf_catalog_entry_t cat_e[0];
+} cdf_catalog_t;
+
struct timespec;
int cdf_timestamp_to_timespec(struct timespec *, cdf_timestamp_t);
int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timespec *);
@@ -301,11 +314,19 @@ int cdf_read_property_info(const cdf_stream_t *, const cdf_header_t *, uint32_t,
int cdf_read_user_stream(const cdf_info_t *, const cdf_header_t *,
const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
const cdf_dir_t *, const char *, cdf_stream_t *);
+#define cdf_read_catalog(info, header, sat, ssat, stream, dir, scn) \
+ cdf_read_user_stream(info, header, sat, ssat, stream, dir, "Catalog", \
+ scn)
+#define cdf_read_encrypted_package(info, header, sat, ssat, stream, dir, scn) \
+ cdf_read_user_stream(info, header, sat, ssat, stream, dir, \
+ "EncryptedPackage", scn)
int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *,
const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *,
const cdf_dir_t *, cdf_stream_t *);
int cdf_unpack_summary_info(const cdf_stream_t *, const cdf_header_t *,
cdf_summary_info_header_t *, cdf_property_info_t **, size_t *);
+int cdf_unpack_catalog(const cdf_header_t *, const cdf_stream_t *,
+ cdf_catalog_t **);
int cdf_print_classid(char *, size_t, const cdf_classid_t *);
int cdf_print_property_name(char *, size_t, uint32_t);
int cdf_print_elapsed_time(char *, size_t, cdf_timestamp_t);
@@ -313,6 +334,7 @@ uint16_t cdf_tole2(uint16_t);
uint32_t cdf_tole4(uint32_t);
uint64_t cdf_tole8(uint64_t);
char *cdf_ctime(const time_t *, char *);
+char *cdf_u16tos8(char *, size_t, const uint16_t *);
#ifdef CDF_DEBUG
void cdf_dump_header(const cdf_header_t *);
@@ -323,6 +345,7 @@ void cdf_dump_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *,
const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *);
void cdf_dump_property_info(const cdf_property_info_t *, size_t);
void cdf_dump_summary_info(const cdf_header_t *, const cdf_stream_t *);
+void cdf_dump_catalog(const cdf_header_t *, const cdf_stream_t *);
#endif
diff --git a/contrib/file/src/compress.c b/contrib/file/src/compress.c
index 45251b1..4a6f42e 100644
--- a/contrib/file/src/compress.c
+++ b/contrib/file/src/compress.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.73 2014/01/05 15:55:21 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.75 2014/12/04 15:56:46 christos Exp $")
#endif
#include "magic.h"
@@ -45,7 +45,7 @@ FILE_RCSID("@(#)$File: compress.c,v 1.73 2014/01/05 15:55:21 christos Exp $")
#endif
#include <string.h>
#include <errno.h>
-#ifndef __MINGW32__
+#if !defined(__MINGW32__) && !defined(WIN32)
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_WAIT_H
@@ -377,6 +377,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
const unsigned char *old, unsigned char **newch, size_t n)
{
int fdin[2], fdout[2];
+ int status;
ssize_t r;
pid_t pid;
@@ -459,7 +460,17 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
/*NOTREACHED*/
default: /* parent */
- break;
+ if (wait(&status) == -1) {
+#ifdef DEBUG
+ (void)fprintf(stderr,
+ "Wait failed (%s)\n",
+ strerror(errno));
+#endif
+ exit(1);
+ }
+ exit(WIFEXITED(status) ?
+ WEXITSTATUS(status) : 1);
+ /*NOTREACHED*/
}
(void) close(fdin[1]);
fdin[1] = -1;
@@ -470,7 +481,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
(void)fprintf(stderr, "Malloc failed (%s)\n",
strerror(errno));
#endif
- n = 0;
+ n = NODATA;
goto err;
}
if ((r = sread(fdout[0], *newch, HOWMANY, 0)) <= 0) {
@@ -479,7 +490,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method,
strerror(errno));
#endif
free(*newch);
- n = 0;
+ n = NODATA;
*newch = NULL;
goto err;
} else {
@@ -491,12 +502,19 @@ err:
if (fdin[1] != -1)
(void) close(fdin[1]);
(void) close(fdout[0]);
-#ifdef WNOHANG
- while (waitpid(pid, NULL, WNOHANG) != -1)
- continue;
-#else
- (void)wait(NULL);
+ if (wait(&status) == -1) {
+#ifdef DEBUG
+ (void)fprintf(stderr, "Wait failed (%s)\n",
+ strerror(errno));
#endif
+ n = NODATA;
+ } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+#ifdef DEBUG
+ (void)fprintf(stderr, "Child status (0x%x)\n", status);
+#endif
+ n = NODATA;
+ }
+
(void) close(fdin[0]);
return n;
diff --git a/contrib/file/src/elfclass.h b/contrib/file/src/elfclass.h
index 0826ce3..e144d11 100644
--- a/contrib/file/src/elfclass.h
+++ b/contrib/file/src/elfclass.h
@@ -36,7 +36,7 @@
#ifdef ELFCORE
case ET_CORE:
phnum = elf_getu16(swap, elfhdr.e_phnum);
- if (phnum > MAX_PHNUM)
+ if (phnum > ms->elf_phnum_max)
return toomany(ms, "program", phnum);
flags |= FLAGS_IS_CORE;
if (dophn_core(ms, clazz, swap, fd,
@@ -49,10 +49,10 @@
case ET_EXEC:
case ET_DYN:
phnum = elf_getu16(swap, elfhdr.e_phnum);
- if (phnum > MAX_PHNUM)
+ if (phnum > ms->elf_phnum_max)
return toomany(ms, "program", phnum);
shnum = elf_getu16(swap, elfhdr.e_shnum);
- if (shnum > MAX_SHNUM)
+ if (shnum > ms->elf_shnum_max)
return toomany(ms, "section", shnum);
if (dophn_exec(ms, clazz, swap, fd,
(off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
@@ -62,7 +62,7 @@
/*FALLTHROUGH*/
case ET_REL:
shnum = elf_getu16(swap, elfhdr.e_shnum);
- if (shnum > MAX_SHNUM)
+ if (shnum > ms->elf_shnum_max)
return toomany(ms, "section", shnum);
if (doshn(ms, clazz, swap, fd,
(off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
diff --git a/contrib/file/src/encoding.c b/contrib/file/src/encoding.c
index b75e0cc..c1b23cc 100644
--- a/contrib/file/src/encoding.c
+++ b/contrib/file/src/encoding.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: encoding.c,v 1.9 2013/11/19 20:45:50 christos Exp $")
+FILE_RCSID("@(#)$File: encoding.c,v 1.10 2014/09/11 12:08:52 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -97,7 +97,6 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni
*code_mime = "utf-8";
} else if (file_looks_utf8(buf, nbytes, *ubuf, ulen) > 1) {
DPRINTF(("utf8 %" SIZE_T_FORMAT "u\n", *ulen));
- *code = "UTF-8 Unicode (with BOM)";
*code = "UTF-8 Unicode";
*code_mime = "utf-8";
} else if ((ucs_type = looks_ucs16(buf, nbytes, *ubuf, ulen)) != 0) {
diff --git a/contrib/file/src/file.c b/contrib/file/src/file.c
index 370da91..148f806 100644
--- a/contrib/file/src/file.c
+++ b/contrib/file/src/file.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: file.c,v 1.153 2014/02/11 15:41:04 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.159 2014/11/28 02:46:39 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -54,9 +54,6 @@ FILE_RCSID("@(#)$File: file.c,v 1.153 2014/02/11 15:41:04 christos Exp $")
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* for read() */
#endif
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif
@@ -101,7 +98,7 @@ private const struct option long_options[] = {
#undef OPT_LONGONLY
{0, 0, NULL, 0}
};
-#define OPTSTRING "bcCde:Ef:F:hiklLm:nNprsvz0"
+#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsvz0"
private const struct {
const char *name;
@@ -119,6 +116,17 @@ private const struct {
{ "tokens", MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored for backwards compatibility */
};
+private struct {
+ const char *name;
+ int tag;
+ size_t value;
+} pm[] = {
+ { "indir", MAGIC_PARAM_INDIR_MAX, 0 },
+ { "name", MAGIC_PARAM_NAME_MAX, 0 },
+ { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
+ { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
+};
+
private char *progname; /* used throughout */
private void usage(void);
@@ -128,6 +136,8 @@ private void help(void);
private int unwrap(struct magic_set *, const char *);
private int process(struct magic_set *ms, const char *, int);
private struct magic_set *load(const char *, int);
+private void setparam(const char *);
+private void applyparam(magic_t);
/*
@@ -145,7 +155,9 @@ main(int argc, char *argv[])
const char *magicfile = NULL; /* where the magic is */
/* makes islower etc work for other langs */
+#ifdef HAVE_SETLOCALE
(void)setlocale(LC_CTYPE, "");
+#endif
#ifdef __EMX__
/* sh-like wildcard expansion! Shouldn't hurt at least ... */
@@ -243,9 +255,13 @@ main(int argc, char *argv[])
flags |= MAGIC_PRESERVE_ATIME;
break;
#endif
+ case 'P':
+ setparam(optarg);
+ break;
case 'r':
flags |= MAGIC_RAW;
break;
+ break;
case 's':
flags |= MAGIC_DEVICES;
break;
@@ -298,6 +314,8 @@ main(int argc, char *argv[])
strerror(errno));
return 1;
}
+
+
switch(action) {
case FILE_CHECK:
c = magic_check(magic, magicfile);
@@ -321,7 +339,7 @@ main(int argc, char *argv[])
if (magic == NULL)
if ((magic = load(magicfile, flags)) == NULL)
return 1;
- break;
+ applyparam(magic);
}
if (optind == argc) {
@@ -351,6 +369,41 @@ main(int argc, char *argv[])
return e;
}
+private void
+applyparam(magic_t magic)
+{
+ size_t i;
+
+ for (i = 0; i < __arraycount(pm); i++) {
+ if (pm[i].value == 0)
+ continue;
+ if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1) {
+ (void)fprintf(stderr, "%s: Can't set %s %s\n", progname,
+ pm[i].name, strerror(errno));
+ exit(1);
+ }
+ }
+}
+
+private void
+setparam(const char *p)
+{
+ size_t i;
+ char *s;
+
+ if ((s = strchr(p, '=')) == NULL)
+ goto badparm;
+
+ for (i = 0; i < __arraycount(pm); i++) {
+ if (strncmp(p, pm[i].name, s - p) != 0)
+ continue;
+ pm[i].value = atoi(s + 1);
+ return;
+ }
+badparm:
+ (void)fprintf(stderr, "%s: Unknown param %s\n", progname, p);
+ exit(1);
+}
private struct magic_set *
/*ARGSUSED*/
diff --git a/contrib/file/src/file.h b/contrib/file/src/file.h
index 1a652a8..14fa836 100644
--- a/contrib/file/src/file.h
+++ b/contrib/file/src/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.152 2014/06/03 19:01:34 christos Exp $
+ * @(#)$File: file.h,v 1.161 2014/12/04 15:56:46 christos Exp $
*/
#ifndef __file_h__
@@ -64,7 +64,9 @@
#include <regex.h>
#include <time.h>
#include <sys/types.h>
+#ifndef WIN32
#include <sys/param.h>
+#endif
/* Do this here and now, because struct stat gets re-defined on solaris */
#include <sys/stat.h>
#include <stdarg.h>
@@ -401,6 +403,14 @@ struct magic_set {
/* FIXME: Make the string dynamically allocated so that e.g.
strings matched in files can be longer than MAXstring */
union VALUETYPE ms_value; /* either number or string */
+ uint16_t indir_max;
+ uint16_t name_max;
+ uint16_t elf_shnum_max;
+ uint16_t elf_phnum_max;
+#define FILE_INDIR_MAX 15
+#define FILE_NAME_MAX 30
+#define FILE_ELF_SHNUM_MAX 32768
+#define FILE_ELF_PHNUM_MAX 128
};
/* Type for Unicode characters */
@@ -440,8 +450,10 @@ protected int file_encoding(struct magic_set *, const unsigned char *, size_t,
unichar **, size_t *, const char **, const char **, const char **);
protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
protected int file_softmagic(struct magic_set *, const unsigned char *, size_t,
- size_t, int, int);
+ uint16_t, uint16_t *, int, int);
protected int file_apprentice(struct magic_set *, const char *, int);
+protected int buffer_apprentice(struct magic_set *, struct magic **,
+ size_t *, size_t);
protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
protected uint64_t file_signextend(struct magic_set *, struct magic *,
uint64_t);
@@ -469,9 +481,20 @@ protected int file_os2_apptype(struct magic_set *, const char *, const void *,
size_t);
#endif /* __EMX__ */
+#if defined(HAVE_LOCALE_H)
+#include <locale.h>
+#endif
+#if defined(HAVE_XLOCALE_H)
+#include <xlocale.h>
+#endif
+
typedef struct {
const char *pat;
- char *old_lc_ctype;
+#if defined(HAVE_NEWLOCALE) && defined(HAVE_USELOCALE) && defined(HAVE_FREELOCALE)
+#define USE_C_LOCALE
+ locale_t old_lc_ctype;
+ locale_t c_lc_ctype;
+#endif
int rc;
regex_t rx;
} file_regex_t;
diff --git a/contrib/file/src/file_opts.h b/contrib/file/src/file_opts.h
index db34eb7..9cb1d01 100644
--- a/contrib/file/src/file_opts.h
+++ b/contrib/file/src/file_opts.h
@@ -44,6 +44,7 @@ OPT('0', "print0", 0, " terminate filenames with ASCII NUL\n")
OPT('p', "preserve-date", 0, " preserve access times on files\n")
#endif
OPT('r', "raw", 0, " don't translate unprintable chars to \\ooo\n")
+OPT('R', "recursion", 0, " set maximum recursion level\n")
OPT('s', "special-files", 0, " treat special (block/char devices) files as\n"
" ordinary ones\n")
OPT('C', "compile", 0, " compile file specified by -m\n")
diff --git a/contrib/file/src/fsmagic.c b/contrib/file/src/fsmagic.c
index ef5492f..1e8fd74 100644
--- a/contrib/file/src/fsmagic.c
+++ b/contrib/file/src/fsmagic.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: fsmagic.c,v 1.73 2014/05/14 23:15:42 christos Exp $")
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.75 2014/12/04 15:56:46 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -75,10 +75,10 @@ bad_link(struct magic_set *ms, int err, char *buf)
else if (!mime) {
if (ms->flags & MAGIC_ERROR) {
file_error(ms, err,
- "broken symbolic link to `%s'", buf);
+ "broken symbolic link to %s", buf);
return -1;
}
- if (file_printf(ms, "broken symbolic link to `%s'", buf) == -1)
+ if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
return -1;
}
return 1;
@@ -129,7 +129,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
#ifdef WIN32
{
- HANDLE hFile = CreateFile(fn, 0, FILE_SHARE_DELETE |
+ HANDLE hFile = CreateFile((LPCSTR)fn, 0, FILE_SHARE_DELETE |
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
NULL);
if (hFile != INVALID_HANDLE_VALUE) {
@@ -352,7 +352,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (mime) {
if (handle_mime(ms, mime, "symlink") == -1)
return -1;
- } else if (file_printf(ms, "%ssymbolic link to `%s'",
+ } else if (file_printf(ms, "%ssymbolic link to %s",
COMMA, buf) == -1)
return -1;
}
diff --git a/contrib/file/src/funcs.c b/contrib/file/src/funcs.c
index 7e7d2e7..f190349 100644
--- a/contrib/file/src/funcs.c
+++ b/contrib/file/src/funcs.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.72 2014/05/14 23:15:42 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.77 2014/11/28 02:46:39 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -45,9 +45,6 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.72 2014/05/14 23:15:42 christos Exp $")
#if defined(HAVE_LIMITS_H)
#include <limits.h>
#endif
-#if defined(HAVE_LOCALE_H)
-#include <locale.h>
-#endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)~0)
@@ -230,7 +227,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu
/* try soft magic tests */
if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
- if ((m = file_softmagic(ms, ubuf, nb, 0, BINTEST,
+ if ((m = file_softmagic(ms, ubuf, nb, 0, NULL, BINTEST,
looks_text)) != 0) {
if ((ms->flags & MAGIC_DEBUG) != 0)
(void)fprintf(stderr, "softmagic %d\n", m);
@@ -455,13 +452,14 @@ out:
protected int
file_regcomp(file_regex_t *rx, const char *pat, int flags)
{
- rx->old_lc_ctype = setlocale(LC_CTYPE, NULL);
- assert(rx->old_lc_ctype != NULL);
- rx->old_lc_ctype = strdup(rx->old_lc_ctype);
+#ifdef USE_C_LOCALE
+ rx->c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
+ assert(rx->c_lc_ctype != NULL);
+ rx->old_lc_ctype = uselocale(rx->c_lc_ctype);
assert(rx->old_lc_ctype != NULL);
+#endif
rx->pat = pat;
- (void)setlocale(LC_CTYPE, "C");
return rx->rc = regcomp(&rx->rx, pat, flags);
}
@@ -478,8 +476,10 @@ file_regfree(file_regex_t *rx)
{
if (rx->rc == 0)
regfree(&rx->rx);
- (void)setlocale(LC_CTYPE, rx->old_lc_ctype);
- free(rx->old_lc_ctype);
+#ifdef USE_C_LOCALE
+ (void)uselocale(rx->old_lc_ctype);
+ freelocale(rx->c_lc_ctype);
+#endif
}
protected void
diff --git a/contrib/file/src/getline.c b/contrib/file/src/getline.c
index 99cd150..ab5e115 100644
--- a/contrib/file/src/getline.c
+++ b/contrib/file/src/getline.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */
+/* $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -52,10 +52,14 @@ getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
for (ptr = *buf, eptr = *buf + *bufsiz;;) {
int c = fgetc(fp);
if (c == -1) {
- if (feof(fp))
- return ptr == *buf ? -1 : ptr - *buf;
- else
- return -1;
+ if (feof(fp)) {
+ ssize_t diff = (ssize_t)(ptr - *buf);
+ if (diff != 0) {
+ *ptr = '\0';
+ return diff;
+ }
+ }
+ return -1;
}
*ptr++ = c;
if (c == delimiter) {
@@ -93,7 +97,7 @@ main(int argc, char *argv[])
size_t n = 0;
while ((len = getline(&p, &n, stdin)) != -1)
- (void)printf("%zd %s", len, p);
+ (void)printf("%" SIZE_T_FORMAT "d %s", len, p);
free(p);
return 0;
}
diff --git a/contrib/file/src/magic.c b/contrib/file/src/magic.c
index e4bd12b..b0cf11c 100644
--- a/contrib/file/src/magic.c
+++ b/contrib/file/src/magic.c
@@ -33,7 +33,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: magic.c,v 1.84 2014/05/14 23:15:42 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.90 2014/12/04 15:56:46 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -128,6 +128,7 @@ out:
#else
char *hmagicp;
char *tmppath = NULL;
+ LPTSTR dllpath;
hmagicpath = NULL;
#define APPENDPATH() \
@@ -173,7 +174,7 @@ out:
}
/* Third, try to get magic file relative to dll location */
- LPTSTR dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1));
+ dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1));
dllpath[MAX_PATH] = 0; /* just in case long path gets truncated and not null terminated */
if (GetModuleFileNameA(NULL, dllpath, MAX_PATH)){
PathRemoveFileSpecA(dllpath);
@@ -257,6 +258,20 @@ magic_load(struct magic_set *ms, const char *magicfile)
return file_apprentice(ms, magicfile, FILE_LOAD);
}
+#ifndef COMPILE_ONLY
+/*
+ * Install a set of compiled magic buffers.
+ */
+public int
+magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
+ size_t nbufs)
+{
+ if (ms == NULL)
+ return -1;
+ return buffer_apprentice(ms, (struct magic **)bufs, sizes, nbufs);
+}
+#endif
+
public int
magic_compile(struct magic_set *ms, const char *magicfile)
{
@@ -522,3 +537,47 @@ magic_version(void)
{
return MAGIC_VERSION;
}
+
+public int
+magic_setparam(struct magic_set *ms, int param, const void *val)
+{
+ switch (param) {
+ case MAGIC_PARAM_INDIR_MAX:
+ ms->indir_max = *(const size_t *)val;
+ return 0;
+ case MAGIC_PARAM_NAME_MAX:
+ ms->name_max = *(const size_t *)val;
+ return 0;
+ case MAGIC_PARAM_ELF_PHNUM_MAX:
+ ms->elf_phnum_max = *(const size_t *)val;
+ return 0;
+ case MAGIC_PARAM_ELF_SHNUM_MAX:
+ ms->elf_shnum_max = *(const size_t *)val;
+ return 0;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+public int
+magic_getparam(struct magic_set *ms, int param, void *val)
+{
+ switch (param) {
+ case MAGIC_PARAM_INDIR_MAX:
+ *(size_t *)val = ms->indir_max;
+ return 0;
+ case MAGIC_PARAM_NAME_MAX:
+ *(size_t *)val = ms->name_max;
+ return 0;
+ case MAGIC_PARAM_ELF_PHNUM_MAX:
+ *(size_t *)val = ms->elf_phnum_max;
+ return 0;
+ case MAGIC_PARAM_ELF_SHNUM_MAX:
+ *(size_t *)val = ms->elf_shnum_max;
+ return 0;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
diff --git a/contrib/file/src/magic.h b/contrib/file/src/magic.h
index 38e59d7..94cb397 100644
--- a/contrib/file/src/magic.h
+++ b/contrib/file/src/magic.h
@@ -75,7 +75,7 @@
#define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
-#define MAGIC_VERSION 518 /* This implementation */
+#define MAGIC_VERSION 521 /* This implementation */
#ifdef __cplusplus
@@ -96,11 +96,21 @@ int magic_setflags(magic_t, int);
int magic_version(void);
int magic_load(magic_t, const char *);
+int magic_load_buffers(magic_t, void **, size_t *, size_t);
+
int magic_compile(magic_t, const char *);
int magic_check(magic_t, const char *);
int magic_list(magic_t, const char *);
int magic_errno(magic_t);
+#define MAGIC_PARAM_INDIR_MAX 0
+#define MAGIC_PARAM_NAME_MAX 1
+#define MAGIC_PARAM_ELF_PHNUM_MAX 2
+#define MAGIC_PARAM_ELF_SHNUM_MAX 3
+
+int magic_setparam(magic_t, int, const void *);
+int magic_getparam(magic_t, int, void *);
+
#ifdef __cplusplus
};
#endif
diff --git a/contrib/file/src/magic.h.in b/contrib/file/src/magic.h.in
index 86fc41b..856478b 100644
--- a/contrib/file/src/magic.h.in
+++ b/contrib/file/src/magic.h.in
@@ -96,11 +96,21 @@ int magic_setflags(magic_t, int);
int magic_version(void);
int magic_load(magic_t, const char *);
+int magic_load_buffers(magic_t, void **, size_t *, size_t);
+
int magic_compile(magic_t, const char *);
int magic_check(magic_t, const char *);
int magic_list(magic_t, const char *);
int magic_errno(magic_t);
+#define MAGIC_PARAM_INDIR_MAX 0
+#define MAGIC_PARAM_NAME_MAX 1
+#define MAGIC_PARAM_ELF_PHNUM_MAX 2
+#define MAGIC_PARAM_ELF_SHNUM_MAX 3
+
+int magic_setparam(magic_t, int, const void *);
+int magic_getparam(magic_t, int, void *);
+
#ifdef __cplusplus
};
#endif
diff --git a/contrib/file/src/pread.c b/contrib/file/src/pread.c
index 649f609..72d3a6b 100644
--- a/contrib/file/src/pread.c
+++ b/contrib/file/src/pread.c
@@ -1,14 +1,23 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: pread.c,v 1.2 2013/04/02 16:23:07 christos Exp $")
+FILE_RCSID("@(#)$File: pread.c,v 1.3 2014/09/15 19:11:25 christos Exp $")
#endif /* lint */
#include <fcntl.h>
#include <unistd.h>
ssize_t
pread(int fd, void *buf, size_t len, off_t off) {
- if (lseek(fd, off, SEEK_SET) == (off_t)-1)
+ off_t old;
+ ssize_t rv;
+
+ if ((old = lseek(fd, off, SEEK_SET)) == -1)
+ return -1;
+
+ if ((rv = read(fd, buf, len)) == -1)
+ return -1;
+
+ if (lseek(fd, old, SEEK_SET) == -1)
return -1;
- return read(fd, buf, len);
+ return rv;
}
diff --git a/contrib/file/src/readcdf.c b/contrib/file/src/readcdf.c
index 7ced9ea..635a926 100644
--- a/contrib/file/src/readcdf.c
+++ b/contrib/file/src/readcdf.c
@@ -26,7 +26,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.44 2014/05/14 23:22:48 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.49 2014/12/04 15:56:46 christos Exp $")
#endif
#include <assert.h>
@@ -35,9 +35,6 @@ FILE_RCSID("@(#)$File: readcdf.c,v 1.44 2014/05/14 23:22:48 christos Exp $")
#include <string.h>
#include <time.h>
#include <ctype.h>
-#if defined(HAVE_LOCALE_H)
-#include <locale.h>
-#endif
#include "cdf.h"
#include "magic.h"
@@ -75,7 +72,7 @@ static const struct cv {
const char *mime;
} clsid2mime[] = {
{
- { 0x00000000000c1084LLU, 0x46000000000000c0LLU },
+ { 0x00000000000c1084ULL, 0x46000000000000c0ULL },
"x-msi",
},
{ { 0, 0 },
@@ -83,7 +80,7 @@ static const struct cv {
},
}, clsid2desc[] = {
{
- { 0x00000000000c1084LLU, 0x46000000000000c0LLU },
+ { 0x00000000000c1084ULL, 0x46000000000000c0ULL },
"MSI Installer",
},
{ { 0, 0 },
@@ -107,20 +104,23 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv)
{
size_t i;
const char *rv = NULL;
- char *old_lc_ctype;
+#ifdef USE_C_LOCALE
+ locale_t old_lc_ctype, c_lc_ctype;
- old_lc_ctype = setlocale(LC_CTYPE, NULL);
- assert(old_lc_ctype != NULL);
- old_lc_ctype = strdup(old_lc_ctype);
+ c_lc_ctype = newlocale(LC_CTYPE_MASK, "C", 0);
+ assert(c_lc_ctype != NULL);
+ old_lc_ctype = uselocale(c_lc_ctype);
assert(old_lc_ctype != NULL);
- (void)setlocale(LC_CTYPE, "C");
+#endif
for (i = 0; nv[i].pattern != NULL; i++)
if (strcasestr(vbuf, nv[i].pattern) != NULL) {
rv = nv[i].mime;
break;
}
- (void)setlocale(LC_CTYPE, old_lc_ctype);
- free(old_lc_ctype);
+#ifdef USE_C_LOCALE
+ (void)uselocale(old_lc_ctype);
+ freelocale(c_lc_ctype);
+#endif
return rv;
}
@@ -241,6 +241,37 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
}
private int
+cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
+ const cdf_stream_t *sst)
+{
+ cdf_catalog_t *cat;
+ size_t i;
+ char buf[256];
+ cdf_catalog_entry_t *ce;
+
+ if (NOTMIME(ms)) {
+ if (file_printf(ms, "Microsoft Thumbs.db [") == -1)
+ return -1;
+ if (cdf_unpack_catalog(h, sst, &cat) == -1)
+ return -1;
+ ce = cat->cat_e;
+ /* skip first entry since it has a , or paren */
+ for (i = 1; i < cat->cat_num; i++)
+ if (file_printf(ms, "%s%s",
+ cdf_u16tos8(buf, ce[i].ce_namlen, ce[i].ce_name),
+ i == cat->cat_num - 1 ? "]" : ", ") == -1) {
+ free(cat);
+ return -1;
+ }
+ free(cat);
+ } else {
+ if (file_printf(ms, "application/CDFV2") == -1)
+ return -1;
+ }
+ return 1;
+}
+
+private int
cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
const cdf_stream_t *sst, const cdf_directory_t *root_storage)
{
@@ -285,11 +316,12 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
if (root_storage) {
str = cdf_clsid_to_mime(root_storage->d_storage_uuid,
clsid2desc);
- if (str)
+ if (str) {
if (file_printf(ms, ", %s", str) == -1)
return -2;
}
}
+ }
m = cdf_file_property_info(ms, info, count, root_storage);
free(info);
@@ -302,11 +334,11 @@ private char *
format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
PRIx64 "-%.12" PRIx64,
- (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffLLU,
- (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffLLU,
- (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffLLU,
- (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffLLU,
- (uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffLLU);
+ (uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL,
+ (uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL,
+ (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
+ (uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL,
+ (uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffULL);
return buf;
}
#endif
@@ -323,6 +355,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
int i;
const char *expn = "";
const char *corrupt = "corrupt: ";
+ const cdf_directory_t *root_storage;
info.i_fd = fd;
info.i_buf = buf;
@@ -356,7 +389,6 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
goto out2;
}
- const cdf_directory_t *root_storage;
if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst,
&root_storage)) == -1) {
expn = "Cannot read short stream";
@@ -404,8 +436,24 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir,
&scn)) == -1) {
if (errno == ESRCH) {
- corrupt = expn;
- expn = "No summary info";
+ if ((i = cdf_read_catalog(&info, &h, &sat, &ssat, &sst,
+ &dir, &scn)) == -1) {
+ corrupt = expn;
+ if ((i = cdf_read_encrypted_package(&info, &h,
+ &sat, &ssat, &sst, &dir, &scn)) == -1)
+ expn = "No summary info";
+ else {
+ expn = "Encrypted";
+ i = -1;
+ }
+ goto out4;
+ }
+#ifdef CDF_DEBUG
+ cdf_dump_catalog(&h, &scn);
+#endif
+ if ((i = cdf_file_catalog(ms, &h, &scn))
+ < 0)
+ expn = "Can't expand catalog";
} else {
expn = "Cannot read summary info";
}
@@ -464,7 +512,8 @@ out0:
if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
return -1;
} else {
- if (file_printf(ms, "application/CDFV2-corrupt") == -1)
+ if (file_printf(ms, "application/CDFV2-%s",
+ *corrupt ? "corrupt" : "encrypted") == -1)
return -1;
}
i = 1;
diff --git a/contrib/file/src/readelf.c b/contrib/file/src/readelf.c
index 55b7e98..08a2afb 100644
--- a/contrib/file/src/readelf.c
+++ b/contrib/file/src/readelf.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.103 2014/05/02 02:25:10 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.111 2014/12/09 02:47:45 christos Exp $")
#endif
#ifdef BUILTIN_ELF
@@ -60,8 +60,9 @@ private uint16_t getu16(int, uint16_t);
private uint32_t getu32(int, uint32_t);
private uint64_t getu64(int, uint64_t);
-#define MAX_PHNUM 256
-#define MAX_SHNUM 1024
+#define MAX_PHNUM 128
+#define MAX_SHNUM 32768
+#define SIZE_UNKNOWN ((off_t)-1)
private int
toomany(struct magic_set *ms, const char *name, uint16_t num)
@@ -324,7 +325,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
}
off += size;
- if (xph_offset > fsize) {
+ if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
/* Perhaps warn here */
continue;
}
@@ -964,7 +965,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
stripped = 0;
break;
default:
- if (xsh_offset > fsize) {
+ if (fsize != SIZE_UNKNOWN && xsh_offset > fsize) {
/* Perhaps warn here */
continue;
}
@@ -1190,7 +1191,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
shared_libraries = " (uses shared libs)";
break;
default:
- if (xph_offset > fsize) {
+ if (fsize != SIZE_UNKNOWN && xph_offset > fsize) {
/* Maybe warn here? */
continue;
}
@@ -1200,7 +1201,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
/* Things we can determine when we seek */
switch (xph_type) {
case PT_NOTE:
- if ((align = xph_align) & 0x80000000UL) {
+ if (((align = xph_align) & 0x80000000UL) != 0 ||
+ align < 4) {
if (file_printf(ms,
", invalid note alignment 0x%lx",
(unsigned long)align) == -1)
@@ -1283,7 +1285,10 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
file_badread(ms);
return -1;
}
- fsize = st.st_size;
+ if (S_ISREG(st.st_mode) || st.st_size != 0)
+ fsize = st.st_size;
+ else
+ fsize = SIZE_UNKNOWN;
clazz = buf[EI_CLASS];
diff --git a/contrib/file/src/softmagic.c b/contrib/file/src/softmagic.c
index b0f193d..c20ae67 100644
--- a/contrib/file/src/softmagic.c
+++ b/contrib/file/src/softmagic.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.191 2014/06/04 17:36:34 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.203 2014/12/04 15:22:05 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -41,17 +41,13 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.191 2014/06/04 17:36:34 christos Exp $")
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
-#if defined(HAVE_LOCALE_H)
-#include <locale.h>
-#endif
-
private int match(struct magic_set *, struct magic *, uint32_t,
- const unsigned char *, size_t, size_t, int, int, int, int, int *, int *,
- int *);
+ const unsigned char *, size_t, size_t, int, int, int, uint16_t,
+ uint16_t *, int *, int *, int *);
private int mget(struct magic_set *, const unsigned char *,
- struct magic *, size_t, size_t, unsigned int, int, int, int, int, int *,
- int *, int *);
+ struct magic *, size_t, size_t, unsigned int, int, int, int, uint16_t,
+ uint16_t *, int *, int *, int *);
private int magiccheck(struct magic_set *, struct magic *);
private int32_t mprint(struct magic_set *, struct magic *);
private int32_t moffset(struct magic_set *, struct magic *);
@@ -68,8 +64,6 @@ private void cvt_64(union VALUETYPE *, const struct magic *);
#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
-#define MAX_RECURSION_LEVEL 10
-
/*
* softmagic - lookup one file in parsed, in-memory copy of database
* Passed the name and FILE * of one file to be typed.
@@ -77,14 +71,21 @@ private void cvt_64(union VALUETYPE *, const struct magic *);
/*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */
protected int
file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
- size_t level, int mode, int text)
+ uint16_t indir_level, uint16_t *name_count, int mode, int text)
{
struct mlist *ml;
int rv, printed_something = 0, need_separator = 0;
+ uint16_t nc;
+
+ if (name_count == NULL) {
+ nc = 0;
+ name_count = &nc;
+ }
+
for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
- text, 0, level, &printed_something, &need_separator,
- NULL)) != 0)
+ text, 0, indir_level, name_count,
+ &printed_something, &need_separator, NULL)) != 0)
return rv;
return 0;
@@ -101,8 +102,8 @@ file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
const char *ptr = fmtcheck(m->desc, def);
if (ptr == def)
file_magerror(ms,
- "%s, %zu: format `%s' does not match with `%s'",
- file, line, m->desc, def);
+ "%s, %" SIZE_T_FORMAT "u: format `%s' does not match"
+ " with `%s'", file, line, m->desc, def);
return ptr;
}
#else
@@ -139,8 +140,8 @@ file_fmtcheck(struct magic_set *ms, const struct magic *m, const char *def,
private int
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
const unsigned char *s, size_t nbytes, size_t offset, int mode, int text,
- int flip, int recursion_level, int *printed_something, int *need_separator,
- int *returnval)
+ int flip, uint16_t indir_level, uint16_t *name_count,
+ int *printed_something, int *need_separator, int *returnval)
{
uint32_t magindex = 0;
unsigned int cont_level = 0;
@@ -177,8 +178,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
/* if main entry matches, print it... */
switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
- flip, recursion_level + 1, printed_something,
- need_separator, returnval)) {
+ flip, indir_level, name_count,
+ printed_something, need_separator, returnval)) {
case -1:
return -1;
case 0:
@@ -238,9 +239,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
if (file_check_mem(ms, ++cont_level) == -1)
return -1;
- while (++magindex < nmagic &&
- magic[magindex].cont_level != 0) {
- m = &magic[magindex];
+ while (magindex + 1 < nmagic &&
+ magic[magindex + 1].cont_level != 0) {
+ m = &magic[++magindex];
ms->line = m->lineno; /* for messages */
if (cont_level < m->cont_level)
@@ -266,8 +267,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
}
#endif
switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
- text, flip, recursion_level + 1, printed_something,
- need_separator, returnval)) {
+ text, flip, indir_level, name_count,
+ printed_something, need_separator, returnval)) {
case -1:
return -1;
case 0:
@@ -403,6 +404,28 @@ strndup(const char *str, size_t n)
}
#endif /* HAVE_STRNDUP */
+static char *
+printable(char *buf, size_t bufsiz, const char *str)
+{
+ char *ptr, *eptr;
+ const unsigned char *s = (const unsigned char *)str;
+
+ for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) {
+ if (isprint(*s)) {
+ *ptr++ = *s;
+ continue;
+ }
+ if (ptr >= eptr + 4)
+ break;
+ *ptr++ = '\\';
+ *ptr++ = ((*s >> 6) & 7) + '0';
+ *ptr++ = ((*s >> 3) & 7) + '0';
+ *ptr++ = ((*s >> 0) & 7) + '0';
+ }
+ *ptr = '\0';
+ return buf;
+}
+
private int32_t
mprint(struct magic_set *ms, struct magic *m)
{
@@ -509,6 +532,7 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + m->vallen;
}
else {
+ char sbuf[512];
char *str = p->s;
/* compute t before we mangle the string? */
@@ -530,7 +554,8 @@ mprint(struct magic_set *ms, struct magic *m)
*++last = '\0';
}
- if (file_printf(ms, F(ms, m, "%s"), str) == -1)
+ if (file_printf(ms, F(ms, m, "%s"),
+ printable(sbuf, sizeof(sbuf), str)) == -1)
return -1;
if (m->type == FILE_PSTRING)
@@ -946,14 +971,17 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
size_t sz = file_pstring_length_size(m);
char *ptr1 = p->s, *ptr2 = ptr1 + sz;
size_t len = file_pstring_get_length(m, ptr1);
- if (len >= sizeof(p->s)) {
+ sz = sizeof(p->s) - sz; /* maximum length of string */
+ if (len >= sz) {
/*
* The size of the pascal string length (sz)
* is 1, 2, or 4. We need at least 1 byte for NUL
* termination, but we've already truncated the
* string by p->s, so we need to deduct sz.
+ * Because we can use one of the bytes of the length
+ * after we shifted as NUL termination.
*/
- len = sizeof(p->s) - sz;
+ len = sz;
}
while (len--)
*ptr1++ = *ptr2++;
@@ -1063,7 +1091,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
private void
mdebug(uint32_t offset, const char *str, size_t len)
{
- (void) fprintf(stderr, "mget/%zu @%d: ", len, offset);
+ (void) fprintf(stderr, "mget/%" SIZE_T_FORMAT "u @%d: ", len, offset);
file_showstr(stderr, str, len);
(void) fputc('\n', stderr);
(void) fputc('\n', stderr);
@@ -1193,8 +1221,8 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
private int
mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
size_t nbytes, size_t o, unsigned int cont_level, int mode, int text,
- int flip, int recursion_level, int *printed_something,
- int *need_separator, int *returnval)
+ int flip, uint16_t indir_level, uint16_t *name_count,
+ int *printed_something, int *need_separator, int *returnval)
{
uint32_t offset = ms->offset;
uint32_t lhs;
@@ -1204,8 +1232,15 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
union VALUETYPE *p = &ms->ms_value;
struct mlist ml;
- if (recursion_level >= MAX_RECURSION_LEVEL) {
- file_error(ms, 0, "recursion nesting exceeded");
+ if (indir_level >= ms->indir_max) {
+ file_error(ms, 0, "indirect recursion nesting (%hu) exceeded",
+ indir_level);
+ return -1;
+ }
+
+ if (*name_count >= ms->name_max) {
+ file_error(ms, 0, "name use count (%hu) exceeded",
+ *name_count);
return -1;
}
@@ -1214,8 +1249,11 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
- fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
- "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes);
+ fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%"
+ SIZE_T_FORMAT "u, " "nbytes=%" SIZE_T_FORMAT
+ "u, il=%hu, nc=%hu)\n",
+ m->type, m->flag, offset, o, nbytes,
+ indir_level, *name_count);
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
#ifndef COMPILE_ONLY
file_mdump(m);
@@ -1656,7 +1694,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
return -1;
rv = file_softmagic(ms, s + offset, nbytes - offset,
- recursion_level, BINTEST, text);
+ indir_level + 1, name_count, BINTEST, text);
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
@@ -1691,13 +1729,13 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
file_error(ms, 0, "cannot find entry `%s'", rbuf);
return -1;
}
-
+ (*name_count)++;
oneed_separator = *need_separator;
if (m->flag & NOSPACE)
*need_separator = 0;
rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
- mode, text, flip, recursion_level, printed_something,
- need_separator, returnval);
+ mode, text, flip, indir_level, name_count,
+ printed_something, need_separator, returnval);
if (rv != 1)
*need_separator = oneed_separator;
return rv;
@@ -1952,6 +1990,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
case FILE_REGEX: {
int rc;
file_regex_t rx;
+ const char *search;
if (ms->search.s == NULL)
return 0;
@@ -1968,19 +2007,31 @@ magiccheck(struct magic_set *ms, struct magic *m)
size_t slen = ms->search.s_len;
#ifndef REG_STARTEND
#define REG_STARTEND 0
- char c;
- if (slen != 0)
- slen--;
- c = ms->search.s[slen];
- ((char *)(intptr_t)ms->search.s)[slen] = '\0';
+ char *copy;
+ if (slen != 0) {
+ copy = malloc(slen);
+ if (copy == NULL) {
+ file_error(ms, errno,
+ "can't allocate %" SIZE_T_FORMAT "u bytes",
+ slen);
+ return -1;
+ }
+ memcpy(copy, ms->search.s, slen);
+ copy[--slen] = '\0';
+ search = copy;
+ } else {
+ search = ms->search.s;
+ copy = NULL;
+ }
#else
+ search = ms->search.s;
pmatch[0].rm_so = 0;
pmatch[0].rm_eo = slen;
#endif
- rc = file_regexec(&rx, (const char *)ms->search.s,
+ rc = file_regexec(&rx, (const char *)search,
1, pmatch, REG_STARTEND);
#if REG_STARTEND == 0
- ((char *)(intptr_t)ms->search.s)[l] = c;
+ free(copy);
#endif
switch (rc) {
case 0:
diff --git a/contrib/file/src/vasprintf.c b/contrib/file/src/vasprintf.c
index cc43ae3..7a18bed 100644
--- a/contrib/file/src/vasprintf.c
+++ b/contrib/file/src/vasprintf.c
@@ -108,7 +108,7 @@ you use strange formats.
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: vasprintf.c,v 1.12 2014/05/14 23:09:21 christos Exp $")
+FILE_RCSID("@(#)$File: vasprintf.c,v 1.13 2014/12/04 15:56:46 christos Exp $")
#endif /* lint */
#include <assert.h>
@@ -633,11 +633,15 @@ int vasprintf(char **ptr, const char *format_string, va_list vargs)
#ifdef va_copy
va_copy (s.vargs, vargs);
#else
-#ifdef __va_copy
+# ifdef __va_copy
__va_copy (s.vargs, vargs);
-#else
+# else
+# ifdef WIN32
+ s.vargs = vargs;
+# else
memcpy (&s.vargs, &vargs, sizeof (s.va_args));
-#endif /* __va_copy */
+# endif /* WIN32 */
+# endif /* __va_copy */
#endif /* va_copy */
s.maxlen = (size_t)INT_MAX;
OpenPOWER on IntegriCloud