1 --- ghostscript-8.64/icclib/icc.c.CVE-2009-0583,0584 2008-05-09 05:12:01.000000000 +0100 |
|
2 +++ ghostscript-8.64/icclib/icc.c 2009-03-06 15:24:33.000000000 +0000 |
|
3 @@ -152,6 +152,8 @@ |
|
4 * Various bug fixes and enhancements. |
|
5 */ |
|
6 |
|
7 +#include <limits.h> |
|
8 +#include <stdint.h> |
|
9 #include <stdio.h> |
|
10 #include <stdlib.h> |
|
11 #include <stdarg.h> |
|
12 @@ -313,8 +315,11 @@ size_t count |
|
13 icmFileMem *p = (icmFileMem *)pp; |
|
14 size_t len; |
|
15 |
|
16 + if (count > 0 && size > SIZE_MAX / count) |
|
17 + return 0; |
|
18 + |
|
19 len = size * count; |
|
20 - if ((p->cur + len) >= p->end) { /* Too much */ |
|
21 + if (len > (p->end - p->cur)) { /* Too much */ |
|
22 if (size > 0) |
|
23 count = (p->end - p->cur)/size; |
|
24 else |
|
25 @@ -1634,6 +1639,8 @@ static int icmUInt8Array_write( |
|
26 |
|
27 /* Allocate a file write buffer */ |
|
28 len = p->get_size((icmBase *)p); |
|
29 + if (icp->errc) |
|
30 + return icp->errc; |
|
31 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
32 sprintf(icp->err,"icmUInt8Array_write malloc() failed"); |
|
33 return icp->errc = 2; |
|
34 @@ -1698,7 +1705,7 @@ static int icmUInt8Array_allocate( |
|
35 if (p->size != p->_size) { |
|
36 if (p->data != NULL) |
|
37 icp->al->free(icp->al, p->data); |
|
38 - if ((p->data = (unsigned int *) icp->al->malloc(icp->al, p->size * sizeof(unsigned int))) == NULL) { |
|
39 + if ((p->data = (unsigned int *) icp->al->calloc(icp->al, p->size, sizeof(unsigned int))) == NULL) { |
|
40 sprintf(icp->err,"icmUInt8Array_alloc: malloc() of icmUInt8Array data failed"); |
|
41 return icp->errc = 2; |
|
42 } |
|
43 @@ -1749,6 +1756,10 @@ static unsigned int icmUInt16Array_get_s |
|
44 icmUInt16Array *p = (icmUInt16Array *)pp; |
|
45 unsigned int len = 0; |
|
46 len += 8; /* 8 bytes for tag and padding */ |
|
47 + if (p->size > (UINT_MAX - len) / 2) { |
|
48 + p->icp->errc = 1; |
|
49 + return (unsigned int) -1; |
|
50 + } |
|
51 len += p->size * 2; /* 2 bytes for each UInt16 */ |
|
52 return len; |
|
53 } |
|
54 @@ -1821,6 +1832,8 @@ static int icmUInt16Array_write( |
|
55 |
|
56 /* Allocate a file write buffer */ |
|
57 len = p->get_size((icmBase *)p); |
|
58 + if (icp->errc) |
|
59 + return icp->errc; |
|
60 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
61 sprintf(icp->err,"icmUInt16Array_write malloc() failed"); |
|
62 return icp->errc = 2; |
|
63 @@ -1885,7 +1898,7 @@ static int icmUInt16Array_allocate( |
|
64 if (p->size != p->_size) { |
|
65 if (p->data != NULL) |
|
66 icp->al->free(icp->al, p->data); |
|
67 - if ((p->data = (unsigned int *) icp->al->malloc(icp->al, p->size * sizeof(unsigned int))) == NULL) { |
|
68 + if ((p->data = (unsigned int *) icp->al->calloc(icp->al, p->size, sizeof(unsigned int))) == NULL) { |
|
69 sprintf(icp->err,"icmUInt16Array_alloc: malloc() of icmUInt16Array data failed"); |
|
70 return icp->errc = 2; |
|
71 } |
|
72 @@ -1936,6 +1949,10 @@ static unsigned int icmUInt32Array_get_s |
|
73 icmUInt32Array *p = (icmUInt32Array *)pp; |
|
74 unsigned int len = 0; |
|
75 len += 8; /* 8 bytes for tag and padding */ |
|
76 + if (p->size > (UINT_MAX - len) / 4) { |
|
77 + p->icp->errc = 1; |
|
78 + return (unsigned int) -1; |
|
79 + } |
|
80 len += p->size * 4; /* 4 bytes for each UInt32 */ |
|
81 return len; |
|
82 } |
|
83 @@ -2008,6 +2025,8 @@ static int icmUInt32Array_write( |
|
84 |
|
85 /* Allocate a file write buffer */ |
|
86 len = p->get_size((icmBase *)p); |
|
87 + if (icp->errc) |
|
88 + return icp->errc; |
|
89 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
90 sprintf(icp->err,"icmUInt32Array_write malloc() failed"); |
|
91 return icp->errc = 2; |
|
92 @@ -2072,7 +2091,7 @@ static int icmUInt32Array_allocate( |
|
93 if (p->size != p->_size) { |
|
94 if (p->data != NULL) |
|
95 icp->al->free(icp->al, p->data); |
|
96 - if ((p->data = (unsigned int *) icp->al->malloc(icp->al, p->size * sizeof(unsigned int))) == NULL) { |
|
97 + if ((p->data = (unsigned int *) icp->al->calloc(icp->al, p->size, sizeof(unsigned int))) == NULL) { |
|
98 sprintf(icp->err,"icmUInt32Array_alloc: malloc() of icmUInt32Array data failed"); |
|
99 return icp->errc = 2; |
|
100 } |
|
101 @@ -2123,6 +2142,10 @@ static unsigned int icmUInt64Array_get_s |
|
102 icmUInt64Array *p = (icmUInt64Array *)pp; |
|
103 unsigned int len = 0; |
|
104 len += 8; /* 8 bytes for tag and padding */ |
|
105 + if (p->size > (UINT_MAX - len) / 8) { |
|
106 + p->icp->errc = 1; |
|
107 + return (unsigned int) -1; |
|
108 + } |
|
109 len += p->size * 8; /* 8 bytes for each UInt64 */ |
|
110 return len; |
|
111 } |
|
112 @@ -2195,6 +2218,8 @@ static int icmUInt64Array_write( |
|
113 |
|
114 /* Allocate a file write buffer */ |
|
115 len = p->get_size((icmBase *)p); |
|
116 + if (icp->errc) |
|
117 + return icp->errc; |
|
118 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
119 sprintf(icp->err,"icmUInt64Array_write malloc() failed"); |
|
120 return icp->errc = 2; |
|
121 @@ -2259,7 +2284,7 @@ static int icmUInt64Array_allocate( |
|
122 if (p->size != p->_size) { |
|
123 if (p->data != NULL) |
|
124 icp->al->free(icp->al, p->data); |
|
125 - if ((p->data = (icmUint64 *) icp->al->malloc(icp->al, p->size * sizeof(icmUint64))) == NULL) { |
|
126 + if ((p->data = (icmUint64 *) icp->al->calloc(icp->al, p->size, sizeof(icmUint64))) == NULL) { |
|
127 sprintf(icp->err,"icmUInt64Array_alloc: malloc() of icmUInt64Array data failed"); |
|
128 return icp->errc = 2; |
|
129 } |
|
130 @@ -2310,6 +2335,10 @@ static unsigned int icmU16Fixed16Array_g |
|
131 icmU16Fixed16Array *p = (icmU16Fixed16Array *)pp; |
|
132 unsigned int len = 0; |
|
133 len += 8; /* 8 bytes for tag and padding */ |
|
134 + if (p->size > (UINT_MAX - len) / 4) { |
|
135 + p->icp->errc = 1; |
|
136 + return (unsigned int) -1; |
|
137 + } |
|
138 len += p->size * 4; /* 4 byte for each U16Fixed16 */ |
|
139 return len; |
|
140 } |
|
141 @@ -2382,6 +2411,8 @@ static int icmU16Fixed16Array_write( |
|
142 |
|
143 /* Allocate a file write buffer */ |
|
144 len = p->get_size((icmBase *)p); |
|
145 + if (icp->errc) |
|
146 + return icp->errc; |
|
147 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
148 sprintf(icp->err,"icmU16Fixed16Array_write malloc() failed"); |
|
149 return icp->errc = 2; |
|
150 @@ -2446,7 +2477,7 @@ static int icmU16Fixed16Array_allocate( |
|
151 if (p->size != p->_size) { |
|
152 if (p->data != NULL) |
|
153 icp->al->free(icp->al, p->data); |
|
154 - if ((p->data = (double *) icp->al->malloc(icp->al, p->size * sizeof(double))) == NULL) { |
|
155 + if ((p->data = (double *) icp->al->calloc(icp->al, p->size, sizeof(double))) == NULL) { |
|
156 sprintf(icp->err,"icmU16Fixed16Array_alloc: malloc() of icmU16Fixed16Array data failed"); |
|
157 return icp->errc = 2; |
|
158 } |
|
159 @@ -2497,6 +2528,10 @@ static unsigned int icmS15Fixed16Array_g |
|
160 icmS15Fixed16Array *p = (icmS15Fixed16Array *)pp; |
|
161 unsigned int len = 0; |
|
162 len += 8; /* 8 bytes for tag and padding */ |
|
163 + if (p->size > (UINT_MAX - len) / 4) { |
|
164 + p->icp->errc = 1; |
|
165 + return (unsigned int) - 1; |
|
166 + } |
|
167 len += p->size * 4; /* 4 byte for each S15Fixed16 */ |
|
168 return len; |
|
169 } |
|
170 @@ -2569,6 +2604,8 @@ static int icmS15Fixed16Array_write( |
|
171 |
|
172 /* Allocate a file write buffer */ |
|
173 len = p->get_size((icmBase *)p); |
|
174 + if (icp->errc) |
|
175 + return icp->errc; |
|
176 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
177 sprintf(icp->err,"icmS15Fixed16Array_write malloc() failed"); |
|
178 return icp->errc = 2; |
|
179 @@ -2633,7 +2670,7 @@ static int icmS15Fixed16Array_allocate( |
|
180 if (p->size != p->_size) { |
|
181 if (p->data != NULL) |
|
182 icp->al->free(icp->al, p->data); |
|
183 - if ((p->data = (double *) icp->al->malloc(icp->al, p->size * sizeof(double))) == NULL) { |
|
184 + if ((p->data = (double *) icp->al->calloc(icp->al, p->size, sizeof(double))) == NULL) { |
|
185 sprintf(icp->err,"icmS15Fixed16Array_alloc: malloc() of icmS15Fixed16Array data failed"); |
|
186 return icp->errc = 2; |
|
187 } |
|
188 @@ -2726,6 +2763,10 @@ static unsigned int icmXYZArray_get_size |
|
189 icmXYZArray *p = (icmXYZArray *)pp; |
|
190 unsigned int len = 0; |
|
191 len += 8; /* 8 bytes for tag and padding */ |
|
192 + if (p->size > (UINT_MAX - len) / 12) { |
|
193 + p->icp->errc = 1; |
|
194 + return (unsigned int) - 1; |
|
195 + } |
|
196 len += p->size * 12; /* 12 bytes for each XYZ */ |
|
197 return len; |
|
198 } |
|
199 @@ -2798,6 +2839,8 @@ static int icmXYZArray_write( |
|
200 |
|
201 /* Allocate a file write buffer */ |
|
202 len = p->get_size((icmBase *)p); |
|
203 + if (icp->errc) |
|
204 + return icp->errc; |
|
205 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
206 sprintf(icp->err,"icmXYZArray_write malloc() failed"); |
|
207 return icp->errc = 2; |
|
208 @@ -2865,7 +2908,7 @@ static int icmXYZArray_allocate( |
|
209 if (p->size != p->_size) { |
|
210 if (p->data != NULL) |
|
211 icp->al->free(icp->al, p->data); |
|
212 - if ((p->data = (icmXYZNumber *) icp->al->malloc(icp->al, p->size * sizeof(icmXYZNumber))) == NULL) { |
|
213 + if ((p->data = (icmXYZNumber *) icp->al->calloc(icp->al, p->size, sizeof(icmXYZNumber))) == NULL) { |
|
214 sprintf(icp->err,"icmXYZArray_alloc: malloc() of icmXYZArray data failed"); |
|
215 return icp->errc = 2; |
|
216 } |
|
217 @@ -3001,7 +3044,7 @@ static int icmTable_setup_bwd( |
|
218 int nf; /* Next free slot */ |
|
219 if (rt->rlists[j] == NULL) { /* No allocation */ |
|
220 as = 5; /* Start with space for 5 */ |
|
221 - if ((rt->rlists[j] = (int *) icp->al->malloc(icp->al, sizeof(int) * as)) == NULL) { |
|
222 + if ((rt->rlists[j] = (int *) icp->al->calloc(icp->al, sizeof(int), as)) == NULL) { |
|
223 return 2; |
|
224 } |
|
225 rt->rlists[j][0] = as; |
|
226 @@ -3141,6 +3184,10 @@ static unsigned int icmCurve_get_size( |
|
227 icmCurve *p = (icmCurve *)pp; |
|
228 unsigned int len = 0; |
|
229 len += 12; /* 12 bytes for tag, padding and count */ |
|
230 + if (p->size > (UINT_MAX - len) / 2) { |
|
231 + p->icp->errc = 1; |
|
232 + return (unsigned int) - 1; |
|
233 + } |
|
234 len += p->size * 2; /* 2 bytes for each UInt16 */ |
|
235 return len; |
|
236 } |
|
237 @@ -3238,6 +3285,8 @@ static int icmCurve_write( |
|
238 |
|
239 /* Allocate a file write buffer */ |
|
240 len = p->get_size((icmBase *)p); |
|
241 + if (icp->errc) |
|
242 + return icp->errc; |
|
243 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
244 sprintf(icp->err,"icmCurve_write malloc() failed"); |
|
245 return icp->errc = 2; |
|
246 @@ -3347,7 +3396,7 @@ static int icmCurve_allocate( |
|
247 if (p->size != p->_size) { |
|
248 if (p->data != NULL) |
|
249 icp->al->free(icp->al, p->data); |
|
250 - if ((p->data = (double *) icp->al->malloc(icp->al, p->size * sizeof(double))) == NULL) { |
|
251 + if ((p->data = (double *) icp->al->calloc(icp->al, p->size, sizeof(double))) == NULL) { |
|
252 sprintf(icp->err,"icmCurve_alloc: malloc() of icmCurve data failed"); |
|
253 return icp->errc = 2; |
|
254 } |
|
255 @@ -3493,6 +3542,8 @@ static int icmData_write( |
|
256 |
|
257 /* Allocate a file write buffer */ |
|
258 len = p->get_size((icmBase *)p); |
|
259 + if (icp->errc) |
|
260 + return icp->errc; |
|
261 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
262 sprintf(icp->err,"icmData_write malloc() failed"); |
|
263 return icp->errc = 2; |
|
264 @@ -3745,6 +3796,8 @@ static int icmText_write( |
|
265 |
|
266 /* Allocate a file write buffer */ |
|
267 len = p->get_size((icmBase *)p); |
|
268 + if (icp->errc) |
|
269 + return icp->errc; |
|
270 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
271 sprintf(icp->err,"icmText_write malloc() failed"); |
|
272 return icp->errc = 2; |
|
273 @@ -4038,6 +4091,8 @@ static int icmDateTimeNumber_write( |
|
274 |
|
275 /* Allocate a file write buffer */ |
|
276 len = p->get_size((icmBase *)p); |
|
277 + if (icp->errc) |
|
278 + return icp->errc; |
|
279 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
280 sprintf(icp->err,"icmDateTimeNumber_write malloc() failed"); |
|
281 return icp->errc = 2; |
|
282 @@ -4128,11 +4183,15 @@ static icmBase *new_icmDateTimeNumber( |
|
283 /* icmLut object */ |
|
284 |
|
285 /* Utility function - raise one integer to an integer power */ |
|
286 -static unsigned int uipow(unsigned int a, unsigned int b) { |
|
287 +static int uipow(unsigned int a, unsigned int b, unsigned int *ret) { |
|
288 unsigned int rv = 1; |
|
289 - for (; b > 0; b--) |
|
290 + for (; b > 0; b--) { |
|
291 + if (a > 0 && rv > UINT_MAX / a) |
|
292 + return 1; |
|
293 rv *= a; |
|
294 - return rv; |
|
295 + } |
|
296 + *ret = rv; |
|
297 + return 0; |
|
298 } |
|
299 |
|
300 /* - - - - - - - - - - - - - - - - */ |
|
301 @@ -4268,7 +4327,7 @@ double *in /* Input array[outputChan] * |
|
302 if (p->inputChan <= 8) { |
|
303 gw = GW; /* Use stack allocation */ |
|
304 } else { |
|
305 - if ((gw = (double *) icp->al->malloc(icp->al, (1 << p->inputChan) * sizeof(double))) == NULL) { |
|
306 + if ((gw = (double *) icp->al->calloc(icp->al, (1 << p->inputChan), sizeof(double))) == NULL) { |
|
307 sprintf(icp->err,"icmLut_lookup_clut: malloc() failed"); |
|
308 return icp->errc = 2; |
|
309 } |
|
310 @@ -4819,19 +4878,50 @@ static unsigned int icmLut_get_size( |
|
311 ) { |
|
312 icmLut *p = (icmLut *)pp; |
|
313 unsigned int len = 0; |
|
314 + unsigned int pw; |
|
315 |
|
316 if (p->ttype == icSigLut8Type) { |
|
317 len += 48; /* tag and header */ |
|
318 + if (p->inputChan > 0 && |
|
319 + p->inputEnt > (UINT_MAX - len) / p->inputChan / 1) |
|
320 + goto overflow; |
|
321 + |
|
322 len += 1 * (p->inputChan * p->inputEnt); |
|
323 - len += 1 * (p->outputChan * uipow(p->clutPoints,p->inputChan)); |
|
324 + if (uipow(p->clutPoints,p->inputChan, &pw) || |
|
325 + (p->outputChan > 0 && |
|
326 + pw > (UINT_MAX - len) / p->outputChan / 1)) |
|
327 + goto overflow; |
|
328 + |
|
329 + len += 1 * (p->outputChan * pw); |
|
330 + if (p->outputChan > 0 && |
|
331 + p->outputEnt > (UINT_MAX - len) / p->outputChan / 1) |
|
332 + goto overflow; |
|
333 + |
|
334 len += 1 * (p->outputChan * p->outputEnt); |
|
335 } else { |
|
336 len += 52; /* tag and header */ |
|
337 + if (p->inputChan > 0 && |
|
338 + p->inputEnt > (UINT_MAX - len) / p->inputChan / 2) |
|
339 + goto overflow; |
|
340 + |
|
341 len += 2 * (p->inputChan * p->inputEnt); |
|
342 - len += 2 * (p->outputChan * uipow(p->clutPoints,p->inputChan)); |
|
343 + if (uipow(p->clutPoints,p->inputChan, &pw) || |
|
344 + (p->outputChan > 0 && |
|
345 + pw > (UINT_MAX - len) / p->outputChan / 2)) |
|
346 + goto overflow; |
|
347 + |
|
348 + len += 2 * (p->outputChan * pw); |
|
349 + if (p->outputChan > 0 && |
|
350 + p->outputEnt > (UINT_MAX - len) / p->outputChan / 2) |
|
351 + goto overflow; |
|
352 + |
|
353 len += 2 * (p->outputChan * p->outputEnt); |
|
354 } |
|
355 return len; |
|
356 + |
|
357 + overflow: |
|
358 + p->icp->errc = 1; |
|
359 + return (unsigned int) -1; |
|
360 } |
|
361 |
|
362 /* read the object, return 0 on success, error code on fail */ |
|
363 @@ -4844,6 +4934,7 @@ static int icmLut_read( |
|
364 icc *icp = p->icp; |
|
365 int rv = 0; |
|
366 unsigned long i, j, g, size; |
|
367 + unsigned int pw; |
|
368 char *bp, *buf; |
|
369 |
|
370 if (len < 4) { |
|
371 @@ -4904,6 +4995,11 @@ static int icmLut_read( |
|
372 return icp->errc = 1; |
|
373 } |
|
374 |
|
375 + if (p->clutPoints > 100) { |
|
376 + sprintf(icp->err,"icmLut_read: too many clutPoints"); |
|
377 + return icp->errc = 1; |
|
378 + } |
|
379 + |
|
380 /* Read 3x3 transform matrix */ |
|
381 for (j = 0; j < 3; j++) { /* Rows */ |
|
382 for (i = 0; i < 3; i++) { /* Columns */ |
|
383 @@ -4921,13 +5017,18 @@ static int icmLut_read( |
|
384 bp = buf+52; |
|
385 } |
|
386 |
|
387 - if (len < icmLut_get_size((icmBase *)p)) { |
|
388 + if (len < icmLut_get_size((icmBase *)p) || icp->errc) { |
|
389 sprintf(icp->err,"icmLut_read: Tag too small for contents"); |
|
390 icp->al->free(icp->al, buf); |
|
391 return icp->errc = 1; |
|
392 } |
|
393 |
|
394 /* Read the input tables */ |
|
395 + if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) { |
|
396 + sprintf(icp->err,"icmLut_read: overflow"); |
|
397 + icp->al->free(icp->al, buf); |
|
398 + return icp->errc = 1; |
|
399 + } |
|
400 size = (p->inputChan * p->inputEnt); |
|
401 if ((rv = p->allocate((icmBase *)p)) != 0) { |
|
402 icp->al->free(icp->al, buf); |
|
403 @@ -4942,7 +5043,14 @@ static int icmLut_read( |
|
404 } |
|
405 |
|
406 /* Read the clut table */ |
|
407 - size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); |
|
408 + if (uipow(p->clutPoints,p->inputChan,&pw) || |
|
409 + (p->outputChan > 0 && |
|
410 + pw > UINT_MAX / p->outputChan)) { |
|
411 + sprintf(icp->err,"icmLut_read: overflow"); |
|
412 + icp->al->free(icp->al, buf); |
|
413 + return icp->errc = 1; |
|
414 + } |
|
415 + size = (p->outputChan * pw); |
|
416 if ((rv = p->allocate((icmBase *)p)) != 0) { |
|
417 icp->al->free(icp->al, buf); |
|
418 return rv; |
|
419 @@ -4956,6 +5064,11 @@ static int icmLut_read( |
|
420 } |
|
421 |
|
422 /* Read the output tables */ |
|
423 + if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) { |
|
424 + sprintf(icp->err,"icmLut_read: overflow"); |
|
425 + icp->al->free(icp->al, buf); |
|
426 + return icp->errc = 1; |
|
427 + } |
|
428 size = (p->outputChan * p->outputEnt); |
|
429 if ((rv = p->allocate((icmBase *)p)) != 0) { |
|
430 icp->al->free(icp->al, buf); |
|
431 @@ -4995,12 +5108,14 @@ static int icmLut_write( |
|
432 icmLut *p = (icmLut *)pp; |
|
433 icc *icp = p->icp; |
|
434 unsigned long i,j; |
|
435 - unsigned int len, size; |
|
436 + unsigned int len, size, pw; |
|
437 char *bp, *buf; /* Buffer to write from */ |
|
438 int rv = 0; |
|
439 |
|
440 /* Allocate a file write buffer */ |
|
441 len = p->get_size((icmBase *)p); |
|
442 + if (icp->errc) |
|
443 + return icp->errc; |
|
444 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
445 sprintf(icp->err,"icmLut_write malloc() failed"); |
|
446 return icp->errc = 2; |
|
447 @@ -5066,6 +5181,11 @@ static int icmLut_write( |
|
448 } |
|
449 |
|
450 /* Write the input tables */ |
|
451 + if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) { |
|
452 + sprintf(icp->err,"icmLut_write: overflow"); |
|
453 + icp->al->free(icp->al, buf); |
|
454 + return icp->errc = 1; |
|
455 + } |
|
456 size = (p->inputChan * p->inputEnt); |
|
457 if (p->ttype == icSigLut8Type) { |
|
458 for (i = 0; i < size; i++, bp += 1) { |
|
459 @@ -5086,7 +5206,14 @@ static int icmLut_write( |
|
460 } |
|
461 |
|
462 /* Write the clut table */ |
|
463 - size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); |
|
464 + if (uipow(p->clutPoints,p->inputChan,&pw) || |
|
465 + (p->outputChan > 0 && |
|
466 + pw > UINT_MAX / p->outputChan)) { |
|
467 + sprintf(icp->err,"icmLut_write: overflow"); |
|
468 + icp->al->free(icp->al, buf); |
|
469 + return icp->errc = 1; |
|
470 + } |
|
471 + size = (p->outputChan * pw); |
|
472 if (p->ttype == icSigLut8Type) { |
|
473 for (i = 0; i < size; i++, bp += 1) { |
|
474 if ((rv = write_DCS8Number(p->clutTable[i], bp)) != 0) { |
|
475 @@ -5106,6 +5233,11 @@ static int icmLut_write( |
|
476 } |
|
477 |
|
478 /* Write the output tables */ |
|
479 + if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) { |
|
480 + sprintf(icp->err,"icmLut_write: overflow"); |
|
481 + icp->al->free(icp->al, buf); |
|
482 + return icp->errc = 1; |
|
483 + } |
|
484 size = (p->outputChan * p->outputEnt); |
|
485 if (p->ttype == icSigLut8Type) { |
|
486 for (i = 0; i < size; i++, bp += 1) { |
|
487 @@ -5177,7 +5309,14 @@ static void icmLut_dump( |
|
488 if (p->inputChan > MAX_CHAN) { |
|
489 fprintf(op," !!Can't dump > %d input channel CLUT table!!\n",MAX_CHAN); |
|
490 } else { |
|
491 - size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); |
|
492 + unsigned int pw; |
|
493 + if (uipow(p->clutPoints,p->inputChan,&pw) || |
|
494 + (p->outputChan > 0 && |
|
495 + pw > UINT_MAX / p->outputChan)) { |
|
496 + fprintf(op,"Would overflow.\n"); |
|
497 + return; |
|
498 + } |
|
499 + size = (p->outputChan * pw); |
|
500 for (j = 0; j < p->inputChan; j++) |
|
501 ii[j] = 0; |
|
502 for (i = 0; i < size;) { |
|
503 @@ -5216,7 +5355,7 @@ static void icmLut_dump( |
|
504 static int icmLut_allocate( |
|
505 icmBase *pp |
|
506 ) { |
|
507 - unsigned int i, j, g, size; |
|
508 + unsigned int i, j, g, size, pw; |
|
509 icmLut *p = (icmLut *)pp; |
|
510 icc *icp = p->icp; |
|
511 |
|
512 @@ -5231,6 +5370,10 @@ static int icmLut_allocate( |
|
513 return icp->errc = 1; |
|
514 } |
|
515 |
|
516 + if (p->inputEnt > 0 && p->inputChan > UINT_MAX / p->inputEnt) { |
|
517 + sprintf(icp->err,"icmLut_alloc: too many entries"); |
|
518 + return icp->errc = 1; |
|
519 + } |
|
520 size = (p->inputChan * p->inputEnt); |
|
521 if (size != p->inputTable_size) { |
|
522 if (p->inputTable != NULL) |
|
523 @@ -5241,7 +5384,13 @@ static int icmLut_allocate( |
|
524 } |
|
525 p->inputTable_size = size; |
|
526 } |
|
527 - size = (p->outputChan * uipow(p->clutPoints,p->inputChan)); |
|
528 + if (uipow(p->clutPoints,p->inputChan,&pw) || |
|
529 + (p->outputChan > 0 && |
|
530 + pw > UINT_MAX / p->outputChan)) { |
|
531 + sprintf(icp->err,"icmLut_alloc: overflow"); |
|
532 + return icp->errc = 1; |
|
533 + } |
|
534 + size = (p->outputChan * pw); |
|
535 if (size != p->clutTable_size) { |
|
536 if (p->clutTable != NULL) |
|
537 icp->al->free(icp->al, p->clutTable); |
|
538 @@ -5251,6 +5400,10 @@ static int icmLut_allocate( |
|
539 } |
|
540 p->clutTable_size = size; |
|
541 } |
|
542 + if (p->outputChan > 0 && p->outputEnt > UINT_MAX / p->outputChan) { |
|
543 + sprintf(icp->err,"icmLut_alloc: overflow"); |
|
544 + return icp->errc = 1; |
|
545 + } |
|
546 size = (p->outputChan * p->outputEnt); |
|
547 if (size != p->outputTable_size) { |
|
548 if (p->outputTable != NULL) |
|
549 @@ -5441,6 +5594,8 @@ static int icmMeasurement_write( |
|
550 |
|
551 /* Allocate a file write buffer */ |
|
552 len = p->get_size((icmBase *)p); |
|
553 + if (icp->errc) |
|
554 + return icp->errc; |
|
555 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
556 sprintf(icp->err,"icmMeasurement_write malloc() failed"); |
|
557 return icp->errc = 2; |
|
558 @@ -5712,13 +5867,20 @@ static unsigned int icmNamedColor_get_si |
|
559 len += p->nDeviceCoords * 1; /* bytes for each named color */ |
|
560 } |
|
561 } else { /* Named Color 2 */ |
|
562 + unsigned int col; |
|
563 len += 8; /* 8 bytes for tag and padding */ |
|
564 len += 4; /* 4 for vendor specific flags */ |
|
565 len += 4; /* 4 for count of named colors */ |
|
566 len += 4; /* 4 for number of device coords */ |
|
567 len += 32; /* 32 for prefix of color names */ |
|
568 len += 32; /* 32 for suffix of color names */ |
|
569 - len += p->count * (32 + 6 + p->nDeviceCoords * 2); /* bytes for each named color */ |
|
570 + col = 32 + 6 + p->nDeviceCoords * 2; |
|
571 + if (p->nDeviceCoords > (UINT_MAX - (32 + 6)) / 2 || |
|
572 + (p->count > 0 && col > (UINT_MAX - len) / p->count)) { |
|
573 + p->icp->errc = 1; |
|
574 + return (unsigned int) -1; |
|
575 + } |
|
576 + len += p->count * col; /* bytes for each named color */ |
|
577 } |
|
578 return len; |
|
579 } |
|
580 @@ -5882,6 +6044,8 @@ static int icmNamedColor_write( |
|
581 |
|
582 /* Allocate a file write buffer */ |
|
583 len = p->get_size((icmBase *)p); |
|
584 + if (icp->errc) |
|
585 + return icp->errc; |
|
586 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
587 sprintf(icp->err,"icmNamedColor_write malloc() failed"); |
|
588 return icp->errc = 2; |
|
589 @@ -6109,9 +6273,22 @@ static unsigned int icmTextDescription_g |
|
590 ) { |
|
591 icmTextDescription *p = (icmTextDescription *)pp; |
|
592 unsigned int len = 0; |
|
593 + if (p->size > UINT_MAX - (8 + 4 + 8)) { |
|
594 + p->icp->errc = 1; |
|
595 + return (unsigned int) -1; |
|
596 + } |
|
597 len += 8; /* 8 bytes for tag and padding */ |
|
598 len += 4 + p->size; /* Ascii string length + ascii string */ |
|
599 - len += 8 + 2 * p->ucSize; /* Unicode language code + length + string */ |
|
600 + len += 8; /* Unicode language code + length */ |
|
601 + if (p->ucSize > (UINT_MAX - len) / 2) { |
|
602 + p->icp->errc = 1; |
|
603 + return (unsigned int) -1; |
|
604 + } |
|
605 + len += 2 * p->ucSize; /* Unicode string */ |
|
606 + if (len > (UINT_MAX - (3 + 67))) { |
|
607 + p->icp->errc = 1; |
|
608 + return (unsigned int) -1; |
|
609 + } |
|
610 len += 3 + 67; /* ScriptCode code, length string */ |
|
611 return len; |
|
612 } |
|
613 @@ -6294,6 +6471,8 @@ static int icmTextDescription_write( |
|
614 |
|
615 /* Allocate a file write buffer */ |
|
616 len = p->get_size((icmBase *)p); |
|
617 + if (icp->errc) |
|
618 + return icp->errc; |
|
619 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
620 sprintf(icp->err,"icmTextDescription_write malloc() failed"); |
|
621 return icp->errc = 2; |
|
622 @@ -6544,7 +6723,7 @@ static int icmTextDescription_allocate( |
|
623 if (p->ucSize != p->uc_size) { |
|
624 if (p->ucDesc != NULL) |
|
625 icp->al->free(icp->al, p->ucDesc); |
|
626 - if ((p->ucDesc = (ORD16 *) icp->al->malloc(icp->al, p->ucSize * sizeof(ORD16))) == NULL) { |
|
627 + if ((p->ucDesc = (ORD16 *) icp->al->calloc(icp->al, p->ucSize, sizeof(ORD16))) == NULL) { |
|
628 sprintf(icp->err,"icmTextDescription_alloc: malloc() of Unicode description failed"); |
|
629 return icp->errc = 2; |
|
630 } |
|
631 @@ -6820,6 +6999,12 @@ static int icmProfileSequenceDesc_read( |
|
632 bp += 8; /* Skip padding */ |
|
633 |
|
634 p->count = read_UInt32Number(bp); /* Number of sequence descriptions */ |
|
635 + if (p->count > 1000) { |
|
636 + sprintf(icp->err,"icmProfileSequenceDesc_read: too many sequence descriptions"); |
|
637 + icp->al->free(icp->al, buf); |
|
638 + return icp->errc = 1; |
|
639 + } |
|
640 + |
|
641 bp += 4; |
|
642 |
|
643 /* Read all the sequence descriptions */ |
|
644 @@ -6852,6 +7037,8 @@ static int icmProfileSequenceDesc_write( |
|
645 |
|
646 /* Allocate a file write buffer */ |
|
647 len = p->get_size((icmBase *)p); |
|
648 + if (icp->errc) |
|
649 + return icp->errc; |
|
650 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
651 sprintf(icp->err,"icmProfileSequenceDesc_write malloc() failed"); |
|
652 return icp->errc = 2; |
|
653 @@ -6922,7 +7109,7 @@ static int icmProfileSequenceDesc_alloca |
|
654 if (p->count != p->_count) { |
|
655 if (p->data != NULL) |
|
656 icp->al->free(icp->al, p->data); |
|
657 - if ((p->data = (icmDescStruct *) icp->al->malloc(icp->al, p->count * sizeof(icmDescStruct))) == NULL) { |
|
658 + if ((p->data = (icmDescStruct *) icp->al->calloc(icp->al, p->count, sizeof(icmDescStruct))) == NULL) { |
|
659 sprintf(icp->err,"icmProfileSequenceDesc_allocate Allocation of DescStruct array failed"); |
|
660 return icp->errc = 2; |
|
661 } |
|
662 @@ -7041,6 +7228,8 @@ static int icmSignature_write( |
|
663 |
|
664 /* Allocate a file write buffer */ |
|
665 len = p->get_size((icmBase *)p); |
|
666 + if (icp->errc) |
|
667 + return icp->errc; |
|
668 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
669 sprintf(icp->err,"icmSignature_write malloc() failed"); |
|
670 return icp->errc = 2; |
|
671 @@ -7156,6 +7345,10 @@ static unsigned int icmScreening_get_siz |
|
672 icmScreening *p = (icmScreening *)pp; |
|
673 unsigned int len = 0; |
|
674 len += 16; /* 16 bytes for tag, padding, flag & channeles */ |
|
675 + if (p->channels > (UINT_MAX - len) / 12) { |
|
676 + p->icp->errc = 1; |
|
677 + return (unsigned int) -1; |
|
678 + } |
|
679 len += p->channels * 12; /* 12 bytes for each channel */ |
|
680 return len; |
|
681 } |
|
682 @@ -7235,6 +7428,8 @@ static int icmScreening_write( |
|
683 |
|
684 /* Allocate a file write buffer */ |
|
685 len = p->get_size((icmBase *)p); |
|
686 + if (icp->errc) |
|
687 + return icp->errc; |
|
688 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
689 sprintf(icp->err,"icmScreening_write malloc() failed"); |
|
690 return icp->errc = 2; |
|
691 @@ -7315,7 +7510,7 @@ static int icmScreening_allocate( |
|
692 if (p->channels != p->_channels) { |
|
693 if (p->data != NULL) |
|
694 icp->al->free(icp->al, p->data); |
|
695 - if ((p->data = (icmScreeningData *) icp->al->malloc(icp->al, p->channels * sizeof(icmScreeningData))) == NULL) { |
|
696 + if ((p->data = (icmScreeningData *) icp->al->calloc(icp->al, p->channels, sizeof(icmScreeningData))) == NULL) { |
|
697 sprintf(icp->err,"icmScreening_alloc: malloc() of icmScreening data failed"); |
|
698 return icp->errc = 2; |
|
699 } |
|
700 @@ -7366,10 +7561,20 @@ static unsigned int icmUcrBg_get_size( |
|
701 icmUcrBg *p = (icmUcrBg *)pp; |
|
702 unsigned int len = 0; |
|
703 len += 8; /* 8 bytes for tag and padding */ |
|
704 + if (p->UCRcount > (UINT_MAX - len - 4) / 2) |
|
705 + goto overflow; |
|
706 + |
|
707 len += 4 + p->UCRcount * 2; /* Undercolor Removal */ |
|
708 + if (p->BGcount > (UINT_MAX - len - 4 - p->size) / 2) |
|
709 + goto overflow; |
|
710 + |
|
711 len += 4 + p->BGcount * 2; /* Black Generation */ |
|
712 len += p->size; /* Description string */ |
|
713 return len; |
|
714 + |
|
715 + overflow: |
|
716 + p->icp->errc = 1; |
|
717 + return (unsigned int) -1; |
|
718 } |
|
719 |
|
720 /* read the object, return 0 on success, error code on fail */ |
|
721 @@ -7498,6 +7703,8 @@ static int icmUcrBg_write( |
|
722 |
|
723 /* Allocate a file write buffer */ |
|
724 len = p->get_size((icmBase *)p); |
|
725 + if (icp->errc) |
|
726 + return icp->errc; |
|
727 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
728 sprintf(icp->err,"icmUcrBg_write malloc() failed"); |
|
729 return icp->errc = 2; |
|
730 @@ -7663,7 +7870,7 @@ static int icmUcrBg_allocate( |
|
731 if (p->UCRcount != p->UCR_count) { |
|
732 if (p->UCRcurve != NULL) |
|
733 icp->al->free(icp->al, p->UCRcurve); |
|
734 - if ((p->UCRcurve = (double *) icp->al->malloc(icp->al, p->UCRcount * sizeof(double))) == NULL) { |
|
735 + if ((p->UCRcurve = (double *) icp->al->calloc(icp->al, p->UCRcount, sizeof(double))) == NULL) { |
|
736 sprintf(icp->err,"icmUcrBg_allocate: malloc() of UCR curve data failed"); |
|
737 return icp->errc = 2; |
|
738 } |
|
739 @@ -7672,7 +7879,7 @@ static int icmUcrBg_allocate( |
|
740 if (p->BGcount != p->BG_count) { |
|
741 if (p->BGcurve != NULL) |
|
742 icp->al->free(icp->al, p->BGcurve); |
|
743 - if ((p->BGcurve = (double *) icp->al->malloc(icp->al, p->BGcount * sizeof(double))) == NULL) { |
|
744 + if ((p->BGcurve = (double *) icp->al->calloc(icp->al, p->BGcount, sizeof(double))) == NULL) { |
|
745 sprintf(icp->err,"icmUcrBg_allocate: malloc() of BG curve data failed"); |
|
746 return icp->errc = 2; |
|
747 } |
|
748 @@ -7743,6 +7950,15 @@ static unsigned int icmVideoCardGamma_ge |
|
749 len += 2; /* 2 bytes for channels */ |
|
750 len += 2; /* 2 for entry count */ |
|
751 len += 2; /* 2 for entry size */ |
|
752 + if (p->u.table.entryCount > 0 && |
|
753 + p->u.table.entrySize > 0 && |
|
754 + p->u.table.channels > |
|
755 + (UINT_MAX - len) / |
|
756 + p->u.table.entryCount / |
|
757 + p->u.table.entrySize) { |
|
758 + p->icp->errc = 1; |
|
759 + return (unsigned int) -1; |
|
760 + } |
|
761 len += ( p->u.table.channels * /* compute table size */ |
|
762 p->u.table.entryCount * |
|
763 p->u.table.entrySize ); |
|
764 @@ -7762,10 +7978,11 @@ static int icmVideoCardGamma_read( |
|
765 ) { |
|
766 icmVideoCardGamma *p = (icmVideoCardGamma *)pp; |
|
767 icc *icp = p->icp; |
|
768 - int rv, c; |
|
769 + int rv; |
|
770 char *bp, *buf; |
|
771 unsigned char *pchar; |
|
772 unsigned short *pshort; |
|
773 + unsigned long c; |
|
774 |
|
775 if (len < 18) { |
|
776 sprintf(icp->err,"icmVideoCardGamma_read: Tag too small to be legal"); |
|
777 @@ -7803,6 +8020,16 @@ static int icmVideoCardGamma_read( |
|
778 p->u.table.channels = read_UInt16Number(bp+12); |
|
779 p->u.table.entryCount = read_UInt16Number(bp+14); |
|
780 p->u.table.entrySize = read_UInt16Number(bp+16); |
|
781 + if (p->u.table.entrySize > 65530 || p->u.table.entrySize == 0) { |
|
782 + sprintf(icp->err,"icmVideoCardGamma_read: Too many entries (or none)"); |
|
783 + return icp->errc = 1; |
|
784 + } |
|
785 + if (p->u.table.entryCount > 0 && p->u.table.entrySize > 0 && |
|
786 + p->u.table.channels > |
|
787 + UINT_MAX / p->u.table.entryCount / p->u.table.entrySize) { |
|
788 + sprintf(icp->err,"icmVideoCardGamma_read: Overflow reading tag"); |
|
789 + return icp->errc = 1; |
|
790 + } |
|
791 if (len-18 < p->u.table.channels*p->u.table.entryCount*p->u.table.entrySize) { |
|
792 sprintf(icp->err,"icmVideoCardGamma_read: Tag too small to be legal"); |
|
793 return icp->errc = 1; |
|
794 @@ -7871,6 +8098,8 @@ static int icmVideoCardGamma_write( |
|
795 |
|
796 /* Allocate a file write buffer */ |
|
797 len = p->get_size((icmBase *)p); |
|
798 + if (icp->errc) |
|
799 + return icp->errc; |
|
800 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
801 sprintf(icp->err,"icmViewingConditions_write malloc() failed"); |
|
802 return icp->errc = 2; |
|
803 @@ -8049,7 +8278,7 @@ static int icmVideoCardGamma_allocate( |
|
804 ) { |
|
805 icmVideoCardGamma *p = (icmVideoCardGamma *)pp; |
|
806 icc *icp = p->icp; |
|
807 - int size; |
|
808 + unsigned int size; |
|
809 |
|
810 /* note: allocation is only relevant for table type |
|
811 * and in that case the channels, entryCount, and entrySize |
|
812 @@ -8059,6 +8288,11 @@ static int icmVideoCardGamma_allocate( |
|
813 if (p->tagType == icmVideoCardGammaTableType) { |
|
814 if (p->u.table.data != NULL) |
|
815 icp->al->free(icp->al, p->u.table.data); |
|
816 + if (p->u.table.entryCount > 0 && |
|
817 + p->u.table.channels > UINT_MAX / p->u.table.entryCount) { |
|
818 + sprintf(icp->err,"icmVideoCardGamma_alloc: table too large"); |
|
819 + return icp->errc = 1; |
|
820 + } |
|
821 size = (p->u.table.channels * |
|
822 p->u.table.entryCount); |
|
823 switch (p->u.table.entrySize) { |
|
824 @@ -8066,6 +8300,10 @@ static int icmVideoCardGamma_allocate( |
|
825 size *= sizeof(unsigned char); |
|
826 break; |
|
827 case 2: |
|
828 + if (size > UINT_MAX / sizeof(unsigned short)) { |
|
829 + sprintf(icp->err,"icmVideoCardGamma_alloc: table too large"); |
|
830 + return icp->errc = 1; |
|
831 + } |
|
832 size *= sizeof(unsigned short); |
|
833 break; |
|
834 default: |
|
835 @@ -8201,6 +8439,8 @@ static int icmViewingConditions_write( |
|
836 |
|
837 /* Allocate a file write buffer */ |
|
838 len = p->get_size((icmBase *)p); |
|
839 + if (icp->errc) |
|
840 + return icp->errc; |
|
841 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
842 sprintf(icp->err,"icmViewingConditions_write malloc() failed"); |
|
843 return icp->errc = 2; |
|
844 @@ -8433,6 +8673,8 @@ static int icmCrdInfo_write( |
|
845 |
|
846 /* Allocate a file write buffer */ |
|
847 len = p->get_size((icmBase *)p); |
|
848 + if (icp->errc) |
|
849 + return icp->errc; |
|
850 if ((buf = (char *) icp->al->malloc(icp->al, len)) == NULL) { |
|
851 sprintf(icp->err,"icmCrdInfo_write malloc() failed"); |
|
852 return icp->errc = 2; |
|
853 @@ -8736,6 +8978,8 @@ static int icmHeader_write( |
|
854 int rv = 0; |
|
855 |
|
856 len = p->get_size(p); |
|
857 + if (icp->errc) |
|
858 + return icp->errc; |
|
859 if ((buf = (char *) icp->al->calloc(icp->al,1,len)) == NULL) { /* Zero it - some CMS are fussy */ |
|
860 sprintf(icp->err,"icmHeader_write calloc() failed"); |
|
861 return icp->errc = 2; |
|
862 @@ -9245,13 +9489,23 @@ static int icc_read( |
|
863 } |
|
864 |
|
865 p->count = read_UInt32Number(tcbuf); /* Tag count */ |
|
866 + if (p->count > 100) { |
|
867 + sprintf(p->err,"icc_read: too many table tags"); |
|
868 + return p->errc = 1; |
|
869 + } |
|
870 if (p->count > 0) { |
|
871 char *bp, *buf; |
|
872 - if ((p->data = (icmTag *) p->al->malloc(p->al, p->count * sizeof(icmTag))) == NULL) { |
|
873 + if ((p->data = (icmTag *) p->al->calloc(p->al, p->count, sizeof(icmTag))) == NULL) { |
|
874 sprintf(p->err,"icc_read: Tag table malloc() failed"); |
|
875 return p->errc = 2; |
|
876 } |
|
877 |
|
878 + if (p->count > (UINT_MAX - 4) / 12) { |
|
879 + sprintf(p->err,"icc_read: overflow"); |
|
880 + p->al->free(p->al, p->data); |
|
881 + p->data = NULL; |
|
882 + return p->errc = 1; |
|
883 + } |
|
884 len = 4 + p->count * 12; |
|
885 if ((buf = (char *) p->al->malloc(p->al, len)) == NULL) { |
|
886 sprintf(p->err,"icc_read: Tag table read buffer malloc() failed"); |
|
887 @@ -9281,6 +9535,14 @@ static int icc_read( |
|
888 return p->errc = 1; |
|
889 } |
|
890 p->data[i].size = read_UInt32Number(bp + 8); |
|
891 + if (p->data[i].offset + p->data[i].size > |
|
892 + p->header->size) { |
|
893 + sprintf(p->err,"icc_read: tag out of bounds"); |
|
894 + p->al->free(p->al, p->data); |
|
895 + p->data = NULL; |
|
896 + p->al->free(p->al, buf); |
|
897 + return p->errc = 1; |
|
898 + } |
|
899 if ( p->fp->seek(p->fp, of + p->data[i].offset) != 0 |
|
900 || p->fp->read(p->fp, tcbuf, 1, 4) != 4) { |
|
901 sprintf(p->err,"icc_read: fseek() or fread() failed on tag headers"); |
|
902 @@ -9321,8 +9583,14 @@ static unsigned int icc_get_size( |
|
903 } |
|
904 |
|
905 size += p->header->get_size(p->header); |
|
906 + if (p->errc) |
|
907 + return (unsigned int) -1; |
|
908 |
|
909 size = DO_ALIGN(size); |
|
910 + if (size == 0 || p->count > (UINT_MAX - 4 - size) / 12) { |
|
911 + p->errc = 1; |
|
912 + return (unsigned int) -1; |
|
913 + } |
|
914 size += 4 + p->count * 12; /* Tag table length */ |
|
915 |
|
916 /* Reset touched flag for each tag type */ |
|
917 @@ -9337,8 +9605,13 @@ static unsigned int icc_get_size( |
|
918 /* Get size for each tag type, skipping links */ |
|
919 for (i = 0; i < p->count; i++) { |
|
920 if (p->data[i].objp->touched == 0) { /* Not alllowed for previously */ |
|
921 + unsigned int obj_size; |
|
922 size = DO_ALIGN(size); |
|
923 - size += p->data[i].objp->get_size(p->data[i].objp); |
|
924 + obj_size = p->data[i].objp->get_size(p->data[i].objp); |
|
925 + if (size == 0 || p->errc || |
|
926 + obj_size > UINT_MAX - size) |
|
927 + return (unsigned int) -1; |
|
928 + size += obj_size; |
|
929 p->data[i].objp->touched = 1; /* Don't account for this again */ |
|
930 } |
|
931 } |
|
932 @@ -9373,9 +9646,19 @@ static int icc_write( |
|
933 } |
|
934 |
|
935 size += p->header->get_size(p->header); |
|
936 + if (p->errc) |
|
937 + return p->errc; |
|
938 |
|
939 + if (p->count > (UINT_MAX - 4 - len) / 12) { |
|
940 + sprintf(p->err,"icc_write: too many tags"); |
|
941 + return p->errc = 1; |
|
942 + } |
|
943 len = 4 + p->count * 12; /* Tag table length */ |
|
944 size = DO_ALIGN(size); |
|
945 + if (size == 0 || size > UINT_MAX - len) { |
|
946 + sprintf(p->err,"icc_write: overflow writing tag table"); |
|
947 + return p->errc = 1; |
|
948 + } |
|
949 size += len; |
|
950 |
|
951 /* Allocate memory buffer for tag table */ |
|
952 @@ -9406,6 +9689,12 @@ static int icc_write( |
|
953 size = DO_ALIGN(size); |
|
954 p->data[i].offset = size; /* Profile relative target */ |
|
955 p->data[i].size = p->data[i].objp->get_size(p->data[i].objp); |
|
956 + if (size == 0 || |
|
957 + p->errc || p->data[i].size > UINT_MAX - size) { |
|
958 + sprintf(p->err,"icc_write: internal error - overflow?"); |
|
959 + p->al->free(p->al, buf); |
|
960 + return p->errc; |
|
961 + } |
|
962 size += p->data[i].size; |
|
963 p->data[i].objp->touched = 1; /* Allocated space for it */ |
|
964 } else { /* must be linked - copy allocation */ |
|
965 @@ -9529,6 +9818,11 @@ static icmBase *icc_add_tag( |
|
966 } |
|
967 |
|
968 /* Make space in tag table for new tag item */ |
|
969 + if (p->count > (UINT_MAX / sizeof(icmTag)) - 1) { |
|
970 + sprintf(p->err,"icc_add_tag: overflow"); |
|
971 + p->errc = 1; |
|
972 + return NULL; |
|
973 + } |
|
974 if (p->data == NULL) |
|
975 tp = p->al->malloc(p->al, (p->count+1) * sizeof(icmTag)); |
|
976 else |
|
977 @@ -9612,6 +9906,11 @@ static icmBase *icc_link_tag( |
|
978 } |
|
979 |
|
980 /* Make space in tag table for new tag item */ |
|
981 + if (p->count > (UINT_MAX / sizeof(icmTag)) - 1) { |
|
982 + sprintf(p->err,"icc_link_tag: overflow"); |
|
983 + p->errc = 1; |
|
984 + return NULL; |
|
985 + } |
|
986 if (p->data == NULL) |
|
987 tp = p->al->malloc(p->al, (p->count+1) * sizeof(icmTag)); |
|
988 else |
|