diff options
Diffstat (limited to 'contrib/file/src')
-rw-r--r-- | contrib/file/src/Makefile.in | 31 | ||||
-rw-r--r-- | contrib/file/src/apprentice.c | 46 | ||||
-rw-r--r-- | contrib/file/src/ascmagic.c | 6 | ||||
-rw-r--r-- | contrib/file/src/cdf.c | 124 | ||||
-rw-r--r-- | contrib/file/src/cdf.h | 9 | ||||
-rw-r--r-- | contrib/file/src/compress.c | 19 | ||||
-rw-r--r-- | contrib/file/src/encoding.c | 38 | ||||
-rw-r--r-- | contrib/file/src/file.c | 61 | ||||
-rw-r--r-- | contrib/file/src/file.h | 21 | ||||
-rw-r--r-- | contrib/file/src/file_opts.h | 10 | ||||
-rw-r--r-- | contrib/file/src/fsmagic.c | 4 | ||||
-rw-r--r-- | contrib/file/src/funcs.c | 36 | ||||
-rw-r--r-- | contrib/file/src/gmtime_r.c | 19 | ||||
-rw-r--r-- | contrib/file/src/is_tar.c | 4 | ||||
-rw-r--r-- | contrib/file/src/localtime_r.c | 19 | ||||
-rw-r--r-- | contrib/file/src/magic.c | 166 | ||||
-rw-r--r-- | contrib/file/src/magic.h | 53 | ||||
-rw-r--r-- | contrib/file/src/magic.h.in | 51 | ||||
-rw-r--r-- | contrib/file/src/print.c | 40 | ||||
-rw-r--r-- | contrib/file/src/readcdf.c | 142 | ||||
-rw-r--r-- | contrib/file/src/readelf.c | 10 | ||||
-rw-r--r-- | contrib/file/src/softmagic.c | 85 |
22 files changed, 651 insertions, 343 deletions
diff --git a/contrib/file/src/Makefile.in b/contrib/file/src/Makefile.in index 41cb9f5..5e69c00 100644 --- a/contrib/file/src/Makefile.in +++ b/contrib/file/src/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.14 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -17,7 +17,17 @@ VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -81,10 +91,6 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = file$(EXEEXT) subdir = src -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ctime_r.c \ - vasprintf.c asctime_r.c asprintf.c strcasestr.c pread.c \ - getline.c strlcpy.c strlcat.c fmtcheck.c getopt_long.c \ - $(top_srcdir)/depcomp $(include_HEADERS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ @@ -92,6 +98,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = @@ -205,6 +213,10 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ + asctime_r.c asprintf.c ctime_r.c fmtcheck.c getline.c \ + getopt_long.c gmtime_r.c localtime_r.c pread.c strcasestr.c \ + strlcat.c strlcpy.c vasprintf.c DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) pkgdatadir = @pkgdatadir@ ACLOCAL = @ACLOCAL@ @@ -363,7 +375,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -485,6 +496,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fmtcheck.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getopt_long.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gmtime_r.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/localtime_r.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strcasestr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strlcat.Plo@am__quote@ @@ -774,6 +787,8 @@ uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-includeHEADERS uninstall-libLTLIBRARIES +.PRECIOUS: Makefile + magic.h: ${HDR} sed -e "s/X.YY/$$(echo @VERSION@ | tr -d .)/" < ${HDR} > $@ diff --git a/contrib/file/src/apprentice.c b/contrib/file/src/apprentice.c index 47b4c87..607201c 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.229 2015/01/01 17:07:34 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.233 2015/06/10 00:57:41 christos Exp $") #endif /* lint */ #include "magic.h" @@ -149,6 +149,7 @@ private int get_op(char); private int parse_mime(struct magic_set *, struct magic_entry *, const char *); private int parse_strength(struct magic_set *, struct magic_entry *, const char *); private int parse_apple(struct magic_set *, struct magic_entry *, const char *); +private int parse_ext(struct magic_set *, struct magic_entry *, const char *); private size_t magicsize = sizeof(struct magic); @@ -163,6 +164,7 @@ private struct { #define DECLARE_FIELD(name) { # name, sizeof(# name) - 1, parse_ ## name } DECLARE_FIELD(mime), DECLARE_FIELD(apple), + DECLARE_FIELD(ext), DECLARE_FIELD(strength), #undef DECLARE_FIELD { NULL, 0, NULL } @@ -964,8 +966,9 @@ apprentice_list(struct mlist *mlist, int mode) *ml->magic[magindex].mimetype == '\0') magindex++; - printf("Strength = %3" SIZE_T_FORMAT "u : %s [%s]\n", + printf("Strength = %3" SIZE_T_FORMAT "u@%u: %s [%s]\n", apprentice_magic_strength(m), + ml->magic[magindex].lineno, ml->magic[magindex].desc, ml->magic[magindex].mimetype); } @@ -1839,15 +1842,19 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, } } /* Indirect offsets are not valid at level 0. */ - if (m->cont_level == 0 && (m->flag & (OFFADD | INDIROFFADD))) + if (m->cont_level == 0 && (m->flag & (OFFADD | INDIROFFADD))) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "relative offset at level 0"); + return -1; + } /* get offset, then skip over it */ m->offset = (uint32_t)strtoul(l, &t, 0); - if (l == t) + if (l == t) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "offset `%s' invalid", l); + return -1; + } l = t; if (m->flag & INDIR) { @@ -1903,7 +1910,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, file_magwarn(ms, "indirect offset type `%c' invalid", *l); - break; + return -1; } l++; } @@ -1923,17 +1930,21 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, } if (isdigit((unsigned char)*l) || *l == '-') { m->in_offset = (int32_t)strtol(l, &t, 0); - if (l == t) + if (l == t) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "in_offset `%s' invalid", l); + return -1; + } l = t; } if (*l++ != ')' || - ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) + ((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "missing ')' in indirect offset"); + return -1; + } } EATAB; @@ -2199,7 +2210,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line, size_t i; const char *l = line; struct magic *m = &me->mp[me->cont_count == 0 ? 0 : me->cont_count - 1]; - char *buf = (char *)m + off; + char *buf = CAST(char *, CAST(void *, m)) + off; if (buf[0] != '\0') { len = nt ? strlen(buf) : len; @@ -2248,11 +2259,25 @@ 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), + return parse_extra(ms, me, line, + CAST(off_t, offsetof(struct magic, apple)), sizeof(m->apple), "APPLE", "!+-./", 0); } /* + * Parse a comma-separated list of extensions + */ +private int +parse_ext(struct magic_set *ms, struct magic_entry *me, const char *line) +{ + struct magic *m = &me->mp[0]; + + return parse_extra(ms, me, line, + CAST(off_t, offsetof(struct magic, ext)), + sizeof(m->ext), "EXTENSION", ",!+-/", 0); +} + +/* * parse a MIME annotation line from magic file, put into magic[index - 1] * if valid */ @@ -2261,7 +2286,8 @@ 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), + return parse_extra(ms, me, line, + CAST(off_t, offsetof(struct magic, mimetype)), sizeof(m->mimetype), "MIME", "+-/.", 1); } diff --git a/contrib/file/src/ascmagic.c b/contrib/file/src/ascmagic.c index 78a6dbb..9e0f663 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.91 2014/11/28 02:46:39 christos Exp $") +FILE_RCSID("@(#)$File: ascmagic.c,v 1.92 2015/04/09 20:01:41 christos Exp $") #endif /* lint */ #include "magic.h" @@ -79,7 +79,7 @@ file_ascmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, const char *code_mime = NULL; const char *type = NULL; - if (ms->flags & MAGIC_APPLE) + if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) return 0; nbytes = trim_nuls(buf, nbytes); @@ -123,7 +123,7 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, size_t last_line_end = (size_t)-1; int has_long_lines = 0; - if (ms->flags & MAGIC_APPLE) + if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) return 0; nbytes = trim_nuls(buf, nbytes); diff --git a/contrib/file/src/cdf.c b/contrib/file/src/cdf.c index 9e3cf9f..c979b1d 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.69 2014/12/04 15:56:46 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.76 2015/02/28 00:18:02 christos Exp $") #endif #include <assert.h> @@ -73,8 +73,11 @@ 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_TOLE(x) (/*CONSTCOND*/sizeof(x) == 2 ? \ + CDF_TOLE2(CAST(uint16_t, x)) : \ + (/*CONSTCOND*/sizeof(x) == 4 ? \ + CDF_TOLE4(CAST(uint32_t, x)) : \ + CDF_TOLE8(CAST(uint64_t, x)))) #define CDF_GETUINT32(x, y) cdf_getuint32(x, y) @@ -271,7 +274,7 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h, const char *e = ((const char *)p) + tail; size_t ss = sst->sst_dirlen < h->h_min_size_standard_stream ? CDF_SHORT_SEC_SIZE(h) : CDF_SEC_SIZE(h); - (void)&line; + /*LINTED*/(void)&line; if (e >= b && (size_t)(e - b) <= ss * sst->sst_len) return 0; DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u" @@ -744,24 +747,33 @@ cdf_read_user_stream(const cdf_info_t *info, const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, const cdf_dir_t *dir, const char *name, cdf_stream_t *scn) { - size_t i; const cdf_directory_t *d; - size_t name_len = strlen(name) + 1; + int i = cdf_find_stream(dir, name, CDF_DIR_TYPE_USER_STREAM); + + if (i <= 0) + return -1; + + d = &dir->dir_tab[i - 1]; + return cdf_read_sector_chain(info, h, sat, ssat, sst, + d->d_stream_first_sector, d->d_size, scn); +} + +int +cdf_find_stream(const cdf_dir_t *dir, const char *name, int type) +{ + size_t i, name_len = strlen(name) + 1; for (i = dir->dir_len; i > 0; i--) - if (dir->dir_tab[i - 1].d_type == CDF_DIR_TYPE_USER_STREAM && + if (dir->dir_tab[i - 1].d_type == type && cdf_namecmp(name, dir->dir_tab[i - 1].d_name, name_len) == 0) break; + if (i > 0) + return i; - if (i == 0) { - DPRINTF(("Cannot find user stream `%s'\n", name)); - errno = ESRCH; - return -1; - } - d = &dir->dir_tab[i - 1]; - return cdf_read_sector_chain(info, h, sat, ssat, sst, - d->d_stream_first_sector, d->d_size, scn); + DPRINTF(("Cannot find type %d `%s'\n", type, name)); + errno = ESRCH; + return 0; } int @@ -998,9 +1010,13 @@ 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) +#define extract_catalog_field(t, f, l) \ + if (b + l + sizeof(cep->f) > eb) { \ + cep->ce_namlen = 0; \ + break; \ + } \ + memcpy(&cep->f, b + (l), sizeof(cep->f)); \ + ce[i].f = CAST(t, CDF_TOLE(cep->f)) int cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst, @@ -1010,40 +1026,58 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst, 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; + size_t nr, i, j, k; cdf_catalog_entry_t *ce; uint16_t reclen; const uint16_t *np; - for (nr = 0; b < eb; nr++) { + for (nr = 0;; nr++) { memcpy(&reclen, b, sizeof(reclen)); reclen = CDF_TOLE2(reclen); if (reclen == 0) break; b += reclen; + if (b > eb) + break; } + nr--; *cat = CAST(cdf_catalog_t *, malloc(sizeof(cdf_catalog_t) + nr * sizeof(*ce))); - (*cat)->cat_num = nr; ce = (*cat)->cat_e; + memset(ce, 0, nr * sizeof(*ce)); 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]); + for (j = i = 0; i < nr; b += reclen) { + cdf_catalog_entry_t *cep = &ce[j]; + uint16_t rlen; + + extract_catalog_field(uint16_t, ce_namlen, 0); + extract_catalog_field(uint16_t, ce_num, 4); + extract_catalog_field(uint64_t, ce_timestamp, 8); + reclen = cep->ce_namlen; + + if (reclen < 14) { + cep->ce_namlen = 0; + continue; } - ce[i].ce_name[ce[i].ce_namlen] = 0; - b += reclen; + + cep->ce_namlen = __arraycount(cep->ce_name) - 1; + rlen = reclen - 14; + if (cep->ce_namlen > rlen) + cep->ce_namlen = rlen; + + np = CAST(const uint16_t *, CAST(const void *, (b + 16))); + if (CAST(const char *, np + cep->ce_namlen) > eb) { + cep->ce_namlen = 0; + break; + } + + for (k = 0; k < cep->ce_namlen; k++) + cep->ce_name[k] = np[k]; /* XXX: CDF_TOLE2? */ + cep->ce_name[cep->ce_namlen] = 0; + j = i; + i++; } + (*cat)->cat_num = j; return 0; } @@ -1188,11 +1222,12 @@ cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size) } void -cdf_dump(void *v, size_t len) +cdf_dump(const void *v, size_t len) { size_t i, j; - unsigned char *p = v; + const unsigned char *p = v; char abuf[16]; + (void)fprintf(stderr, "%.4x: ", 0); for (i = 0, j = 0; i < len; i++, p++) { (void)fprintf(stderr, "%.2x ", *p); @@ -1327,10 +1362,10 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count) cdf_print_elapsed_time(buf, sizeof(buf), tp); (void)fprintf(stderr, "timestamp %s\n", buf); } else { - char buf[26]; + char tbuf[26]; cdf_timestamp_to_timespec(&ts, tp); (void)fprintf(stderr, "timestamp %s", - cdf_ctime(&ts.tv_sec, buf)); + cdf_ctime(&ts.tv_sec, tbuf)); } break; case CDF_CLIPBOARD: @@ -1401,7 +1436,10 @@ main(int argc, char *argv[]) cdf_dir_t dir; cdf_info_t info; const cdf_directory_t *root; - +#ifdef __linux__ +#define getprogname() __progname + extern char *__progname; +#endif if (argc < 2) { (void)fprintf(stderr, "Usage: %s <filename>\n", getprogname()); return -1; @@ -1453,8 +1491,8 @@ main(int argc, char *argv[]) else cdf_dump_summary_info(&h, &scn); #endif - if (cdf_read_catalog(&info, &h, &sat, &ssat, &sst, &dir, - &scn) == -1) + if (cdf_read_user_stream(&info, &h, &sat, &ssat, &sst, + &dir, "Catalog", &scn) == -1) warn("Cannot read catalog"); #ifdef CDF_DEBUG else diff --git a/contrib/file/src/cdf.h b/contrib/file/src/cdf.h index 64e3648..cee8d77 100644 --- a/contrib/file/src/cdf.h +++ b/contrib/file/src/cdf.h @@ -314,12 +314,7 @@ 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_find_stream(const cdf_dir_t *, const char *, int); 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 *); @@ -339,7 +334,7 @@ char *cdf_u16tos8(char *, size_t, const uint16_t *); #ifdef CDF_DEBUG void cdf_dump_header(const cdf_header_t *); void cdf_dump_sat(const char *, const cdf_sat_t *, size_t); -void cdf_dump(void *, size_t); +void cdf_dump(const void *, size_t); void cdf_dump_stream(const cdf_header_t *, const cdf_stream_t *); 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 *); diff --git a/contrib/file/src/compress.c b/contrib/file/src/compress.c index e968bb4..539031e 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.77 2014/12/12 16:33:01 christos Exp $") +FILE_RCSID("@(#)$File: compress.c,v 1.80 2015/06/03 18:21:24 christos Exp $") #endif #include "magic.h" @@ -45,7 +45,12 @@ FILE_RCSID("@(#)$File: compress.c,v 1.77 2014/12/12 16:33:01 christos Exp $") #endif #include <string.h> #include <errno.h> +#ifdef HAVE_SIGNAL_H #include <signal.h> +# ifndef HAVE_SIG_T +typedef void (*sig_t)(int); +# endif /* HAVE_SIG_T */ +#endif #if !defined(__MINGW32__) && !defined(WIN32) #include <sys/ioctl.h> #endif @@ -104,12 +109,16 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, size_t i, nsz; int rv = 0; int mime = ms->flags & MAGIC_MIME; +#ifdef HAVE_SIGNAL_H sig_t osigpipe; +#endif if ((ms->flags & MAGIC_COMPRESS) == 0) return 0; +#ifdef HAVE_SIGNAL_H osigpipe = signal(SIGPIPE, SIG_IGN); +#endif for (i = 0; i < ncompr; i++) { if (nbytes < compr[i].maglen) continue; @@ -121,7 +130,8 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, if (file_buffer(ms, -1, name, newbuf, nsz) == -1) goto error; - if (mime == MAGIC_MIME || mime == 0) { + if ((ms->flags & MAGIC_COMPRESS_TRANSP) == 0 && + (mime == MAGIC_MIME || mime == 0)) { if (file_printf(ms, mime ? " compressed-encoding=" : " (") == -1) goto error; @@ -136,7 +146,9 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, } } error: +#ifdef HAVE_SIGNAL_H (void)signal(SIGPIPE, osigpipe); +#endif free(newbuf); ms->flags |= MAGIC_COMPRESS; return rv; @@ -383,7 +395,6 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method, int fdin[2], fdout[2]; int status; ssize_t r; - pid_t pid; #ifdef BUILTIN_DECOMPRESS /* FIXME: This doesn't cope with bzip2 */ @@ -397,7 +408,7 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method, file_error(ms, errno, "cannot create pipe"); return NODATA; } - switch (pid = fork()) { + switch (fork()) { case 0: /* child */ (void) close(0); if (fd != -1) { diff --git a/contrib/file/src/encoding.c b/contrib/file/src/encoding.c index c1b23cc..3c116cd 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.10 2014/09/11 12:08:52 christos Exp $") +FILE_RCSID("@(#)$File: encoding.c,v 1.13 2015/06/04 19:16:28 christos Exp $") #endif /* lint */ #include "magic.h" @@ -47,6 +47,7 @@ FILE_RCSID("@(#)$File: encoding.c,v 1.10 2014/09/11 12:08:52 christos Exp $") private int looks_ascii(const unsigned char *, size_t, unichar *, size_t *); private int looks_utf8_with_BOM(const unsigned char *, size_t, unichar *, size_t *); +private int looks_utf7(const unsigned char *, size_t, unichar *, size_t *); private int looks_ucs16(const unsigned char *, size_t, unichar *, size_t *); private int looks_latin1(const unsigned char *, size_t, unichar *, size_t *); private int looks_extended(const unsigned char *, size_t, unichar *, size_t *); @@ -88,9 +89,15 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni } if (looks_ascii(buf, nbytes, *ubuf, ulen)) { - DPRINTF(("ascii %" SIZE_T_FORMAT "u\n", *ulen)); - *code = "ASCII"; - *code_mime = "us-ascii"; + if (looks_utf7(buf, nbytes, *ubuf, ulen) > 0) { + DPRINTF(("utf-7 %" SIZE_T_FORMAT "u\n", *ulen)); + *code = "UTF-7 Unicode"; + *code_mime = "utf-7"; + } else { + DPRINTF(("ascii %" SIZE_T_FORMAT "u\n", *ulen)); + *code = "ASCII"; + *code_mime = "us-ascii"; + } } else if (looks_utf8_with_BOM(buf, nbytes, *ubuf, ulen) > 0) { DPRINTF(("utf8/bom %" SIZE_T_FORMAT "u\n", *ulen)); *code = "UTF-8 Unicode (with BOM)"; @@ -199,8 +206,8 @@ file_encoding(struct magic_set *ms, const unsigned char *buf, size_t nbytes, uni #define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */ private char text_chars[256] = { - /* BEL BS HT LF FF CR */ - F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */ + /* BEL BS HT LF VT FF CR */ + F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, /* 0x0X */ /* ESC */ F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */ @@ -372,6 +379,25 @@ looks_utf8_with_BOM(const unsigned char *buf, size_t nbytes, unichar *ubuf, } private int +looks_utf7(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen) +{ + if (nbytes > 4 && buf[0] == '+' && buf[1] == '/' && buf[2] == 'v') + switch (buf[3]) { + case '8': + case '9': + case '+': + case '/': + if (ubuf) + *ulen = 0; + return 1; + default: + return -1; + } + else + return -1; +} + +private int looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen) { diff --git a/contrib/file/src/file.c b/contrib/file/src/file.c index 546fd8b..c700f66 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.160 2014/12/16 23:18:40 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.164 2015/06/03 18:21:24 christos Exp $") #endif /* lint */ #include "magic.h" @@ -68,14 +68,14 @@ int getopt_long(int argc, char * const *argv, const char *optstring, const struc #endif #ifdef S_IFLNK -#define FILE_FLAGS "-bcEhikLlNnprsvz0" +#define FILE_FLAGS "-bcEhikLlNnprsvzZ0" #else -#define FILE_FLAGS "-bcEiklNnprsvz0" +#define FILE_FLAGS "-bcEiklNnprsvzZ0" #endif # define USAGE \ "Usage: %s [" FILE_FLAGS \ - "] [--apple] [--mime-encoding] [--mime-type]\n" \ + "] [--apple] [--extension] [--mime-encoding] [--mime-type]\n" \ " [-e testname] [-F separator] [-f namefile] [-m magicfiles] " \ "file ...\n" \ " %s -C [-m magicfiles]\n" \ @@ -89,16 +89,21 @@ private int /* Global command-line options */ private const char *separator = ":"; /* Default field separator */ private const struct option long_options[] = { +#define OPT_HELP 1 +#define OPT_APPLE 2 +#define OPT_EXTENSIONS 3 +#define OPT_MIME_TYPE 4 +#define OPT_MIME_ENCODING 5 #define OPT(shortname, longname, opt, doc) \ {longname, opt, NULL, shortname}, -#define OPT_LONGONLY(longname, opt, doc) \ - {longname, opt, NULL, 0}, +#define OPT_LONGONLY(longname, opt, doc, id) \ + {longname, opt, NULL, id}, #include "file_opts.h" #undef OPT #undef OPT_LONGONLY {0, 0, NULL, 0} }; -#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsvz0" +#define OPTSTRING "bcCde:Ef:F:hiklLm:nNpP:rsvzZ0" private const struct { const char *name; @@ -130,8 +135,14 @@ private struct { private char *progname; /* used throughout */ +#ifdef __dead +__dead +#endif private void usage(void); private void docprint(const char *); +#ifdef __dead +__dead +#endif private void help(void); private int unwrap(struct magic_set *, const char *); @@ -176,21 +187,20 @@ main(int argc, char *argv[]) while ((c = getopt_long(argc, argv, OPTSTRING, long_options, &longindex)) != -1) switch (c) { - case 0 : - switch (longindex) { - case 0: - help(); - break; - case 10: - flags |= MAGIC_APPLE; - break; - case 11: - flags |= MAGIC_MIME_TYPE; - break; - case 12: - flags |= MAGIC_MIME_ENCODING; - break; - } + case OPT_HELP: + help(); + break; + case OPT_APPLE: + flags |= MAGIC_APPLE; + break; + case OPT_EXTENSIONS: + flags |= MAGIC_EXTENSION; + break; + case OPT_MIME_TYPE: + flags |= MAGIC_MIME_TYPE; + break; + case OPT_MIME_ENCODING: + flags |= MAGIC_MIME_ENCODING; break; case '0': nulsep = 1; @@ -262,7 +272,6 @@ main(int argc, char *argv[]) case 'r': flags |= MAGIC_RAW; break; - break; case 's': flags |= MAGIC_DEVICES; break; @@ -276,6 +285,10 @@ main(int argc, char *argv[]) case 'z': flags |= MAGIC_COMPRESS; break; + + case 'Z': + flags |= MAGIC_COMPRESS|MAGIC_COMPRESS_TRANSP; + break; #ifdef S_IFLNK case 'L': flags |= MAGIC_SYMLINK; @@ -583,7 +596,7 @@ help(void) #define OPT(shortname, longname, opt, doc) \ fprintf(stdout, " -%c, --" longname, shortname), \ docprint(doc); -#define OPT_LONGONLY(longname, opt, doc) \ +#define OPT_LONGONLY(longname, opt, doc, id) \ fprintf(stdout, " --" longname), \ docprint(doc); #include "file_opts.h" diff --git a/contrib/file/src/file.h b/contrib/file/src/file.h index 01aa37a..1b4ef6f 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.164 2015/01/01 17:07:34 christos Exp $ + * @(#)$File: file.h,v 1.168 2015/04/09 20:01:41 christos Exp $ */ #ifndef __file_h__ @@ -126,7 +126,7 @@ #endif #ifndef HOWMANY -# define HOWMANY (256 * 1024) /* how much of the file to look at */ +# define HOWMANY (1024 * 1024) /* how much of the file to look at */ #endif #define MAXMAGIS 8192 /* max entries in any one magic file or directory */ @@ -135,8 +135,8 @@ #define MAXstring 64 /* max len of "string" types */ #define MAGICNO 0xF11E041C -#define VERSIONNO 12 -#define FILE_MAGICSIZE 248 +#define VERSIONNO 13 +#define FILE_MAGICSIZE 312 #define FILE_LOAD 0 #define FILE_CHECK 1 @@ -307,7 +307,9 @@ struct magic { /* Words 33-52 */ char mimetype[MAXMIME]; /* MIME type */ /* Words 53-54 */ - char apple[8]; + char apple[8]; /* APPLE CREATOR/TYPE */ + /* Words 55-63 */ + char ext[64]; /* Popular extensions */ }; #define BIT(A) (1 << (A)) @@ -564,6 +566,12 @@ char *ctime_r(const time_t *, char *); #ifndef HAVE_ASCTIME_R char *asctime_r(const struct tm *, char *); #endif +#ifndef HAVE_GMTIME_R +struct tm *gmtime_r(const time_t *, struct tm *); +#endif +#ifndef HAVE_LOCALTIME_R +struct tm *localtime_r(const time_t *, struct tm *); +#endif #ifndef HAVE_FMTCHECK const char *fmtcheck(const char *, const char *) __attribute__((__format_arg__(2))); @@ -590,5 +598,8 @@ static const char *rcsid(const char *p) { \ #else #define FILE_RCSID(id) #endif +#ifndef __RCSID +#define __RCSID(a) +#endif #endif /* __file_h__ */ diff --git a/contrib/file/src/file_opts.h b/contrib/file/src/file_opts.h index 3286ac6..2e30d06 100644 --- a/contrib/file/src/file_opts.h +++ b/contrib/file/src/file_opts.h @@ -12,11 +12,12 @@ * switch statement! */ -OPT_LONGONLY("help", 0, " display this help and exit\n") +OPT_LONGONLY("help", 0, " display this help and exit\n", OPT_HELP) OPT('v', "version", 0, " output version information and exit\n") OPT('m', "magic-file", 1, " LIST use LIST as a colon-separated list of magic\n" " number files\n") OPT('z', "uncompress", 0, " try to look inside compressed files\n") +OPT('Z', "uncompress-noreport", 0, " only print the contents of compressed files\n") OPT('b', "brief", 0, " do not prepend filenames to output lines\n") OPT('c', "checking-printout", 0, " print the parsed form of the magic file, use in\n" " conjunction with -m to debug a new magic file\n" @@ -28,9 +29,10 @@ OPT('f', "files-from", 1, " FILE read the filenames to be examined from FIL OPT('F', "separator", 1, " STRING use string as separator instead of `:'\n") OPT('i', "mime", 0, " output MIME type strings (--mime-type and\n" " --mime-encoding)\n") -OPT_LONGONLY("apple", 0, " output the Apple CREATOR/TYPE\n") -OPT_LONGONLY("mime-type", 0, " output the MIME type\n") -OPT_LONGONLY("mime-encoding", 0, " output the MIME encoding\n") +OPT_LONGONLY("apple", 0, " output the Apple CREATOR/TYPE\n", OPT_APPLE) +OPT_LONGONLY("extension", 0, " output a slash-separated list of extensions\n", OPT_EXTENSIONS) +OPT_LONGONLY("mime-type", 0, " output the MIME type\n", OPT_MIME_TYPE) +OPT_LONGONLY("mime-encoding", 0, " output the MIME encoding\n", OPT_MIME_ENCODING) OPT('k', "keep-going", 0, " don't stop at the first match\n") OPT('l', "list", 0, " list magic strength\n") #ifdef S_IFLNK diff --git a/contrib/file/src/fsmagic.c b/contrib/file/src/fsmagic.c index 1e8fd74..27f982a 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.75 2014/12/04 15:56:46 christos Exp $") +FILE_RCSID("@(#)$File: fsmagic.c,v 1.76 2015/04/09 20:01:41 christos Exp $") #endif /* lint */ #include "magic.h" @@ -110,7 +110,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb) struct stat tstatbuf; #endif - if (ms->flags & MAGIC_APPLE) + if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) return 0; if (fn == NULL) return 0; diff --git a/contrib/file/src/funcs.c b/contrib/file/src/funcs.c index a60ccaa..dc7bbd1 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.79 2014/12/16 20:52:49 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.82 2015/06/03 18:01:20 christos Exp $") #endif /* lint */ #include "magic.h" @@ -159,8 +159,20 @@ file_badread(struct magic_set *ms) } #ifndef COMPILE_ONLY + +static int +checkdone(struct magic_set *ms, int *rv) +{ + if ((ms->flags & MAGIC_CONTINUE) == 0) + return 1; + if (file_printf(ms, "\n- ") == -1) + *rv = -1; + return 0; +} + +/*ARGSUSED*/ protected int -file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unused)), +file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)), const void *buf, size_t nb) { int m = 0, rv = 0, looks_text = 0; @@ -214,7 +226,8 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu if ((m = file_is_tar(ms, ubuf, nb)) != 0) { if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "tar %d\n", m); - goto done; + if (checkdone(ms, &rv)) + goto done; } /* Check if we have a CDF file */ @@ -222,7 +235,8 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu if ((m = file_trycdf(ms, fd, ubuf, nb)) != 0) { if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "cdf %d\n", m); - goto done; + if (checkdone(ms, &rv)) + goto done; } /* try soft magic tests */ @@ -249,7 +263,8 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu "elf %d\n", m); } #endif - goto done; + if (checkdone(ms, &rv)) + goto done; } /* try text properties */ @@ -258,7 +273,8 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((unu if ((m = file_ascmagic(ms, ubuf, nb, looks_text)) != 0) { if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "ascmagic %d\n", m); - goto done; + if (checkdone(ms, &rv)) + goto done; } } @@ -400,7 +416,7 @@ file_check_mem(struct magic_set *ms, unsigned int level) size_t len; if (level >= ms->c.len) { - len = (ms->c.len += 20) * sizeof(*ms->c.li); + len = (ms->c.len = 20 + level) * sizeof(*ms->c.li); ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ? malloc(len) : realloc(ms->c.li, len)); @@ -549,9 +565,9 @@ file_printable(char *buf, size_t bufsiz, const char *str) if (ptr >= eptr - 3) break; *ptr++ = '\\'; - *ptr++ = ((*s >> 6) & 7) + '0'; - *ptr++ = ((*s >> 3) & 7) + '0'; - *ptr++ = ((*s >> 0) & 7) + '0'; + *ptr++ = ((CAST(unsigned int, *s) >> 6) & 7) + '0'; + *ptr++ = ((CAST(unsigned int, *s) >> 3) & 7) + '0'; + *ptr++ = ((CAST(unsigned int, *s) >> 0) & 7) + '0'; } *ptr = '\0'; return buf; diff --git a/contrib/file/src/gmtime_r.c b/contrib/file/src/gmtime_r.c new file mode 100644 index 0000000..963dfee --- /dev/null +++ b/contrib/file/src/gmtime_r.c @@ -0,0 +1,19 @@ +/* $File: gmtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $ */ + +#include "file.h" +#ifndef lint +FILE_RCSID("@(#)$File: gmtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $") +#endif /* lint */ +#include <time.h> +#include <string.h> + +/* asctime_r is not thread-safe anyway */ +struct tm * +gmtime_r(const time_t t, struct tm *tm) +{ + struct tm *tmp = gmtime(t); + if (tmp == NULL) + return NULL; + memcpy(tm, tmp, sizeof(*tm)); + return tmp; +} diff --git a/contrib/file/src/is_tar.c b/contrib/file/src/is_tar.c index 876c631..a3e5dbf 100644 --- a/contrib/file/src/is_tar.c +++ b/contrib/file/src/is_tar.c @@ -40,7 +40,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: is_tar.c,v 1.37 2010/11/30 14:58:53 rrt Exp $") +FILE_RCSID("@(#)$File: is_tar.c,v 1.38 2015/04/09 20:01:41 christos Exp $") #endif #include "magic.h" @@ -69,7 +69,7 @@ file_is_tar(struct magic_set *ms, const unsigned char *buf, size_t nbytes) int tar; int mime = ms->flags & MAGIC_MIME; - if ((ms->flags & MAGIC_APPLE) != 0) + if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0) return 0; tar = is_tar(buf, nbytes); diff --git a/contrib/file/src/localtime_r.c b/contrib/file/src/localtime_r.c new file mode 100644 index 0000000..69d78d9 --- /dev/null +++ b/contrib/file/src/localtime_r.c @@ -0,0 +1,19 @@ +/* $File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $ */ + +#include "file.h" +#ifndef lint +FILE_RCSID("@(#)$File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $") +#endif /* lint */ +#include <time.h> +#include <string.h> + +/* asctime_r is not thread-safe anyway */ +struct tm * +localtime_r(const time_t t, struct tm *tm) +{ + struct tm *tmp = localtime(t); + if (tmp == NULL) + return NULL; + memcpy(tm, tmp, sizeof(*tm)); + return tmp; +} diff --git a/contrib/file/src/magic.c b/contrib/file/src/magic.c index d16f8c6..bc8c344 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.91 2014/12/16 23:18:40 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.93 2015/04/15 23:47:58 christos Exp $") #endif /* lint */ #include "magic.h" @@ -83,6 +83,86 @@ private const char *file_or_fd(struct magic_set *, const char *, int); #define STDIN_FILENO 0 #endif +#ifdef WIN32 +/* HINSTANCE of this shared library. Needed for get_default_magic() */ +static HINSTANCE _w32_dll_instance = NULL; + +static void +_w32_append_path(char **hmagicpath, const char *fmt, ...) +{ + char *tmppath; + char *newpath; + va_list ap; + + va_start(ap, fmt); + if (vasprintf(&tmppath, fmt, ap) < 0) { + va_end(ap); + return; + } + va_end(ap); + + if (access(tmppath, R_OK) == -1) + goto out; + + if (*hmagicpath == NULL) { + *hmagicpath = tmppath; + return; + } + + if (asprintf(&newpath, "%s%c%s", *hmagicpath, PATHSEP, tmppath) < 0) + goto out; + + free(*hmagicpath); + free(tmppath); + *hmagicpath = newpath; + return; +out: + free(tmppath); +} + +static void +_w32_get_magic_relative_to(char **hmagicpath, HINSTANCE module) +{ + static const char *trypaths[] = { + "%s/share/misc/magic.mgc", + "%s/magic.mgc", + }; + LPSTR dllpath; + size_t sp; + + dllpath = calloc(MAX_PATH + 1, sizeof(*dllpath)); + + if (!GetModuleFileNameA(module, dllpath, MAX_PATH)) + goto out; + + PathRemoveFileSpecA(dllpath); + + sp = strlen(dllpath); + if (sp > 3 && stricmp(&dllpath[sp - 3], "bin") == 0) { + _w32_append_path(hmagicpath, + "%s/../share/misc/magic.mgc", dllpath); + goto out; + } + + for (sp = 0; sp < __arraycount(trypaths); sp++) + _w32_append_path(hmagicpath, trypaths[sp], dllpath); +out: + free(dllpath); +} + +/* Placate GCC by offering a sacrificial previous prototype */ +BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID); + +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, + LPVOID lpvReserved __attribute__((__unused__))) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + _w32_dll_instance = hinstDLL; + return TRUE; +} +#endif + private const char * get_default_magic(void) { @@ -126,75 +206,33 @@ out: free(hmagicpath); return MAGIC; #else - char *hmagicp; - char *tmppath = NULL; - LPTSTR dllpath; hmagicpath = NULL; -#define APPENDPATH() \ - do { \ - if (tmppath && access(tmppath, R_OK) != -1) { \ - if (hmagicpath == NULL) \ - hmagicpath = tmppath; \ - else { \ - if (asprintf(&hmagicp, "%s%c%s", hmagicpath, \ - PATHSEP, tmppath) >= 0) { \ - free(hmagicpath); \ - hmagicpath = hmagicp; \ - } \ - free(tmppath); \ - } \ - tmppath = NULL; \ - } \ - } while (/*CONSTCOND*/0) - if (default_magic) { free(default_magic); default_magic = NULL; } - /* First, try to get user-specific magic file */ - if ((home = getenv("LOCALAPPDATA")) == NULL) { - if ((home = getenv("USERPROFILE")) != NULL) - if (asprintf(&tmppath, - "%s/Local Settings/Application Data%s", home, - hmagic) < 0) - tmppath = NULL; - } else { - if (asprintf(&tmppath, "%s%s", home, hmagic) < 0) - tmppath = NULL; - } + /* First, try to get a magic file from user-application data */ + if ((home = getenv("LOCALAPPDATA")) != NULL) + _w32_append_path(&hmagicpath, "%s%s", home, hmagic); - APPENDPATH(); + /* Second, try to get a magic file from the user profile data */ + if ((home = getenv("USERPROFILE")) != NULL) + _w32_append_path(&hmagicpath, + "%s/Local Settings/Application Data%s", home, hmagic); - /* Second, try to get a magic file from Common Files */ - if ((home = getenv("COMMONPROGRAMFILES")) != NULL) { - if (asprintf(&tmppath, "%s%s", home, hmagic) >= 0) - APPENDPATH(); - } + /* Third, try to get a magic file from Common Files */ + if ((home = getenv("COMMONPROGRAMFILES")) != NULL) + _w32_append_path(&hmagicpath, "%s%s", home, hmagic); - /* Third, try to get magic file relative to dll location */ - 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); - if (strlen(dllpath) > 3 && - stricmp(&dllpath[strlen(dllpath) - 3], "bin") == 0) { - if (asprintf(&tmppath, - "%s/../share/misc/magic.mgc", dllpath) >= 0) - APPENDPATH(); - } else { - if (asprintf(&tmppath, - "%s/share/misc/magic.mgc", dllpath) >= 0) - APPENDPATH(); - else if (asprintf(&tmppath, - "%s/magic.mgc", dllpath) >= 0) - APPENDPATH(); - } - } + /* Fourth, try to get magic file relative to exe location */ + _w32_get_magic_relative_to(&hmagicpath, NULL); + + /* Fifth, try to get magic file relative to dll location */ + _w32_get_magic_relative_to(&hmagicpath, _w32_dll_instance); - /* Don't put MAGIC constant - it likely points to a file within MSys - tree */ + /* Avoid MAGIC constant - it likely points to a file within MSys tree */ default_magic = hmagicpath; return default_magic; #endif @@ -543,19 +581,19 @@ 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; + ms->indir_max = (uint16_t)*(const size_t *)val; return 0; case MAGIC_PARAM_NAME_MAX: - ms->name_max = *(const size_t *)val; + ms->name_max = (uint16_t)*(const size_t *)val; return 0; case MAGIC_PARAM_ELF_PHNUM_MAX: - ms->elf_phnum_max = *(const size_t *)val; + ms->elf_phnum_max = (uint16_t)*(const size_t *)val; return 0; case MAGIC_PARAM_ELF_SHNUM_MAX: - ms->elf_shnum_max = *(const size_t *)val; + ms->elf_shnum_max = (uint16_t)*(const size_t *)val; return 0; case MAGIC_PARAM_ELF_NOTES_MAX: - ms->elf_notes_max = *(const size_t *)val; + ms->elf_notes_max = (uint16_t)*(const size_t *)val; return 0; default: errno = EINVAL; diff --git a/contrib/file/src/magic.h b/contrib/file/src/magic.h index 721712f..0d64316 100644 --- a/contrib/file/src/magic.h +++ b/contrib/file/src/magic.h @@ -29,30 +29,35 @@ #include <sys/types.h> -#define MAGIC_NONE 0x000000 /* No flags */ -#define MAGIC_DEBUG 0x000001 /* Turn on debugging */ -#define MAGIC_SYMLINK 0x000002 /* Follow symlinks */ -#define MAGIC_COMPRESS 0x000004 /* Check inside compressed files */ -#define MAGIC_DEVICES 0x000008 /* Look at the contents of devices */ -#define MAGIC_MIME_TYPE 0x000010 /* Return the MIME type */ -#define MAGIC_CONTINUE 0x000020 /* Return all matches */ -#define MAGIC_CHECK 0x000040 /* Print warnings to stderr */ -#define MAGIC_PRESERVE_ATIME 0x000080 /* Restore access time on exit */ -#define MAGIC_RAW 0x000100 /* Don't translate unprintable chars */ -#define MAGIC_ERROR 0x000200 /* Handle ENOENT etc as real errors */ -#define MAGIC_MIME_ENCODING 0x000400 /* Return the MIME encoding */ +#define MAGIC_NONE 0x0000000 /* No flags */ +#define MAGIC_DEBUG 0x0000001 /* Turn on debugging */ +#define MAGIC_SYMLINK 0x0000002 /* Follow symlinks */ +#define MAGIC_COMPRESS 0x0000004 /* Check inside compressed files */ +#define MAGIC_DEVICES 0x0000008 /* Look at the contents of devices */ +#define MAGIC_MIME_TYPE 0x0000010 /* Return the MIME type */ +#define MAGIC_CONTINUE 0x0000020 /* Return all matches */ +#define MAGIC_CHECK 0x0000040 /* Print warnings to stderr */ +#define MAGIC_PRESERVE_ATIME 0x0000080 /* Restore access time on exit */ +#define MAGIC_RAW 0x0000100 /* Don't convert unprintable chars */ +#define MAGIC_ERROR 0x0000200 /* Handle ENOENT etc as real errors */ +#define MAGIC_MIME_ENCODING 0x0000400 /* Return the MIME encoding */ #define MAGIC_MIME (MAGIC_MIME_TYPE|MAGIC_MIME_ENCODING) -#define MAGIC_APPLE 0x000800 /* Return the Apple creator and type */ - -#define MAGIC_NO_CHECK_COMPRESS 0x001000 /* Don't check for compressed files */ -#define MAGIC_NO_CHECK_TAR 0x002000 /* Don't check for tar files */ -#define MAGIC_NO_CHECK_SOFT 0x004000 /* Don't check magic entries */ -#define MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */ -#define MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */ -#define MAGIC_NO_CHECK_TEXT 0x020000 /* Don't check for text files */ -#define MAGIC_NO_CHECK_CDF 0x040000 /* Don't check for cdf files */ -#define MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check tokens */ -#define MAGIC_NO_CHECK_ENCODING 0x200000 /* Don't check text encodings */ +#define MAGIC_APPLE 0x0000800 /* Return the Apple creator/type */ +#define MAGIC_EXTENSION 0x1000000 /* Return a /-separated list of + * extensions */ +#define MAGIC_COMPRESS_TRANSP 0x2000000 /* Check inside compressed files + * but not report compression */ +#define MAGIC_NODESC (MAGIC_EXTENSION|MAGIC_MIME|MAGIC_APPLE) + +#define MAGIC_NO_CHECK_COMPRESS 0x0001000 /* Don't check for compressed files */ +#define MAGIC_NO_CHECK_TAR 0x0002000 /* Don't check for tar files */ +#define MAGIC_NO_CHECK_SOFT 0x0004000 /* Don't check magic entries */ +#define MAGIC_NO_CHECK_APPTYPE 0x0008000 /* Don't check application type */ +#define MAGIC_NO_CHECK_ELF 0x0010000 /* Don't check for elf details */ +#define MAGIC_NO_CHECK_TEXT 0x0020000 /* Don't check for text files */ +#define MAGIC_NO_CHECK_CDF 0x0040000 /* Don't check for cdf files */ +#define MAGIC_NO_CHECK_TOKENS 0x0100000 /* Don't check tokens */ +#define MAGIC_NO_CHECK_ENCODING 0x0200000 /* Don't check text encodings */ /* No built-in tests; only consult the magic file */ #define MAGIC_NO_CHECK_BUILTIN ( \ @@ -75,7 +80,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 521 /* This implementation */ +#define MAGIC_VERSION 522 /* This implementation */ #ifdef __cplusplus diff --git a/contrib/file/src/magic.h.in b/contrib/file/src/magic.h.in index 0d4c5ce..500bdbd 100644 --- a/contrib/file/src/magic.h.in +++ b/contrib/file/src/magic.h.in @@ -29,30 +29,35 @@ #include <sys/types.h> -#define MAGIC_NONE 0x000000 /* No flags */ -#define MAGIC_DEBUG 0x000001 /* Turn on debugging */ -#define MAGIC_SYMLINK 0x000002 /* Follow symlinks */ -#define MAGIC_COMPRESS 0x000004 /* Check inside compressed files */ -#define MAGIC_DEVICES 0x000008 /* Look at the contents of devices */ -#define MAGIC_MIME_TYPE 0x000010 /* Return the MIME type */ -#define MAGIC_CONTINUE 0x000020 /* Return all matches */ -#define MAGIC_CHECK 0x000040 /* Print warnings to stderr */ -#define MAGIC_PRESERVE_ATIME 0x000080 /* Restore access time on exit */ -#define MAGIC_RAW 0x000100 /* Don't translate unprintable chars */ -#define MAGIC_ERROR 0x000200 /* Handle ENOENT etc as real errors */ -#define MAGIC_MIME_ENCODING 0x000400 /* Return the MIME encoding */ +#define MAGIC_NONE 0x0000000 /* No flags */ +#define MAGIC_DEBUG 0x0000001 /* Turn on debugging */ +#define MAGIC_SYMLINK 0x0000002 /* Follow symlinks */ +#define MAGIC_COMPRESS 0x0000004 /* Check inside compressed files */ +#define MAGIC_DEVICES 0x0000008 /* Look at the contents of devices */ +#define MAGIC_MIME_TYPE 0x0000010 /* Return the MIME type */ +#define MAGIC_CONTINUE 0x0000020 /* Return all matches */ +#define MAGIC_CHECK 0x0000040 /* Print warnings to stderr */ +#define MAGIC_PRESERVE_ATIME 0x0000080 /* Restore access time on exit */ +#define MAGIC_RAW 0x0000100 /* Don't convert unprintable chars */ +#define MAGIC_ERROR 0x0000200 /* Handle ENOENT etc as real errors */ +#define MAGIC_MIME_ENCODING 0x0000400 /* Return the MIME encoding */ #define MAGIC_MIME (MAGIC_MIME_TYPE|MAGIC_MIME_ENCODING) -#define MAGIC_APPLE 0x000800 /* Return the Apple creator and type */ - -#define MAGIC_NO_CHECK_COMPRESS 0x001000 /* Don't check for compressed files */ -#define MAGIC_NO_CHECK_TAR 0x002000 /* Don't check for tar files */ -#define MAGIC_NO_CHECK_SOFT 0x004000 /* Don't check magic entries */ -#define MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */ -#define MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */ -#define MAGIC_NO_CHECK_TEXT 0x020000 /* Don't check for text files */ -#define MAGIC_NO_CHECK_CDF 0x040000 /* Don't check for cdf files */ -#define MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check tokens */ -#define MAGIC_NO_CHECK_ENCODING 0x200000 /* Don't check text encodings */ +#define MAGIC_APPLE 0x0000800 /* Return the Apple creator/type */ +#define MAGIC_EXTENSION 0x1000000 /* Return a /-separated list of + * extensions */ +#define MAGIC_COMPRESS_TRANSP 0x2000000 /* Check inside compressed files + * but not report compression */ +#define MAGIC_NODESC (MAGIC_EXTENSION|MAGIC_MIME|MAGIC_APPLE) + +#define MAGIC_NO_CHECK_COMPRESS 0x0001000 /* Don't check for compressed files */ +#define MAGIC_NO_CHECK_TAR 0x0002000 /* Don't check for tar files */ +#define MAGIC_NO_CHECK_SOFT 0x0004000 /* Don't check magic entries */ +#define MAGIC_NO_CHECK_APPTYPE 0x0008000 /* Don't check application type */ +#define MAGIC_NO_CHECK_ELF 0x0010000 /* Don't check for elf details */ +#define MAGIC_NO_CHECK_TEXT 0x0020000 /* Don't check for text files */ +#define MAGIC_NO_CHECK_CDF 0x0040000 /* Don't check for cdf files */ +#define MAGIC_NO_CHECK_TOKENS 0x0100000 /* Don't check tokens */ +#define MAGIC_NO_CHECK_ENCODING 0x0200000 /* Don't check text encodings */ /* No built-in tests; only consult the magic file */ #define MAGIC_NO_CHECK_BUILTIN ( \ diff --git a/contrib/file/src/print.c b/contrib/file/src/print.c index fa81798..07ae8f6 100644 --- a/contrib/file/src/print.c +++ b/contrib/file/src/print.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: print.c,v 1.76 2013/02/26 18:25:00 christos Exp $") +FILE_RCSID("@(#)$File: print.c,v 1.79 2015/01/09 19:28:32 christos Exp $") #endif /* lint */ #include <string.h> @@ -164,6 +164,7 @@ file_mdump(struct magic *m) case FILE_MELDATE: (void)fprintf(stderr, "%s,", file_fmttime(m->value.l, 0, tbuf)); + break; case FILE_QDATE: case FILE_LEQDATE: case FILE_BEQDATE: @@ -231,40 +232,27 @@ protected const char * file_fmttime(uint64_t v, int flags, char *buf) { char *pp; - time_t t = (time_t)v; - struct tm *tm; + time_t t; + struct tm *tm, tmz; if (flags & FILE_T_WINDOWS) { struct timespec ts; - cdf_timestamp_to_timespec(&ts, t); + cdf_timestamp_to_timespec(&ts, v); t = ts.tv_sec; + } else { + // XXX: perhaps detect and print something if overflow + // on 32 bit time_t? + t = (time_t)v; } if (flags & FILE_T_LOCAL) { - pp = ctime_r(&t, buf); + tm = localtime_r(&t, &tmz); } else { -#ifndef HAVE_DAYLIGHT - private int daylight = 0; -#ifdef HAVE_TM_ISDST - private time_t now = (time_t)0; - - if (now == (time_t)0) { - struct tm *tm1; - (void)time(&now); - tm1 = localtime(&now); - if (tm1 == NULL) - goto out; - daylight = tm1->tm_isdst; - } -#endif /* HAVE_TM_ISDST */ -#endif /* HAVE_DAYLIGHT */ - if (daylight) - t += 3600; - tm = gmtime(&t); - if (tm == NULL) - goto out; - pp = asctime_r(tm, buf); + tm = gmtime_r(&t, &tmz); } + if (tm == NULL) + goto out; + pp = asctime_r(tm, buf); if (pp == NULL) goto out; diff --git a/contrib/file/src/readcdf.c b/contrib/file/src/readcdf.c index 635a926..99d8ec0 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.49 2014/12/04 15:56:46 christos Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.53 2015/04/09 20:01:41 christos Exp $") #endif #include <assert.h> @@ -39,6 +39,10 @@ FILE_RCSID("@(#)$File: readcdf.c,v 1.49 2014/12/04 15:56:46 christos Exp $") #include "cdf.h" #include "magic.h" +#ifndef __arraycount +#define __arraycount(a) (sizeof(a) / sizeof(a[0])) +#endif + #define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0) static const struct nv { @@ -96,6 +100,10 @@ cdf_clsid_to_mime(const uint64_t clsid[2], const struct cv *cv) if (clsid[0] == cv[i].clsid[0] && clsid[1] == cv[i].clsid[1]) return cv[i].mime; } +#ifdef CDF_DEBUG + fprintf(stderr, "unknown mime %" PRIx64 ", %" PRIx64 "\n", clsid[0], + clsid[1]); +#endif return NULL; } @@ -117,6 +125,9 @@ cdf_app_to_mime(const char *vbuf, const struct nv *nv) rv = nv[i].mime; break; } +#ifdef CDF_DEBUG + fprintf(stderr, "unknown app %s\n", vbuf); +#endif #ifdef USE_C_LOCALE (void)uselocale(old_lc_ctype); freelocale(c_lc_ctype); @@ -343,6 +354,90 @@ format_clsid(char *buf, size_t len, const uint64_t uuid[2]) { } #endif +private int +cdf_file_catalog_info(struct magic_set *ms, const cdf_info_t *info, + const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat, + const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn) +{ + int i; + + if ((i = cdf_read_user_stream(info, h, sat, ssat, sst, + dir, "Catalog", scn)) == -1) + return i; +#ifdef CDF_DEBUG + cdf_dump_catalog(&h, &scn); +#endif + if ((i = cdf_file_catalog(ms, h, scn)) == -1) + return -1; + return i; +} + +private struct sinfo { + const char *name; + const char *mime; + const char *sections[5]; + const int types[5]; +} sectioninfo[] = { + { "Encrypted", "encrypted", + { + "EncryptedPackage", NULL, NULL, NULL, NULL, + }, + { + CDF_DIR_TYPE_USER_STREAM, 0, 0, 0, 0, + + }, + }, + { "QuickBooks", "quickbooks", + { +#if 0 + "TaxForms", "PDFTaxForms", "modulesInBackup", +#endif + "mfbu_header", NULL, NULL, NULL, NULL, + }, + { +#if 0 + CDF_DIR_TYPE_USER_STORAGE, + CDF_DIR_TYPE_USER_STORAGE, + CDF_DIR_TYPE_USER_STREAM, +#endif + CDF_DIR_TYPE_USER_STREAM, + 0, 0, 0, 0 + }, + }, +}; + +private int +cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir) +{ + size_t sd, j; + + for (sd = 0; sd < __arraycount(sectioninfo); sd++) { + const struct sinfo *si = §ioninfo[sd]; + for (j = 0; si->sections[j]; j++) { + if (cdf_find_stream(dir, si->sections[j], si->types[j]) + <= 0) { +#ifdef CDF_DEBUG + fprintf(stderr, "Can't read %s\n", + si->sections[j]); +#endif + break; + } + } + if (si->sections[j] != NULL) + continue; + if (NOTMIME(ms)) { + if (file_printf(ms, "CDFV2 %s", si->name) == -1) + return -1; + } else { + if (file_printf(ms, "application/CDFV2-%s", + si->mime) == -1) + return -1; + } + return 1; + } + return -1; +} + protected int file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, size_t nbytes) @@ -354,13 +449,12 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, cdf_dir_t dir; int i; const char *expn = ""; - const char *corrupt = "corrupt: "; const cdf_directory_t *root_storage; info.i_fd = fd; info.i_buf = buf; info.i_len = nbytes; - if (ms->flags & MAGIC_APPLE) + if (ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) return 0; if (cdf_read_header(&info, &h) == -1) return 0; @@ -435,30 +529,21 @@ 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) { - 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 { + if (errno != ESRCH) { expn = "Cannot read summary info"; - } - goto out4; - } + goto out4; + } + i = cdf_file_catalog_info(ms, &info, &h, &sat, &ssat, &sst, + &dir, &scn); + if (i > 0) + goto out4; + i = cdf_file_dir_info(ms, &dir); + if (i < 0) + expn = "Cannot read section info"; + goto out4; + } + + #ifdef CDF_DEBUG cdf_dump_summary_info(&h, &scn); #endif @@ -509,11 +594,10 @@ out0: "Composite Document File V2 Document") == -1) return -1; if (*expn) - if (file_printf(ms, ", %s%s", corrupt, expn) == -1) + if (file_printf(ms, ", %s", expn) == -1) return -1; } else { - if (file_printf(ms, "application/CDFV2-%s", - *corrupt ? "corrupt" : "encrypted") == -1) + if (file_printf(ms, "application/CDFV2-unknown") == -1) return -1; } i = 1; diff --git a/contrib/file/src/readelf.c b/contrib/file/src/readelf.c index d159620..55009e8 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.117 2014/12/16 23:29:42 christos Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.119 2015/04/09 20:01:41 christos Exp $") #endif #ifdef BUILTIN_ELF @@ -482,6 +482,7 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v) } private int +/*ARGSUSED*/ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz, size_t noff, size_t doff, int *flags) @@ -622,7 +623,7 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, return 1; for (i = 0; i < __arraycount(pax); i++) { - if (((1 << i) & desc) == 0) + if (((1 << (int)i) & desc) == 0) continue; if (file_printf(ms, "%s%s", did++ ? "," : "", pax[i]) == -1) @@ -1008,7 +1009,8 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, } /* Read offset of name section to be able to read section names later */ - if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) < (ssize_t)xsh_sizeof) { + if (pread(fd, xsh_addr, xsh_sizeof, CAST(off_t, (off + size * strtab))) + < (ssize_t)xsh_sizeof) { file_badread(ms); return -1; } @@ -1351,7 +1353,7 @@ file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf, Elf64_Ehdr elf64hdr; uint16_t type, phnum, shnum, notecount; - if (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) + if (ms->flags & (MAGIC_MIME|MAGIC_APPLE|MAGIC_EXTENSION)) return 0; /* * ELF executables have multiple section headers in arbitrary diff --git a/contrib/file/src/softmagic.c b/contrib/file/src/softmagic.c index 5e277e3..15a092f 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.206 2015/01/01 17:07:34 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.216 2015/06/09 22:17:52 christos Exp $") #endif /* lint */ #include "magic.h" @@ -147,7 +147,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, unsigned int cont_level = 0; int returnvalv = 0, e; /* if a match is found it is set to 1*/ int firstline = 1; /* a flag to print X\n X\n- X */ - int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0; + int print = (ms->flags & MAGIC_NODESC) == 0; if (returnval == NULL) returnval = &returnvalv; @@ -361,6 +361,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) { return *returnval; /* don't keep searching */ } + cont_level = 0; } return *returnval; /* This is hit if -k is set or there is no match */ } @@ -518,7 +519,7 @@ mprint(struct magic_set *ms, struct magic *m) t = ms->offset + strlen(str); if (*m->value.s == '\0') - str[strcspn(str, "\n")] = '\0'; + str[strcspn(str, "\r\n")] = '\0'; if (m->str_flags & STRING_TRIM) { char *last; @@ -547,7 +548,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_LEDATE: case FILE_MEDATE: if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->l + m->num_mask, FILE_T_LOCAL, tbuf)) == -1) + file_fmttime(p->l, 0, tbuf)) == -1) return -1; t = ms->offset + sizeof(uint32_t); break; @@ -557,7 +558,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_LELDATE: case FILE_MELDATE: if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->l + m->num_mask, 0, tbuf)) == -1) + file_fmttime(p->l, FILE_T_LOCAL, tbuf)) == -1) return -1; t = ms->offset + sizeof(uint32_t); break; @@ -566,7 +567,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEQDATE: case FILE_LEQDATE: if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->q + m->num_mask, FILE_T_LOCAL, tbuf)) == -1) + file_fmttime(p->q, 0, tbuf)) == -1) return -1; t = ms->offset + sizeof(uint64_t); break; @@ -575,7 +576,7 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEQLDATE: case FILE_LEQLDATE: if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->q + m->num_mask, 0, tbuf)) == -1) + file_fmttime(p->q, FILE_T_LOCAL, tbuf)) == -1) return -1; t = ms->offset + sizeof(uint64_t); break; @@ -584,14 +585,14 @@ mprint(struct magic_set *ms, struct magic *m) case FILE_BEQWDATE: case FILE_LEQWDATE: if (file_printf(ms, F(ms, m, "%s"), - file_fmttime(p->q + m->num_mask, FILE_T_WINDOWS, tbuf)) == -1) + file_fmttime(p->q, FILE_T_WINDOWS, tbuf)) == -1) return -1; t = ms->offset + sizeof(uint64_t); break; - case FILE_FLOAT: - case FILE_BEFLOAT: - case FILE_LEFLOAT: + case FILE_FLOAT: + case FILE_BEFLOAT: + case FILE_LEFLOAT: vf = p->f; switch (check_fmt(ms, m)) { case -1: @@ -609,9 +610,9 @@ mprint(struct magic_set *ms, struct magic *m) t = ms->offset + sizeof(float); break; - case FILE_DOUBLE: - case FILE_BEDOUBLE: - case FILE_LEDOUBLE: + case FILE_DOUBLE: + case FILE_BEDOUBLE: + case FILE_LEDOUBLE: vd = p->d; switch (check_fmt(ms, m)) { case -1: @@ -629,6 +630,7 @@ mprint(struct magic_set *ms, struct magic *m) t = ms->offset + sizeof(double); break; + case FILE_SEARCH: case FILE_REGEX: { char *cp; int rval; @@ -652,16 +654,6 @@ mprint(struct magic_set *ms, struct magic *m) break; } - case FILE_SEARCH: - if (file_printf(ms, F(ms, m, "%s"), - file_printable(sbuf, sizeof(sbuf), m->value.s)) == -1) - return -1; - if ((m->str_flags & REGEX_OFFSET_START)) - t = ms->search.offset; - else - t = ms->search.offset + m->vallen; - break; - case FILE_DEFAULT: case FILE_CLEAR: if (file_printf(ms, "%s", m->desc) == -1) @@ -716,7 +708,7 @@ moffset(struct magic_set *ms, struct magic *m) uint32_t t; if (*m->value.s == '\0') - p->s[strcspn(p->s, "\n")] = '\0'; + p->s[strcspn(p->s, "\r\n")] = '\0'; t = CAST(uint32_t, (ms->offset + strlen(p->s))); if (m->type == FILE_PSTRING) t += (uint32_t)file_pstring_length_size(m); @@ -978,8 +970,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) case FILE_BELDATE: p->l = (int32_t) ((p->hl[0]<<24)|(p->hl[1]<<16)|(p->hl[2]<<8)|(p->hl[3])); - if (type == FILE_BELONG) - cvt_32(p, m); + cvt_32(p, m); return 1; case FILE_BEQUAD: case FILE_BEQDATE: @@ -990,8 +981,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) ((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)| ((uint64_t)p->hq[4]<<24)|((uint64_t)p->hq[5]<<16)| ((uint64_t)p->hq[6]<<8)|((uint64_t)p->hq[7])); - if (type == FILE_BEQUAD) - cvt_64(p, m); + cvt_64(p, m); return 1; case FILE_LESHORT: p->h = (short)((p->hs[1]<<8)|(p->hs[0])); @@ -1002,8 +992,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) case FILE_LELDATE: p->l = (int32_t) ((p->hl[3]<<24)|(p->hl[2]<<16)|(p->hl[1]<<8)|(p->hl[0])); - if (type == FILE_LELONG) - cvt_32(p, m); + cvt_32(p, m); return 1; case FILE_LEQUAD: case FILE_LEQDATE: @@ -1014,16 +1003,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip) ((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)| ((uint64_t)p->hq[3]<<24)|((uint64_t)p->hq[2]<<16)| ((uint64_t)p->hq[1]<<8)|((uint64_t)p->hq[0])); - if (type == FILE_LEQUAD) - cvt_64(p, m); + cvt_64(p, m); return 1; case FILE_MELONG: case FILE_MEDATE: case FILE_MELDATE: p->l = (int32_t) ((p->hl[1]<<24)|(p->hl[0]<<16)|(p->hl[3]<<8)|(p->hl[2])); - if (type == FILE_MELONG) - cvt_32(p, m); + cvt_32(p, m); return 1; case FILE_FLOAT: cvt_float(p, m); @@ -1116,13 +1103,11 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, bytecnt = m->str_range; } - if (bytecnt == 0) - bytecnt = 8192; - if (bytecnt > nbytes) - bytecnt = nbytes; + if (bytecnt == 0 || bytecnt > nbytes - offset) + bytecnt = nbytes - offset; buf = RCAST(const char *, s) + offset; - end = last = RCAST(const char *, s) + bytecnt; + end = last = RCAST(const char *, s) + bytecnt + offset; /* mget() guarantees buf <= last */ for (lines = linecnt, b = buf; lines && b < end && ((b = CAST(const char *, @@ -1582,7 +1567,9 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, offset = ((((offset >> 0) & 0x7f) << 0) | (((offset >> 8) & 0x7f) << 7) | (((offset >> 16) & 0x7f) << 14) | - (((offset >> 24) & 0x7f) << 21)) + 10; + (((offset >> 24) & 0x7f) << 21)); + if ((ms->flags & MAGIC_DEBUG) != 0) + fprintf(stderr, "id3 offs=%u\n", offset); break; default: break; @@ -1666,7 +1653,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, case FILE_INDIRECT: if (m->str_flags & INDIRECT_RELATIVE) - offset += o; + offset += CAST(uint32_t, o); if (offset == 0) return 0; @@ -1687,7 +1674,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return -1; if (rv == 1) { - if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 && + if ((ms->flags & MAGIC_NODESC) == 0 && file_printf(ms, F(ms, m, "%u"), offset) == -1) { free(rbuf); return -1; @@ -1721,9 +1708,11 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, printed_something, need_separator, returnval); if (rv != 1) *need_separator = oneed_separator; - return rv; + return 1; case FILE_NAME: + if (ms->flags & MAGIC_NODESC) + return 1; if (file_printf(ms, "%s", m->desc) == -1) return -1; return 1; @@ -1965,6 +1954,7 @@ magiccheck(struct magic_set *ms, struct magic *m) m->str_flags); if (v == 0) { /* found match */ ms->search.offset += idx; + ms->search.rm_len = m->str_range - idx; break; } } @@ -2148,6 +2138,11 @@ handle_annotation(struct magic_set *ms, struct magic *m) return -1; return 1; } + if (ms->flags & MAGIC_EXTENSION) { + if (file_printf(ms, "%s", m->ext) == -1) + return -1; + return 1; + } if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) { if (file_printf(ms, "%s", m->mimetype) == -1) return -1; @@ -2159,7 +2154,7 @@ handle_annotation(struct magic_set *ms, struct magic *m) private int print_sep(struct magic_set *ms, int firstline) { - if (ms->flags & MAGIC_MIME) + if (ms->flags & MAGIC_NODESC) return 0; if (firstline) return 0; |