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