diff options
Diffstat (limited to 'ext/fileinfo/libmagic/cdf.c')
| -rw-r--r-- | ext/fileinfo/libmagic/cdf.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c index dd7177ed90..cbe3b0cf77 100644 --- a/ext/fileinfo/libmagic/cdf.c +++ b/ext/fileinfo/libmagic/cdf.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.53 2013/02/26 16:20:42 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.55 2014/02/27 23:26:17 christos Exp $") #endif #include <assert.h> @@ -365,10 +365,10 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, size_t ss = CDF_SHORT_SEC_SIZE(h); size_t pos = CDF_SHORT_SEC_POS(h, id); assert(ss == len); - if (pos > CDF_SEC_SIZE(h) * sst->sst_len) { + if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { DPRINTF(("Out of bounds read %" SIZE_T_FORMAT "u > %" SIZE_T_FORMAT "u\n", - pos, CDF_SEC_SIZE(h) * sst->sst_len)); + pos + len, CDF_SEC_SIZE(h) * sst->sst_len)); return -1; } (void)memcpy(((char *)buf) + offs, @@ -688,11 +688,13 @@ out: int cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, - const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn) + const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn, + const cdf_directory_t **root) { size_t i; const cdf_directory_t *d; + *root = NULL; for (i = 0; i < dir->dir_len; i++) if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE) break; @@ -701,6 +703,7 @@ cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, if (i == dir->dir_len) 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) @@ -823,6 +826,10 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, i, inp[i].pi_id, inp[i].pi_type, q - p, offs)); if (inp[i].pi_type & CDF_VECTOR) { nelements = CDF_GETUINT32(q, 1); + if (nelements == 0) { + DPRINTF(("CDF_VECTOR with nelements == 0\n")); + goto out; + } o = 2; } else { nelements = 1; @@ -897,7 +904,9 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, } DPRINTF(("nelements = %" SIZE_T_FORMAT "u\n", nelements)); - for (j = 0; j < nelements; j++, i++) { + for (j = 0; j < nelements && i < sh.sh_properties; + j++, i++) + { uint32_t l = CDF_GETUINT32(q, o); inp[i].pi_str.s_len = l; inp[i].pi_str.s_buf = (const char *) @@ -942,7 +951,7 @@ int cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, cdf_summary_info_header_t *ssi, cdf_property_info_t **info, size_t *count) { - size_t i, maxcount; + size_t maxcount; const cdf_summary_info_header_t *si = CAST(const cdf_summary_info_header_t *, sst->sst_tab); const cdf_section_declaration_t *sd = @@ -957,21 +966,13 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, ssi->si_os = CDF_TOLE2(si->si_os); ssi->si_class = si->si_class; cdf_swap_class(&ssi->si_class); - ssi->si_count = CDF_TOLE2(si->si_count); + ssi->si_count = CDF_TOLE4(si->si_count); *count = 0; maxcount = 0; *info = NULL; - for (i = 0; i < CDF_TOLE4(si->si_count); i++) { - if (i >= CDF_LOOP_LIMIT) { - DPRINTF(("Unpack summary info loop limit")); - errno = EFTYPE; + if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), info, + count, &maxcount) == -1) return -1; - } - if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), - info, count, &maxcount) == -1) { - return -1; - } - } return 0; } |
