diff options
Diffstat (limited to 'contrib/file/src/readcdf.c')
-rw-r--r-- | contrib/file/src/readcdf.c | 142 |
1 files changed, 113 insertions, 29 deletions
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; |