diff options
Diffstat (limited to 'contrib/file/src')
-rw-r--r-- | contrib/file/src/apprentice.c | 37 | ||||
-rw-r--r-- | contrib/file/src/ascmagic.c | 8 | ||||
-rw-r--r-- | contrib/file/src/cdf.c | 32 | ||||
-rw-r--r-- | contrib/file/src/cdf.h | 6 | ||||
-rw-r--r-- | contrib/file/src/compress.c | 14 | ||||
-rw-r--r-- | contrib/file/src/der.c | 14 | ||||
-rw-r--r-- | contrib/file/src/file.c | 6 | ||||
-rw-r--r-- | contrib/file/src/file.h | 10 | ||||
-rw-r--r-- | contrib/file/src/funcs.c | 5 | ||||
-rw-r--r-- | contrib/file/src/magic.c | 4 | ||||
-rw-r--r-- | contrib/file/src/readcdf.c | 183 | ||||
-rw-r--r-- | contrib/file/src/readelf.c | 22 | ||||
-rw-r--r-- | contrib/file/src/softmagic.c | 353 |
13 files changed, 301 insertions, 393 deletions
diff --git a/contrib/file/src/apprentice.c b/contrib/file/src/apprentice.c index e395854..f2622c0 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.249 2016/05/17 21:43:07 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.255 2016/10/24 18:02:17 christos Exp $") #endif /* lint */ #include "magic.h" @@ -408,11 +408,11 @@ add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx) { struct mlist *ml; - mlp->map = idx == 0 ? map : NULL; + mlp->map = NULL; if ((ml = CAST(struct mlist *, malloc(sizeof(*ml)))) == NULL) return -1; - ml->map = NULL; + ml->map = idx == 0 ? map : NULL; ml->magic = map->magic[idx]; ml->nmagic = map->nmagic[idx]; @@ -451,6 +451,8 @@ apprentice_1(struct magic_set *ms, const char *fn, int action) #ifndef COMPILE_ONLY map = apprentice_map(ms, fn); + if (map == (struct magic_map *)-1) + return -1; if (map == NULL) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "using regular magic file `%s'", fn); @@ -462,7 +464,7 @@ 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)); - goto fail; + return -1; } } @@ -476,12 +478,6 @@ apprentice_1(struct magic_set *ms, const char *fn, int action) } } 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 */ @@ -554,7 +550,7 @@ apprentice_unmap(struct magic_map *map) case MAP_TYPE_MALLOC: for (i = 0; i < MAGIC_SETS; i++) { if ((char *)map->magic[i] >= (char *)map->p && - (char *)map->magic[i] < (char *)map->p + map->len) + (char *)map->magic[i] <= (char *)map->p + map->len) continue; free(map->magic[i]); } @@ -594,7 +590,7 @@ mlist_free(struct mlist *mlist) ml = mlist->next; for (ml = mlist->next; (next = ml->next) != NULL; ml = next) { if (ml->map) - apprentice_unmap(ml->map); + apprentice_unmap(CAST(struct magic_map *, ml->map)); free(ml); if (ml == mlist) break; @@ -1879,10 +1875,13 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, if (m->flag & INDIR) { m->in_type = FILE_LONG; m->in_offset = 0; + m->in_op = 0; /* - * read [.lbs][+-]nnnnn) + * read [.,lbs][+-]nnnnn) */ - if (*l == '.') { + if (*l == '.' || *l == ',') { + if (*l == ',') + m->in_op |= FILE_OPSIGNED; l++; switch (*l) { case 'l': @@ -1934,7 +1933,6 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line, l++; } - m->in_op = 0; if (*l == '~') { m->in_op |= FILE_OPINVERSE; l++; @@ -2930,6 +2928,7 @@ apprentice_map(struct magic_set *ms, const char *fn) struct stat st; char *dbname = NULL; struct magic_map *map; + struct magic_map *rv = NULL; fd = -1; if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) { @@ -2978,8 +2977,10 @@ apprentice_map(struct magic_set *ms, const char *fn) (void)close(fd); fd = -1; - if (check_buffer(ms, map, dbname) != 0) + if (check_buffer(ms, map, dbname) != 0) { + rv = (struct magic_map *)-1; goto error; + } #ifdef QUICK if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) { file_error(ms, errno, "cannot mprotect `%s'", dbname); @@ -2995,7 +2996,7 @@ error: (void)close(fd); apprentice_unmap(map); free(dbname); - return NULL; + return rv; } private int @@ -3151,7 +3152,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip) return NULL; /* Compatibility with old code that looked in .mime */ - if (strstr(p, ".mime") != NULL) + if (strstr(fn, ".mime") != NULL) ms->flags &= MAGIC_MIME_TYPE; return buf; } diff --git a/contrib/file/src/ascmagic.c b/contrib/file/src/ascmagic.c index baa95ab..85a973e 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.95 2016/05/03 16:10:37 christos Exp $") +FILE_RCSID("@(#)$File: ascmagic.c,v 1.97 2016/06/27 20:56:25 christos Exp $") #endif /* lint */ #include "magic.h" @@ -144,8 +144,10 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, (size_t)(utf8_end - utf8_buf), NULL, NULL, TEXTTEST, text)) == 0) rv = -1; - if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))) - return rv == -1 ? 0 : 1; + if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))) { + rv = rv == -1 ? 0 : 1; + goto done; + } } if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION))) return 0; diff --git a/contrib/file/src/cdf.c b/contrib/file/src/cdf.c index 4ec65b4..d38e793 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.82 2016/06/01 22:25:25 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.85 2016/10/24 18:02:17 christos Exp $") #endif #include <assert.h> @@ -266,7 +266,7 @@ cdf_unpack_dir(cdf_directory_t *d, char *buf) CDF_UNPACK(d->d_unused0); } -static int +int cdf_zero_stream(cdf_stream_t *scn) { scn->sst_len = 0; @@ -731,22 +731,25 @@ cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, break; /* If the it is not there, just fake it; some docs don't have it */ - if (i == dir->dir_len) + if (i == dir->dir_len) { + DPRINTF(("Cannot find root storage dir\n")); goto out; + } d = &dir->dir_tab[i]; *root = d; /* If the it is not there, just fake it; some docs don't have it */ - if (d->d_stream_first_sector < 0) + if (d->d_stream_first_sector < 0) { + DPRINTF(("No first secror in dir\n")); goto out; + } return cdf_read_long_sector_chain(info, h, sat, d->d_stream_first_sector, d->d_size, scn); out: scn->sst_tab = NULL; (void)cdf_zero_stream(scn); - errno = EFTYPE; - return -1; + return 0; } static int @@ -759,6 +762,15 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l) } int +cdf_read_doc_summary_info(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) +{ + return cdf_read_user_stream(info, h, sat, ssat, sst, dir, + "\05DocumentSummaryInformation", scn); +} + +int cdf_read_summary_info(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) @@ -1098,7 +1110,7 @@ cdf_unpack_catalog(const cdf_header_t *h, const cdf_stream_t *sst, cep->ce_namlen = rlen; np = CAST(const uint16_t *, CAST(const void *, (b + 16))); - if (CAST(const char *, np + cep->ce_namlen) > eb) { + if (RCAST(const char *, np + cep->ce_namlen) > eb) { cep->ce_namlen = 0; break; } @@ -1275,7 +1287,7 @@ cdf_dump(const void *v, size_t len) } void -cdf_dump_stream(const cdf_header_t *h, const cdf_stream_t *sst) +cdf_dump_stream(const cdf_stream_t *sst) { size_t ss = sst->sst_ss; cdf_dump(sst->sst_tab, ss * sst->sst_len); @@ -1331,7 +1343,7 @@ cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h, name, d->d_stream_first_sector, d->d_size); break; } - cdf_dump_stream(h, &scn); + cdf_dump_stream(&scn); free(scn.sst_tab); break; default: @@ -1507,7 +1519,7 @@ main(int argc, char *argv[]) == -1) err(1, "Cannot read short stream"); #ifdef CDF_DEBUG - cdf_dump_stream(&h, &sst); + cdf_dump_stream(&sst); #endif #ifdef CDF_DEBUG diff --git a/contrib/file/src/cdf.h b/contrib/file/src/cdf.h index 853a719..0b345ab 100644 --- a/contrib/file/src/cdf.h +++ b/contrib/file/src/cdf.h @@ -316,6 +316,10 @@ 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 *); int cdf_find_stream(const cdf_dir_t *, const char *, int); +int cdf_zero_stream(cdf_stream_t *); +int cdf_read_doc_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_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 *); @@ -336,7 +340,7 @@ char *cdf_u16tos8(char *, size_t, const uint16_t *); void cdf_dump_header(const cdf_header_t *); void cdf_dump_sat(const char *, const cdf_sat_t *, size_t); void cdf_dump(const void *, size_t); -void cdf_dump_stream(const cdf_header_t *, const cdf_stream_t *); +void cdf_dump_stream(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 *); void cdf_dump_property_info(const cdf_property_info_t *, size_t); diff --git a/contrib/file/src/compress.c b/contrib/file/src/compress.c index 1988fe7..95f0955 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.97 2016/05/13 23:02:28 christos Exp $") +FILE_RCSID("@(#)$File: compress.c,v 1.100 2016/10/24 18:02:17 christos Exp $") #endif #include "magic.h" @@ -132,6 +132,9 @@ static const char *lrzip_args[] = { static const char *lz4_args[] = { "lz4", "-cd", NULL }; +static const char *zstd_args[] = { + "zstd", "-cd", NULL +}; private const struct { const void *magic; @@ -154,8 +157,9 @@ private const struct { { "\3757zXZ\0", 6, xz_args }, /* XZ Utils */ { "LRZI", 4, lrzip_args }, /* LRZIP */ { "\004\"M\030",4, lz4_args }, /* LZ4 */ + { "\x28\xB5\x2F\xFD", 4, zstd_args }, /* zstd */ #ifdef ZLIBSUPPORT - { zlibcmp, 0, zlib_args }, /* zlib */ + { RCAST(const void *, zlibcmp), 0, zlib_args }, /* zlib */ #endif }; @@ -204,7 +208,7 @@ file_zmagic(struct magic_set *ms, int fd, const char *name, continue; #ifdef ZLIBSUPPORT if (compr[i].maglen == 0) - zm = (CAST(int (*)(const unsigned char *), + zm = (RCAST(int (*)(const unsigned char *), CCAST(void *, compr[i].magic)))(buf); else #endif @@ -362,7 +366,7 @@ nocheck: return rn - n; default: n -= rv; - buf = ((char *)buf) + rv; + buf = CAST(char *, CCAST(void *, buf)) + rv; break; } while (n > 0); @@ -517,7 +521,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch, return OKDATA; err: - strlcpy((char *)*newch, z.msg, bytes_max); + strlcpy((char *)*newch, z.msg ? z.msg : zError(rc), bytes_max); *n = strlen((char *)*newch); return ERRDATA; } diff --git a/contrib/file/src/der.c b/contrib/file/src/der.c index f36606b..8ae638f 100644 --- a/contrib/file/src/der.c +++ b/contrib/file/src/der.c @@ -35,13 +35,11 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: der.c,v 1.7 2016/06/01 22:01:15 christos Exp $") +FILE_RCSID("@(#)$File: der.c,v 1.10 2016/10/24 18:02:17 christos Exp $") #endif #endif #include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> #include <stdio.h> #include <fcntl.h> @@ -53,6 +51,8 @@ FILE_RCSID("@(#)$File: der.c,v 1.7 2016/06/01 22:01:15 christos Exp $") #include "magic.h" #include "der.h" #else +#include <sys/mman.h> +#include <sys/stat.h> #include <err.h> #endif @@ -181,6 +181,8 @@ getlength(const uint8_t *c, size_t *p, size_t l) for (i = 0; i < digits; i++) len = (len << 8) | c[(*p)++]; + if (*p + len >= l) + return DER_BAD; return len; } @@ -198,7 +200,7 @@ der_tag(char *buf, size_t len, uint32_t tag) static int der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len) { - const uint8_t *d = q; + const uint8_t *d = CAST(const uint8_t *, q); switch (tag) { case DER_TAG_PRINTABLE_STRING: case DER_TAG_UTF8_STRING: @@ -220,7 +222,7 @@ der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len) int32_t der_offs(struct magic_set *ms, struct magic *m, size_t nbytes) { - const uint8_t *b = CAST(const void *, ms->search.s); + const uint8_t *b = RCAST(const uint8_t *, ms->search.s); size_t offs = 0, len = ms->search.s_len ? ms->search.s_len : nbytes; if (gettag(b, &offs, len) == DER_BAD) @@ -251,7 +253,7 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes) int der_cmp(struct magic_set *ms, struct magic *m) { - const uint8_t *b = CAST(const void *, ms->search.s); + const uint8_t *b = RCAST(const uint8_t *, ms->search.s); const char *s = m->value.s; size_t offs = 0, len = ms->search.s_len; uint32_t tag, tlen; diff --git a/contrib/file/src/file.c b/contrib/file/src/file.c index 9a8606d..fad3160 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.171 2016/05/17 15:52:45 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.172 2016/10/24 15:21:07 christos Exp $") #endif /* lint */ #include "magic.h" @@ -431,6 +431,8 @@ private struct magic_set * load(const char *magicfile, int flags) { struct magic_set *magic = magic_open(flags); + const char *e; + if (magic == NULL) { (void)fprintf(stderr, "%s: %s\n", progname, strerror(errno)); return NULL; @@ -441,6 +443,8 @@ load(const char *magicfile, int flags) magic_close(magic); return NULL; } + if ((e = magic_error(magic)) != NULL) + (void)fprintf(stderr, "%s: Warning: %s\n", progname, e); return magic; } diff --git a/contrib/file/src/file.h b/contrib/file/src/file.h index f22fcd9..180efd3 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.178 2016/03/31 17:51:12 christos Exp $ + * @(#)$File: file.h,v 1.180 2016/07/20 11:27:08 christos Exp $ */ #ifndef __file_h__ @@ -134,11 +134,11 @@ or directory */ #define MAXDESC 64 /* max len of text description/MIME type */ #define MAXMIME 80 /* max len of text MIME type */ -#define MAXstring 64 /* max len of "string" types */ +#define MAXstring 96 /* max len of "string" types */ #define MAGICNO 0xF11E041C -#define VERSIONNO 13 -#define FILE_MAGICSIZE 312 +#define VERSIONNO 14 +#define FILE_MAGICSIZE 344 #define FILE_LOAD 0 #define FILE_CHECK 1 @@ -275,7 +275,7 @@ struct magic { #define FILE_OPS_MASK 0x07 /* mask for above ops */ #define FILE_UNUSED_1 0x08 #define FILE_UNUSED_2 0x10 -#define FILE_UNUSED_3 0x20 +#define FILE_OPSIGNED 0x20 #define FILE_OPINVERSE 0x40 #define FILE_OPINDIRECT 0x80 diff --git a/contrib/file/src/funcs.c b/contrib/file/src/funcs.c index df8dbae..c8918a4 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.89 2016/03/21 15:56:53 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.90 2016/10/19 20:51:17 christos Exp $") #endif /* lint */ #include "magic.h" @@ -250,7 +250,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u } /* try soft magic tests */ - if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) + if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) { m = file_softmagic(ms, ubuf, nb, NULL, NULL, BINTEST, looks_text); if ((ms->flags & MAGIC_DEBUG) != 0) @@ -277,6 +277,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u if (checkdone(ms, &rv)) goto done; } + } /* try text properties */ if ((ms->flags & MAGIC_NO_CHECK_TEXT) == 0) { diff --git a/contrib/file/src/magic.c b/contrib/file/src/magic.c index a256c42..b61ad29 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.99 2016/05/03 16:09:38 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.100 2016/07/18 11:43:05 christos Exp $") #endif /* lint */ #include "magic.h" @@ -492,7 +492,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) if (r < PIPE_BUF) break; } - if (nbytes == 0) { + if (nbytes == 0 && inname) { /* We can not read it, but we were able to stat it. */ if (unreadable_info(ms, sb.st_mode, inname) == -1) goto done; diff --git a/contrib/file/src/readcdf.c b/contrib/file/src/readcdf.c index db8d3d3..20e631d 100644 --- a/contrib/file/src/readcdf.c +++ b/contrib/file/src/readcdf.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008 Christos Zoulas + * Copyright (c) 2008, 2016 Christos Zoulas * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readcdf.c,v 1.57 2016/05/03 16:08:49 christos Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.63 2016/10/18 22:25:42 christos Exp $") #endif #include <assert.h> @@ -373,13 +373,61 @@ cdf_file_catalog_info(struct magic_set *ms, const cdf_info_t *info, dir, "Catalog", scn)) == -1) return i; #ifdef CDF_DEBUG - cdf_dump_catalog(&h, scn); + cdf_dump_catalog(h, scn); #endif if ((i = cdf_file_catalog(ms, h, scn)) == -1) return -1; return i; } +private int +cdf_check_summary_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, + const cdf_directory_t *root_storage, const char **expn) +{ + int i; + const char *str = NULL; + cdf_directory_t *d; + char name[__arraycount(d->d_name)]; + size_t j, k; + +#ifdef CDF_DEBUG + cdf_dump_summary_info(h, scn); +#endif + if ((i = cdf_file_summary_info(ms, h, scn, root_storage)) < 0) { + *expn = "Can't expand summary_info"; + return i; + } + if (i == 1) + return i; + for (j = 0; str == NULL && j < dir->dir_len; j++) { + d = &dir->dir_tab[j]; + for (k = 0; k < sizeof(name); k++) + name[k] = (char)cdf_tole2(d->d_name[k]); + str = cdf_app_to_mime(name, + NOTMIME(ms) ? name2desc : name2mime); + } + if (NOTMIME(ms)) { + if (str != NULL) { + if (file_printf(ms, "%s", str) == -1) + return -1; + i = 1; + } + } else { + if (str == NULL) + str = "vnd.ms-office"; + if (file_printf(ms, "application/%s", str) == -1) + return -1; + i = 1; + } + if (i <= 0) { + i = cdf_file_catalog_info(ms, info, h, sat, ssat, sst, + dir, scn); + } + return i; +} + private struct sinfo { const char *name; const char *mime; @@ -388,10 +436,13 @@ private struct sinfo { } sectioninfo[] = { { "Encrypted", "encrypted", { - "EncryptedPackage", NULL, NULL, NULL, NULL, + "EncryptedPackage", "EncryptedSummary", + NULL, NULL, NULL, }, { - CDF_DIR_TYPE_USER_STREAM, 0, 0, 0, 0, + CDF_DIR_TYPE_USER_STREAM, + CDF_DIR_TYPE_USER_STREAM, + 0, 0, 0, }, }, @@ -412,6 +463,46 @@ private struct sinfo { 0, 0, 0, 0 }, }, + { "Microsoft Excel", "vnd.ms-excel", + { + "Book", "Workbook", NULL, NULL, NULL, + }, + { + CDF_DIR_TYPE_USER_STREAM, + CDF_DIR_TYPE_USER_STREAM, + 0, 0, 0, + }, + }, + { "Microsoft Word", "msword", + { + "WordDocument", NULL, NULL, NULL, NULL, + }, + { + CDF_DIR_TYPE_USER_STREAM, + 0, 0, 0, 0, + }, + }, + { "Microsoft PowerPoint", "vnd.ms-powerpoint", + { + "PowerPoint", NULL, NULL, NULL, NULL, + }, + { + CDF_DIR_TYPE_USER_STREAM, + 0, 0, 0, 0, + }, + }, + { "Microsoft Outlook Message", "vnd.ms-outlook", + { + "__properties_version1.0", + "__recip_version1.0_#00000000", + NULL, NULL, NULL, + }, + { + CDF_DIR_TYPE_USER_STREAM, + CDF_DIR_TYPE_USER_STORAGE, + 0, 0, 0, + }, + }, }; private int @@ -423,22 +514,19 @@ cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir) 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) { + > 0) + break; #ifdef CDF_DEBUG - fprintf(stderr, "Can't read %s\n", - si->sections[j]); + fprintf(stderr, "Can't read %s\n", si->sections[j]); #endif - break; - } } - if (si->sections[j] != NULL) + 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) + if (file_printf(ms, "application/%s", si->mime) == -1) return -1; } return 1; @@ -459,6 +547,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, const char *expn = ""; const cdf_directory_t *root_storage; + scn.sst_tab = NULL; info.i_fd = fd; info.i_buf = buf; info.i_len = nbytes; @@ -528,10 +617,7 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, i = 1; goto out5; } else { - free(scn.sst_tab); - scn.sst_tab = NULL; - scn.sst_len = 0; - scn.sst_dirlen = 0; + cdf_zero_stream(&scn); } } @@ -539,56 +625,31 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, &scn)) == -1) { if (errno != ESRCH) { expn = "Cannot read summary info"; - 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; + } else { + i = cdf_check_summary_info(ms, &info, &h, + &sat, &ssat, &sst, &dir, &scn, root_storage, &expn); + cdf_zero_stream(&scn); } - - -#ifdef CDF_DEBUG - cdf_dump_summary_info(&h, &scn); -#endif - if ((i = cdf_file_summary_info(ms, &h, &scn, root_storage)) < 0) - expn = "Can't expand summary_info"; - - if (i == 0) { - const char *str = NULL; - cdf_directory_t *d; - char name[__arraycount(d->d_name)]; - size_t j, k; - - for (j = 0; str == NULL && j < dir.dir_len; j++) { - d = &dir.dir_tab[j]; - for (k = 0; k < sizeof(name); k++) - name[k] = (char)cdf_tole2(d->d_name[k]); - str = cdf_app_to_mime(name, - NOTMIME(ms) ? name2desc : name2mime); - } - if (NOTMIME(ms)) { - if (str != NULL) { - if (file_printf(ms, "%s", str) == -1) - return -1; - i = 1; + if (i <= 0) { + if ((i = cdf_read_doc_summary_info(&info, &h, &sat, &ssat, + &sst, &dir, &scn)) == -1) { + if (errno != ESRCH) { + expn = "Cannot read summary info"; } } else { - if (str == NULL) - str = "vnd.ms-office"; - if (file_printf(ms, "application/%s", str) == -1) - return -1; - i = 1; + i = cdf_check_summary_info(ms, &info, &h, &sat, &ssat, + &sst, &dir, &scn, root_storage, &expn); } } + if (i <= 0) { + i = cdf_file_dir_info(ms, &dir); + if (i < 0) + expn = "Cannot read section info"; + } out5: - free(scn.sst_tab); -out4: - free(sst.sst_tab); + cdf_zero_stream(&scn); + cdf_zero_stream(&sst); out3: free(dir.dir_tab); out2: @@ -605,7 +666,7 @@ out0: if (file_printf(ms, ", %s", expn) == -1) return -1; } else { - if (file_printf(ms, "application/CDFV2-unknown") == -1) + if (file_printf(ms, "application/CDFV2") == -1) return -1; } i = 1; diff --git a/contrib/file/src/readelf.c b/contrib/file/src/readelf.c index 39598f7..90dae39 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.127 2015/11/18 12:29:29 christos Exp $") +FILE_RCSID("@(#)$File: readelf.c,v 1.128 2016/10/04 21:43:10 christos Exp $") #endif #ifdef BUILTIN_ELF @@ -509,12 +509,26 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type, size_t noff, size_t doff, int *flags) { if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 && - type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) { + type == NT_GNU_BUILD_ID && (descsz >= 4 || descsz <= 20)) { uint8_t desc[20]; + const char *btype; uint32_t i; *flags |= FLAGS_DID_BUILD_ID; - if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" : - "sha1") == -1) + switch (descsz) { + case 8: + btype = "xxHash"; + break; + case 16: + btype = "md5/uuid"; + break; + case 20: + btype = "sha1"; + break; + default: + btype = "unknown"; + break; + } + if (file_printf(ms, ", BuildID[%s]=", btype) == -1) return 1; (void)memcpy(desc, &nbuf[doff], descsz); for (i = 0; i < descsz; i++) diff --git a/contrib/file/src/softmagic.c b/contrib/file/src/softmagic.c index 644c9d9..0e9d433 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.234 2016/06/13 12:02:06 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.238 2016/10/24 18:02:17 christos Exp $") #endif /* lint */ #include "magic.h" @@ -57,13 +57,13 @@ private int mcopy(struct magic_set *, union VALUETYPE *, int, int, const unsigned char *, uint32_t, size_t, struct magic *); private int mconvert(struct magic_set *, struct magic *, int); private int print_sep(struct magic_set *, int); -private int handle_annotation(struct magic_set *, struct magic *); +private int handle_annotation(struct magic_set *, struct magic *, int); private int cvt_8(union VALUETYPE *, const struct magic *); private int cvt_16(union VALUETYPE *, const struct magic *); private int cvt_32(union VALUETYPE *, const struct magic *); private int cvt_64(union VALUETYPE *, const struct magic *); -#define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o))) +#define OFFSET_OOB(n, o, i) ((n) < (uint32_t)(o) || (i) > ((n) - (o))) #define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \ ((uint64_t)(p)->hq[2]<<40)|((uint64_t)(p)->hq[3]<<32)| \ ((uint64_t)(p)->hq[4]<<24)|((uint64_t)(p)->hq[5]<<16)| \ @@ -80,6 +80,7 @@ private int cvt_64(union VALUETYPE *, const struct magic *); ((uint32_t)(p)->hl[3]<<8)|((uint32_t)(p)->hl[2])) #define BE16(p) (((uint16_t)(p)->hs[0]<<8)|((uint16_t)(p)->hs[1])) #define LE16(p) (((uint16_t)(p)->hs[1]<<8)|((uint16_t)(p)->hs[0])) +#define SEXT(s,v,p) ((s)?(intmax_t)(int##v##_t)(p):(intmax_t)(uint##v##_t)(p)) /* * softmagic - lookup one file in parsed, in-memory copy of database @@ -230,7 +231,7 @@ flush: goto flush; } - if ((e = handle_annotation(ms, m)) != 0) { + if ((e = handle_annotation(ms, m, firstline)) != 0) { *need_separator = 1; *printed_something = 1; *returnval = 1; @@ -328,7 +329,7 @@ flush: } else ms->c.li[cont_level].got_match = 1; - if ((e = handle_annotation(ms, m)) != 0) { + if ((e = handle_annotation(ms, m, firstline)) != 0) { *need_separator = 1; *printed_something = 1; *returnval = 1; @@ -1226,7 +1227,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, memchr(c, '\r', CAST(size_t, (end - c)))))); lines--, b++) { last = b; - if (b[0] == '\r' && b[1] == '\n') + if (b < end - 1 && b[0] == '\r' && b[1] == '\n') b++; } if (lines) @@ -1294,6 +1295,45 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, return 0; } +private uint32_t +do_ops(struct magic *m, intmax_t lhs, intmax_t off) +{ + intmax_t offset; + if (off) { + switch (m->in_op & FILE_OPS_MASK) { + case FILE_OPAND: + offset = lhs & off; + break; + case FILE_OPOR: + offset = lhs | off; + break; + case FILE_OPXOR: + offset = lhs ^ off; + break; + case FILE_OPADD: + offset = lhs + off; + break; + case FILE_OPMINUS: + offset = lhs - off; + break; + case FILE_OPMULTIPLY: + offset = lhs * off; + break; + case FILE_OPDIVIDE: + offset = lhs / off; + break; + case FILE_OPMODULO: + offset = lhs % off; + break; + } + } else + offset = lhs; + if (m->in_op & FILE_OPINVERSE) + offset = ~offset; + + return (uint32_t)offset; +} + 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, @@ -1301,7 +1341,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, int *printed_something, int *need_separator, int *returnval) { uint32_t offset = ms->offset; - uint32_t lhs; + intmax_t lhs; file_pushbuf_t *pb; int rv, oneed_separator, in_type; char *rbuf; @@ -1337,7 +1377,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, } if (m->flag & INDIR) { - int off = m->in_offset; + intmax_t off = m->in_offset; + const int sgn = m->in_op & FILE_OPSIGNED; if (m->in_op & FILE_OPINDIRECT) { const union VALUETYPE *q = CAST(const union VALUETYPE *, ((const void *)(s + offset + off))); @@ -1345,178 +1386,55 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return 0; switch (cvt_flip(m->in_type, flip)) { case FILE_BYTE: - off = q->b; + off = SEXT(sgn,8,q->b); break; case FILE_SHORT: - off = q->h; + off = SEXT(sgn,16,q->h); break; case FILE_BESHORT: - off = (short)BE16(q); + off = SEXT(sgn,16,BE16(q)); break; case FILE_LESHORT: - off = (short)LE16(q); + off = SEXT(sgn,16,LE16(q)); break; case FILE_LONG: - off = q->l; + off = SEXT(sgn,32,q->l); break; case FILE_BELONG: case FILE_BEID3: - off = (int32_t)BE32(q); + off = SEXT(sgn,32,BE32(q)); break; case FILE_LEID3: case FILE_LELONG: - off = (int32_t)LE32(q); + off = SEXT(sgn,32,LE32(q)); break; case FILE_MELONG: - off = (int32_t)ME32(q); + off = SEXT(sgn,32,ME32(q)); break; } if ((ms->flags & MAGIC_DEBUG) != 0) - fprintf(stderr, "indirect offs=%u\n", off); + fprintf(stderr, "indirect offs=%jd\n", off); } switch (in_type = cvt_flip(m->in_type, flip)) { case FILE_BYTE: if (OFFSET_OOB(nbytes, offset, 1)) return 0; - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = p->b & off; - break; - case FILE_OPOR: - offset = p->b | off; - break; - case FILE_OPXOR: - offset = p->b ^ off; - break; - case FILE_OPADD: - offset = p->b + off; - break; - case FILE_OPMINUS: - offset = p->b - off; - break; - case FILE_OPMULTIPLY: - offset = p->b * off; - break; - case FILE_OPDIVIDE: - offset = p->b / off; - break; - case FILE_OPMODULO: - offset = p->b % off; - break; - } - } else - offset = p->b; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + offset = do_ops(m, SEXT(sgn,8,p->b), off); break; case FILE_BESHORT: if (OFFSET_OOB(nbytes, offset, 2)) return 0; - lhs = (p->hs[0] << 8) | p->hs[1]; - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = lhs & off; - break; - case FILE_OPOR: - offset = lhs | off; - break; - case FILE_OPXOR: - offset = lhs ^ off; - break; - case FILE_OPADD: - offset = lhs + off; - break; - case FILE_OPMINUS: - offset = lhs - off; - break; - case FILE_OPMULTIPLY: - offset = lhs * off; - break; - case FILE_OPDIVIDE: - offset = lhs / off; - break; - case FILE_OPMODULO: - offset = lhs % off; - break; - } - } else - offset = lhs; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + offset = do_ops(m, SEXT(sgn,16,BE16(p)), off); break; case FILE_LESHORT: if (OFFSET_OOB(nbytes, offset, 2)) return 0; - lhs = (p->hs[1] << 8) | p->hs[0]; - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = lhs & off; - break; - case FILE_OPOR: - offset = lhs | off; - break; - case FILE_OPXOR: - offset = lhs ^ off; - break; - case FILE_OPADD: - offset = lhs + off; - break; - case FILE_OPMINUS: - offset = lhs - off; - break; - case FILE_OPMULTIPLY: - offset = lhs * off; - break; - case FILE_OPDIVIDE: - offset = lhs / off; - break; - case FILE_OPMODULO: - offset = lhs % off; - break; - } - } else - offset = lhs; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + offset = do_ops(m, SEXT(sgn,16,LE16(p)), off); break; case FILE_SHORT: if (OFFSET_OOB(nbytes, offset, 2)) return 0; - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = p->h & off; - break; - case FILE_OPOR: - offset = p->h | off; - break; - case FILE_OPXOR: - offset = p->h ^ off; - break; - case FILE_OPADD: - offset = p->h + off; - break; - case FILE_OPMINUS: - offset = p->h - off; - break; - case FILE_OPMULTIPLY: - offset = p->h * off; - break; - case FILE_OPDIVIDE: - offset = p->h / off; - break; - case FILE_OPMODULO: - offset = p->h % off; - break; - } - } - else - offset = p->h; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + offset = do_ops(m, SEXT(sgn,16,p->h), off); break; case FILE_BELONG: case FILE_BEID3: @@ -1524,38 +1442,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return 0; lhs = BE32(p); if (in_type == FILE_BEID3) - lhs = cvt_id3(ms, lhs); - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = lhs & off; - break; - case FILE_OPOR: - offset = lhs | off; - break; - case FILE_OPXOR: - offset = lhs ^ off; - break; - case FILE_OPADD: - offset = lhs + off; - break; - case FILE_OPMINUS: - offset = lhs - off; - break; - case FILE_OPMULTIPLY: - offset = lhs * off; - break; - case FILE_OPDIVIDE: - offset = lhs / off; - break; - case FILE_OPMODULO: - offset = lhs % off; - break; - } - } else - offset = lhs; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + lhs = cvt_id3(ms, (uint32_t)lhs); + offset = do_ops(m, SEXT(sgn,32,lhs), off); break; case FILE_LELONG: case FILE_LEID3: @@ -1563,109 +1451,18 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, return 0; lhs = LE32(p); if (in_type == FILE_LEID3) - lhs = cvt_id3(ms, lhs); - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = lhs & off; - break; - case FILE_OPOR: - offset = lhs | off; - break; - case FILE_OPXOR: - offset = lhs ^ off; - break; - case FILE_OPADD: - offset = lhs + off; - break; - case FILE_OPMINUS: - offset = lhs - off; - break; - case FILE_OPMULTIPLY: - offset = lhs * off; - break; - case FILE_OPDIVIDE: - offset = lhs / off; - break; - case FILE_OPMODULO: - offset = lhs % off; - break; - } - } else - offset = lhs; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + lhs = cvt_id3(ms, (uint32_t)lhs); + offset = do_ops(m, SEXT(sgn,32,lhs), off); break; case FILE_MELONG: if (OFFSET_OOB(nbytes, offset, 4)) return 0; - lhs = ME32(p); - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = lhs & off; - break; - case FILE_OPOR: - offset = lhs | off; - break; - case FILE_OPXOR: - offset = lhs ^ off; - break; - case FILE_OPADD: - offset = lhs + off; - break; - case FILE_OPMINUS: - offset = lhs - off; - break; - case FILE_OPMULTIPLY: - offset = lhs * off; - break; - case FILE_OPDIVIDE: - offset = lhs / off; - break; - case FILE_OPMODULO: - offset = lhs % off; - break; - } - } else - offset = lhs; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + offset = do_ops(m, SEXT(sgn,32,ME32(p)), off); break; case FILE_LONG: if (OFFSET_OOB(nbytes, offset, 4)) return 0; - if (off) { - switch (m->in_op & FILE_OPS_MASK) { - case FILE_OPAND: - offset = p->l & off; - break; - case FILE_OPOR: - offset = p->l | off; - break; - case FILE_OPXOR: - offset = p->l ^ off; - break; - case FILE_OPADD: - offset = p->l + off; - break; - case FILE_OPMINUS: - offset = p->l - off; - break; - case FILE_OPMULTIPLY: - offset = p->l * off; - break; - case FILE_OPDIVIDE: - offset = p->l / off; - break; - case FILE_OPMODULO: - offset = p->l % off; - break; - } - } else - offset = p->l; - if (m->in_op & FILE_OPINVERSE) - offset = ~offset; + offset = do_ops(m, SEXT(sgn,32,p->l), off); break; default: break; @@ -2078,7 +1875,7 @@ magiccheck(struct magic_set *ms, struct magic *m) size_t slen = ms->search.s_len; char *copy; if (slen != 0) { - copy = malloc(slen); + copy = CAST(char *, malloc(slen)); if (copy == NULL) { file_regfree(&rx); file_error(ms, errno, @@ -2231,19 +2028,25 @@ magiccheck(struct magic_set *ms, struct magic *m) } private int -handle_annotation(struct magic_set *ms, struct magic *m) +handle_annotation(struct magic_set *ms, struct magic *m, int firstline) { if ((ms->flags & MAGIC_APPLE) && m->apple[0]) { + if (!firstline && file_printf(ms, "\n- ") == -1) + return -1; if (file_printf(ms, "%.8s", m->apple) == -1) return -1; return 1; } if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) { + if (!firstline && file_printf(ms, "\n- ") == -1) + return -1; if (file_printf(ms, "%s", m->ext) == -1) return -1; return 1; } if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) { + if (!firstline && file_printf(ms, "\n- ") == -1) + return -1; if (file_printf(ms, "%s", m->mimetype) == -1) return -1; return 1; @@ -2254,8 +2057,8 @@ handle_annotation(struct magic_set *ms, struct magic *m) private int print_sep(struct magic_set *ms, int firstline) { - if (ms->flags & MAGIC_NODESC) - return 0; +// if (ms->flags & MAGIC_NODESC) +// return 0; if (firstline) return 0; /* |