diff options
Diffstat (limited to 'ext/fileinfo/libmagic/readcdf.c')
-rw-r--r-- | ext/fileinfo/libmagic/readcdf.c | 145 |
1 files changed, 98 insertions, 47 deletions
diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c index 3abcc2e62e..1600625eb8 100644 --- a/ext/fileinfo/libmagic/readcdf.c +++ b/ext/fileinfo/libmagic/readcdf.c @@ -26,7 +26,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readcdf.c,v 1.33 2012/06/20 21:52:36 christos Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.37 2014/01/06 13:41:18 rrt Exp $") #endif #include <stdlib.h> @@ -38,12 +38,61 @@ FILE_RCSID("@(#)$File: readcdf.c,v 1.33 2012/06/20 21:52:36 christos Exp $") #include <string.h> #include <time.h> #include <ctype.h> +#if defined(HAVE_LOCALE_H) +#include <locale.h> +#endif #include "cdf.h" #include "magic.h" #define NOTMIME(ms) (((ms)->flags & MAGIC_MIME) == 0) +static const struct nv { + const char *pattern; + const char *mime; +} app2mime[] = { + { "Word", "msword", }, + { "Excel", "vnd.ms-excel", }, + { "Powerpoint", "vnd.ms-powerpoint", }, + { "Crystal Reports", "x-rpt", }, + { "Advanced Installer", "vnd.ms-msi", }, + { "InstallShield", "vnd.ms-msi", }, + { "Microsoft Patch Compiler", "vnd.ms-msi", }, + { "NAnt", "vnd.ms-msi", }, + { "Windows Installer", "vnd.ms-msi", }, + { NULL, NULL, }, +}, name2mime[] = { + { "WordDocument", "msword", }, + { "PowerPoint", "vnd.ms-powerpoint", }, + { "DigitalSignature", "vnd.ms-msi", }, + { NULL, NULL, }, +}, name2desc[] = { + { "WordDocument", "Microsoft Office Word",}, + { "PowerPoint", "Microsoft PowerPoint", }, + { "DigitalSignature", "Microsoft Installer", }, + { NULL, NULL, }, +}; + +#ifdef PHP_WIN32 +# define strcasestr strstr +#endif + +private const char * +cdf_app_to_mime(const char *vbuf, const struct nv *nv) +{ + size_t i; + const char *rv = NULL; + + (void)setlocale(LC_CTYPE, "C"); + for (i = 0; nv[i].pattern != NULL; i++) + if (strcasestr(vbuf, nv[i].pattern) != NULL) { + rv = nv[i].mime; + break; + } + (void)setlocale(LC_CTYPE, ""); + return rv; +} + private int cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, size_t count) @@ -56,6 +105,8 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, const char *s; int len; + memset(&ts, 0, sizeof(ts)); + for (i = 0; i < count; i++) { cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); switch (info[i].pi_type) { @@ -113,18 +164,10 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, return -1; } } else if (info[i].pi_id == - CDF_PROPERTY_NAME_OF_APPLICATION) { - if (strstr(vbuf, "Word")) - str = "msword"; - else if (strstr(vbuf, "Excel")) - str = "vnd.ms-excel"; - else if (strstr(vbuf, "Powerpoint")) - str = "vnd.ms-powerpoint"; - else if (strstr(vbuf, - "Crystal Reports")) - str = "x-rpt"; - } - } + CDF_PROPERTY_NAME_OF_APPLICATION) { + str = cdf_app_to_mime(vbuf, app2mime); + } + } break; case CDF_FILETIME: tp = info[i].pi_tp; @@ -142,12 +185,14 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, return -1; } else { char *c, *ec; + const time_t sec = ts.tv_sec; if (cdf_timestamp_to_timespec(&ts, tp) == -1) { return -1; } - c = cdf_ctime(&ts.tv_sec, tbuf); - if ((ec = strchr(c, '\n')) != NULL) - *ec = '\0'; + c = cdf_ctime(&sec, tbuf); + if (c != NULL && + (ec = strchr(c, '\n')) != NULL) + *ec = '\0'; if (NOTMIME(ms) && file_printf(ms, ", %s: %s", buf, c) == -1) @@ -287,26 +332,34 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, if ((i = cdf_file_summary_info(ms, &h, &scn)) < 0) expn = "Can't expand summary_info"; if (i == 0) { - const char *str = "vnd.ms-office"; + const char *str = NULL; cdf_directory_t *d; char name[__arraycount(d->d_name)]; size_t j, k; for (j = 0; 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]); - if (strstr(name, "WordDocument") != 0) { - str = "msword"; - break; - } - if (strstr(name, "PowerPoint") != 0) { - str = "vnd.ms-powerpoint"; - break; - } + d = &dir.dir_tab[j]; + for (k = 0; k < sizeof(name); k++) + name[k] = (char)cdf_tole2(d->d_name[k]); + if (NOTMIME(ms)) + str = cdf_app_to_mime(name, name2desc); + else + str = cdf_app_to_mime(name, name2mime); + if (str != NULL) + break; + } + 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 (file_printf(ms, "application/%s", str) == -1) - return -1; - i = 1; } free(scn.sst_tab); out4: @@ -318,21 +371,19 @@ out2: out1: free(sat.sat_tab); out0: - if (i != 1) { - if (i == -1) { - if (NOTMIME(ms)) { - if (file_printf(ms, - "Composite Document File V2 Document") == -1) - return -1; - if (*expn) - if (file_printf(ms, ", %s%s", corrupt, expn) == -1) - return -1; - } else { - if (file_printf(ms, "application/CDFV2-corrupt") == -1) - return -1; - } - } - i = 1; - } + if (i == -1) { + if (NOTMIME(ms)) { + if (file_printf(ms, + "Composite Document File V2 Document") == -1) + return -1; + if (*expn) + if (file_printf(ms, ", %s%s", corrupt, expn) == -1) + return -1; + } else { + if (file_printf(ms, "application/CDFV2-corrupt") == -1) + return -1; + } + i = 1; + } return i; } |