diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c index 59af8da..3adac3f 100644 --- a/ext/fileinfo/libmagic/cdf.c +++ b/ext/fileinfo/libmagic/cdf.c @@ -316,18 +316,27 @@ ssize_t cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { - assert((size_t)CDF_SEC_SIZE(h) == len); - return cdf_read(info, (off_t)CDF_SEC_POS(h, id), - ((char *)buf) + offs, len); + size_t ss = CDF_SEC_SIZE(h); + size_t pos = CDF_SEC_POS(h, id); + assert(ss == len); + return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len); } ssize_t cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { - assert((size_t)CDF_SHORT_SEC_SIZE(h) == len); + size_t ss = CDF_SHORT_SEC_SIZE(h); + size_t pos = CDF_SHORT_SEC_POS(h, id); + assert(ss == len); + if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { + DPRINTF(("Out of bounds read %lu > %" + "l" "u\n", + pos + len, CDF_SEC_SIZE(h) * sst->sst_len)); + return -1; + } (void)memcpy(((char *)buf) + offs, - ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len); + ((const char *)sst->sst_tab) + pos, len); return len; } @@ -347,7 +356,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) break; #define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss)) - if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec || + if ((nsatpersec > 0 && h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec) || i > CDF_SEC_LIMIT) { DPRINTF(("Number of sectors in master SAT too big %u %zu\n", h->h_num_sectors_in_master_sat, i)); @@ -751,8 +760,13 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t if (cdf_check_stream_offset(sst, h, e, 0) == -1) goto out; for (i = 0; i < sh.sh_properties; i++) { - q = (const uint32_t *)((const char *)p + - CDF_TOLE4(p[(i << 1) + 1])) - 2; + size_t tail = (i << 1) + 1; + if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t)) == -1) + goto out; + size_t ofs = CDF_TOLE4(p[tail]); + q = (const uint32_t *)(const void *) + ((const char *)(const void *)p + ofs + - 2 * sizeof(uint32_t)); if (q > e) { DPRINTF(("Ran of the end %p > %p\n", q, e)); goto out; @@ -808,6 +822,20 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t (void)memcpy(&u64, &q[o], sizeof(u64)); inp[i].pi_u64 = CDF_TOLE4(u64); break; + case CDF_FLOAT: + if (inp[i].pi_type & CDF_VECTOR) + goto unknown; + (void)memcpy(&u32, &q[o], sizeof(u32)); + u32 = CDF_TOLE4(u32); + memcpy(&inp[i].pi_f, &u32, sizeof(inp[i].pi_f)); + break; + case CDF_DOUBLE: + if (inp[i].pi_type & CDF_VECTOR) + goto unknown; + (void)memcpy(&u64, &q[o], sizeof(u64)); + u64 = CDF_TOLE8((uint64_t)u64); + memcpy(&inp[i].pi_d, &u64, sizeof(inp[i].pi_d)); + break; case CDF_LENGTH32_STRING: if (nelements > 1) { size_t nelem = inp - *info; @@ -832,6 +860,8 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t inp[i].pi_str.s_buf)); l = 4 + CDF_ROUND(l, sizeof(l)); o += l >> 2; + if (q + o >= e) + goto out; } i--; break; @@ -849,7 +879,7 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t unknown: DPRINTF(("Don't know how to deal with %x\n", inp[i].pi_type)); - goto out; + break; } } return 0; @@ -880,8 +910,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, cdf_summ maxcount = 0; *info = NULL; if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), - info, count, &maxcount) == -1) + info, count, &maxcount) == -1) { return -1; + } return 0; } @@ -1125,6 +1156,14 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count) (void)fprintf(stderr, "unsigned 32 [%u]\n", info[i].pi_u32); break; + case CDF_FLOAT: + (void)fprintf(stderr, "float [%g]\n", + info[i].pi_f); + break; + case CDF_DOUBLE: + (void)fprintf(stderr, "double [%g]\n", + info[i].pi_d); + break; case CDF_LENGTH32_STRING: (void)fprintf(stderr, "string %u [%.*s]\n", info[i].pi_str.s_len, diff --git a/ext/fileinfo/libmagic/cdf.h b/ext/fileinfo/libmagic/cdf.h index c27d1ea..16bb494 100644 --- a/ext/fileinfo/libmagic/cdf.h +++ b/ext/fileinfo/libmagic/cdf.h @@ -65,9 +65,9 @@ typedef struct { cdf_secid_t h_master_sat[436/4]; } cdf_header_t; -#define CDF_SEC_SIZE(h) (1 << (h)->h_sec_size_p2) +#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2)) #define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h)) -#define CDF_SHORT_SEC_SIZE(h) (1 << (h)->h_short_sec_size_p2) +#define CDF_SHORT_SEC_SIZE(h) ((size_t)(1 << (h)->h_short_sec_size_p2)) #define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h)) typedef int32_t cdf_dirid_t; @@ -159,6 +159,8 @@ typedef struct { uint64_t _pi_u64; int64_t _pi_s64; cdf_timestamp_t _pi_tp; + float _pi_f; + double _pi_d; struct { uint32_t s_len; const char *s_buf; @@ -170,6 +172,8 @@ typedef struct { #define pi_s32 pi_val._pi_s32 #define pi_u16 pi_val._pi_u16 #define pi_s16 pi_val._pi_s16 +#define pi_f pi_val._pi_f +#define pi_d pi_val._pi_d #define pi_tp pi_val._pi_tp #define pi_str pi_val._pi_str } cdf_property_info_t; diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c index d26054e..eb6f851 100644 --- a/ext/fileinfo/libmagic/readcdf.c +++ b/ext/fileinfo/libmagic/readcdf.c @@ -74,6 +74,16 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, info[i].pi_u32) == -1) return -1; break; + case CDF_FLOAT: + if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, + info[i].pi_f) == -1) + return -1; + break; + case CDF_DOUBLE: + if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, + info[i].pi_d) == -1) + return -1; + break; case CDF_LENGTH32_STRING: len = info[i].pi_str.s_len; if (len > 1) {