summaryrefslogtreecommitdiffstats
path: root/contrib/file/src/readcdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/file/src/readcdf.c')
-rw-r--r--contrib/file/src/readcdf.c142
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 = &sectioninfo[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;
OpenPOWER on IntegriCloud