1 |
diff --git a/ext/fileinfo/libmagic/cdf.c b/ext/fileinfo/libmagic/cdf.c |
2 |
index 59af8da..3adac3f 100644 |
3 |
--- a/ext/fileinfo/libmagic/cdf.c |
4 |
+++ b/ext/fileinfo/libmagic/cdf.c |
5 |
@@ -316,18 +316,27 @@ ssize_t |
6 |
cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, |
7 |
const cdf_header_t *h, cdf_secid_t id) |
8 |
{ |
9 |
- assert((size_t)CDF_SEC_SIZE(h) == len); |
10 |
- return cdf_read(info, (off_t)CDF_SEC_POS(h, id), |
11 |
- ((char *)buf) + offs, len); |
12 |
+ size_t ss = CDF_SEC_SIZE(h); |
13 |
+ size_t pos = CDF_SEC_POS(h, id); |
14 |
+ assert(ss == len); |
15 |
+ return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len); |
16 |
} |
17 |
|
18 |
ssize_t |
19 |
cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, |
20 |
size_t len, const cdf_header_t *h, cdf_secid_t id) |
21 |
{ |
22 |
- assert((size_t)CDF_SHORT_SEC_SIZE(h) == len); |
23 |
+ size_t ss = CDF_SHORT_SEC_SIZE(h); |
24 |
+ size_t pos = CDF_SHORT_SEC_POS(h, id); |
25 |
+ assert(ss == len); |
26 |
+ if (pos + len > CDF_SEC_SIZE(h) * sst->sst_len) { |
27 |
+ DPRINTF(("Out of bounds read %lu > %" |
28 |
+ "l" "u\n", |
29 |
+ pos + len, CDF_SEC_SIZE(h) * sst->sst_len)); |
30 |
+ return -1; |
31 |
+ } |
32 |
(void)memcpy(((char *)buf) + offs, |
33 |
- ((const char *)sst->sst_tab) + CDF_SHORT_SEC_POS(h, id), len); |
34 |
+ ((const char *)sst->sst_tab) + pos, len); |
35 |
return len; |
36 |
} |
37 |
|
38 |
@@ -347,7 +356,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) |
39 |
break; |
40 |
|
41 |
#define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss)) |
42 |
- if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec || |
43 |
+ if ((nsatpersec > 0 && h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec) || |
44 |
i > CDF_SEC_LIMIT) { |
45 |
DPRINTF(("Number of sectors in master SAT too big %u %zu\n", |
46 |
h->h_num_sectors_in_master_sat, i)); |
47 |
@@ -751,8 +760,13 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t |
48 |
if (cdf_check_stream_offset(sst, h, e, 0) == -1) |
49 |
goto out; |
50 |
for (i = 0; i < sh.sh_properties; i++) { |
51 |
- q = (const uint32_t *)((const char *)p + |
52 |
- CDF_TOLE4(p[(i << 1) + 1])) - 2; |
53 |
+ size_t tail = (i << 1) + 1; |
54 |
+ if (cdf_check_stream_offset(sst, h, p, tail * sizeof(uint32_t)) == -1) |
55 |
+ goto out; |
56 |
+ size_t ofs = CDF_TOLE4(p[tail]); |
57 |
+ q = (const uint32_t *)(const void *) |
58 |
+ ((const char *)(const void *)p + ofs |
59 |
+ - 2 * sizeof(uint32_t)); |
60 |
if (q > e) { |
61 |
DPRINTF(("Ran of the end %p > %p\n", q, e)); |
62 |
goto out; |
63 |
@@ -808,6 +822,20 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t |
64 |
(void)memcpy(&u64, &q[o], sizeof(u64)); |
65 |
inp[i].pi_u64 = CDF_TOLE4(u64); |
66 |
break; |
67 |
+ case CDF_FLOAT: |
68 |
+ if (inp[i].pi_type & CDF_VECTOR) |
69 |
+ goto unknown; |
70 |
+ (void)memcpy(&u32, &q[o], sizeof(u32)); |
71 |
+ u32 = CDF_TOLE4(u32); |
72 |
+ memcpy(&inp[i].pi_f, &u32, sizeof(inp[i].pi_f)); |
73 |
+ break; |
74 |
+ case CDF_DOUBLE: |
75 |
+ if (inp[i].pi_type & CDF_VECTOR) |
76 |
+ goto unknown; |
77 |
+ (void)memcpy(&u64, &q[o], sizeof(u64)); |
78 |
+ u64 = CDF_TOLE8((uint64_t)u64); |
79 |
+ memcpy(&inp[i].pi_d, &u64, sizeof(inp[i].pi_d)); |
80 |
+ break; |
81 |
case CDF_LENGTH32_STRING: |
82 |
if (nelements > 1) { |
83 |
size_t nelem = inp - *info; |
84 |
@@ -832,6 +860,8 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t |
85 |
inp[i].pi_str.s_buf)); |
86 |
l = 4 + CDF_ROUND(l, sizeof(l)); |
87 |
o += l >> 2; |
88 |
+ if (q + o >= e) |
89 |
+ goto out; |
90 |
} |
91 |
i--; |
92 |
break; |
93 |
@@ -849,7 +879,7 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h, uint32_t |
94 |
unknown: |
95 |
DPRINTF(("Don't know how to deal with %x\n", |
96 |
inp[i].pi_type)); |
97 |
- goto out; |
98 |
+ break; |
99 |
} |
100 |
} |
101 |
return 0; |
102 |
@@ -880,8 +910,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h, cdf_summ |
103 |
maxcount = 0; |
104 |
*info = NULL; |
105 |
if (cdf_read_property_info(sst, h, CDF_TOLE4(sd->sd_offset), |
106 |
- info, count, &maxcount) == -1) |
107 |
+ info, count, &maxcount) == -1) { |
108 |
return -1; |
109 |
+ } |
110 |
return 0; |
111 |
} |
112 |
|
113 |
@@ -1125,6 +1156,14 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count) |
114 |
(void)fprintf(stderr, "unsigned 32 [%u]\n", |
115 |
info[i].pi_u32); |
116 |
break; |
117 |
+ case CDF_FLOAT: |
118 |
+ (void)fprintf(stderr, "float [%g]\n", |
119 |
+ info[i].pi_f); |
120 |
+ break; |
121 |
+ case CDF_DOUBLE: |
122 |
+ (void)fprintf(stderr, "double [%g]\n", |
123 |
+ info[i].pi_d); |
124 |
+ break; |
125 |
case CDF_LENGTH32_STRING: |
126 |
(void)fprintf(stderr, "string %u [%.*s]\n", |
127 |
info[i].pi_str.s_len, |
128 |
diff --git a/ext/fileinfo/libmagic/cdf.h b/ext/fileinfo/libmagic/cdf.h |
129 |
index c27d1ea..16bb494 100644 |
130 |
--- a/ext/fileinfo/libmagic/cdf.h |
131 |
+++ b/ext/fileinfo/libmagic/cdf.h |
132 |
@@ -65,9 +65,9 @@ typedef struct { |
133 |
cdf_secid_t h_master_sat[436/4]; |
134 |
} cdf_header_t; |
135 |
|
136 |
-#define CDF_SEC_SIZE(h) (1 << (h)->h_sec_size_p2) |
137 |
+#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2)) |
138 |
#define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h)) |
139 |
-#define CDF_SHORT_SEC_SIZE(h) (1 << (h)->h_short_sec_size_p2) |
140 |
+#define CDF_SHORT_SEC_SIZE(h) ((size_t)(1 << (h)->h_short_sec_size_p2)) |
141 |
#define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h)) |
142 |
|
143 |
typedef int32_t cdf_dirid_t; |
144 |
@@ -159,6 +159,8 @@ typedef struct { |
145 |
uint64_t _pi_u64; |
146 |
int64_t _pi_s64; |
147 |
cdf_timestamp_t _pi_tp; |
148 |
+ float _pi_f; |
149 |
+ double _pi_d; |
150 |
struct { |
151 |
uint32_t s_len; |
152 |
const char *s_buf; |
153 |
@@ -170,6 +172,8 @@ typedef struct { |
154 |
#define pi_s32 pi_val._pi_s32 |
155 |
#define pi_u16 pi_val._pi_u16 |
156 |
#define pi_s16 pi_val._pi_s16 |
157 |
+#define pi_f pi_val._pi_f |
158 |
+#define pi_d pi_val._pi_d |
159 |
#define pi_tp pi_val._pi_tp |
160 |
#define pi_str pi_val._pi_str |
161 |
} cdf_property_info_t; |
162 |
diff --git a/ext/fileinfo/libmagic/readcdf.c b/ext/fileinfo/libmagic/readcdf.c |
163 |
index d26054e..eb6f851 100644 |
164 |
--- a/ext/fileinfo/libmagic/readcdf.c |
165 |
+++ b/ext/fileinfo/libmagic/readcdf.c |
166 |
@@ -74,6 +74,16 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, |
167 |
info[i].pi_u32) == -1) |
168 |
return -1; |
169 |
break; |
170 |
+ case CDF_FLOAT: |
171 |
+ if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, |
172 |
+ info[i].pi_f) == -1) |
173 |
+ return -1; |
174 |
+ break; |
175 |
+ case CDF_DOUBLE: |
176 |
+ if (NOTMIME(ms) && file_printf(ms, ", %s: %g", buf, |
177 |
+ info[i].pi_d) == -1) |
178 |
+ return -1; |
179 |
+ break; |
180 |
case CDF_LENGTH32_STRING: |
181 |
len = info[i].pi_str.s_len; |
182 |
if (len > 1) { |