diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-08-23 09:35:53 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-08-23 09:35:53 +0200 |
commit | d2b032452241708bee68d02aa02092cfbfba951a (patch) | |
tree | b3d7aa034e73c422933958522d8948b2e451e5e9 | |
parent | 2fb6d01cf03ea7142fe1759fc8241f55331bf876 (diff) | |
download | libextractor-d2b032452241708bee68d02aa02092cfbfba951a.tar.gz libextractor-d2b032452241708bee68d02aa02092cfbfba951a.zip |
fix #5846
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/plugins/dvi_extractor.c | 88 |
2 files changed, 48 insertions, 43 deletions
@@ -1,3 +1,6 @@ | |||
1 | Fri 23 Aug 2019 09:34:35 AM CEST | ||
2 | Fix invalid read for malformed DVI files (#5846). -CG | ||
3 | |||
1 | Mon 13 May 2019 07:42:19 AM CEST | 4 | Mon 13 May 2019 07:42:19 AM CEST |
2 | Consistently use AS_IF and AS_CASE in configure.ac. -CG | 5 | Consistently use AS_IF and AS_CASE in configure.ac. -CG |
3 | 6 | ||
diff --git a/src/plugins/dvi_extractor.c b/src/plugins/dvi_extractor.c index 268b48c..e3aa450 100644 --- a/src/plugins/dvi_extractor.c +++ b/src/plugins/dvi_extractor.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libextractor. | 2 | This file is part of libextractor. |
3 | Copyright (C) 2002, 2003, 2004, 2012, 2017 Vidyut Samanta and Christian Grothoff | 3 | Copyright (C) 2002, 2003, 2004, 2012, 2017, 2019 Vidyut Samanta and Christian Grothoff |
4 | 4 | ||
5 | libextractor is free software; you can redistribute it and/or modify | 5 | libextractor is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -182,6 +182,8 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
182 | size = ec->get_size (ec->cls); | 182 | size = ec->get_size (ec->cls); |
183 | if (size > 16 * 1024 * 1024) | 183 | if (size > 16 * 1024 * 1024) |
184 | return; /* too large */ | 184 | return; /* too large */ |
185 | if (klen + 15 > size) | ||
186 | return; /* malformed klen */ | ||
185 | if (NULL == (data = malloc ((size_t) size))) | 187 | if (NULL == (data = malloc ((size_t) size))) |
186 | return; /* out of memory */ | 188 | return; /* out of memory */ |
187 | memcpy (data, buf, iret); | 189 | memcpy (data, buf, iret); |
@@ -189,16 +191,16 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
189 | while (off < size) | 191 | while (off < size) |
190 | { | 192 | { |
191 | if (0 >= (iret = ec->read (ec->cls, &buf, 16 * 1024))) | 193 | if (0 >= (iret = ec->read (ec->cls, &buf, 16 * 1024))) |
192 | { | 194 | { |
193 | free (data); | 195 | free (data); |
194 | return; | 196 | return; |
195 | } | 197 | } |
196 | memcpy (&data[off], buf, iret); | 198 | memcpy (&data[off], buf, iret); |
197 | off += iret; | 199 | off += iret; |
198 | } | 200 | } |
199 | pos = size - 1; | 201 | pos = size - 1; |
200 | while ( (223 == data[pos]) && | 202 | while ( (223 == data[pos]) && |
201 | (pos > 0) ) | 203 | (pos > 0) ) |
202 | pos--; | 204 | pos--; |
203 | if ( (2 != data[pos]) || | 205 | if ( (2 != data[pos]) || |
204 | (pos < 40) ) | 206 | (pos < 40) ) |
@@ -225,9 +227,9 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
225 | break; | 227 | break; |
226 | if ( (pos + 45 > size) || | 228 | if ( (pos + 45 > size) || |
227 | (pos + 45 < pos) ) | 229 | (pos + 45 < pos) ) |
228 | goto CLEANUP; | 230 | goto CLEANUP; |
229 | if (data[pos] != 139) /* expect 'bop' */ | 231 | if (data[pos] != 139) /* expect 'bop' */ |
230 | goto CLEANUP; | 232 | goto CLEANUP; |
231 | pageCount++; | 233 | pageCount++; |
232 | opos = pos; | 234 | opos = pos; |
233 | pos = getIntAt (&data[opos + 41]); | 235 | pos = getIntAt (&data[opos + 41]); |
@@ -238,24 +240,24 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
238 | } | 240 | } |
239 | /* ok, now we believe it's a dvi... */ | 241 | /* ok, now we believe it's a dvi... */ |
240 | snprintf (pages, | 242 | snprintf (pages, |
241 | sizeof (pages), | 243 | sizeof (pages), |
242 | "%u", | 244 | "%u", |
243 | pageCount); | 245 | pageCount); |
244 | if (0 != ec->proc (ec->cls, | 246 | if (0 != ec->proc (ec->cls, |
245 | "dvi", | 247 | "dvi", |
246 | EXTRACTOR_METATYPE_PAGE_COUNT, | 248 | EXTRACTOR_METATYPE_PAGE_COUNT, |
247 | EXTRACTOR_METAFORMAT_UTF8, | 249 | EXTRACTOR_METAFORMAT_UTF8, |
248 | "text/plain", | 250 | "text/plain", |
249 | pages, | 251 | pages, |
250 | strlen (pages) + 1)) | 252 | strlen (pages) + 1)) |
251 | goto CLEANUP; | 253 | goto CLEANUP; |
252 | if (0 != ec->proc (ec->cls, | 254 | if (0 != ec->proc (ec->cls, |
253 | "dvi", | 255 | "dvi", |
254 | EXTRACTOR_METATYPE_MIMETYPE, | 256 | EXTRACTOR_METATYPE_MIMETYPE, |
255 | EXTRACTOR_METAFORMAT_UTF8, | 257 | EXTRACTOR_METAFORMAT_UTF8, |
256 | "text/plain", | 258 | "text/plain", |
257 | "application/x-dvi", | 259 | "application/x-dvi", |
258 | strlen ("application/x-dvi") + 1)) | 260 | strlen ("application/x-dvi") + 1)) |
259 | goto CLEANUP; | 261 | goto CLEANUP; |
260 | { | 262 | { |
261 | char comment[klen + 1]; | 263 | char comment[klen + 1]; |
@@ -263,18 +265,18 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
263 | comment[klen] = '\0'; | 265 | comment[klen] = '\0'; |
264 | memcpy (comment, &data[15], klen); | 266 | memcpy (comment, &data[15], klen); |
265 | if (0 != ec->proc (ec->cls, | 267 | if (0 != ec->proc (ec->cls, |
266 | "dvi", | 268 | "dvi", |
267 | EXTRACTOR_METATYPE_COMMENT, | 269 | EXTRACTOR_METATYPE_COMMENT, |
268 | EXTRACTOR_METAFORMAT_C_STRING, | 270 | EXTRACTOR_METAFORMAT_C_STRING, |
269 | "text/plain", | 271 | "text/plain", |
270 | comment, | 272 | comment, |
271 | klen + 1)) | 273 | klen + 1)) |
272 | goto CLEANUP; | 274 | goto CLEANUP; |
273 | } | 275 | } |
274 | /* try to find PDF/ps special */ | 276 | /* try to find PDF/ps special */ |
275 | pos = opos; | 277 | pos = opos; |
276 | while ( (size >= 100) && | 278 | while ( (size >= 100) && |
277 | (pos < size - 100) ) | 279 | (pos < size - 100) ) |
278 | { | 280 | { |
279 | switch (data[pos]) | 281 | switch (data[pos]) |
280 | { | 282 | { |
@@ -284,34 +286,34 @@ EXTRACTOR_dvi_extract_method (struct EXTRACTOR_ExtractContext *ec) | |||
284 | break; | 286 | break; |
285 | case 239: /* zzz1 */ | 287 | case 239: /* zzz1 */ |
286 | len = data[pos + 1]; | 288 | len = data[pos + 1]; |
287 | if (pos + 2 + len < size) | 289 | if ( (pos + 2 + len < size) && |
288 | if (0 != parseZZZ ((const char *) data, pos + 2, len, ec->proc, ec->cls)) | 290 | (0 != parseZZZ ((const char *) data, pos + 2, len, ec->proc, ec->cls)) ) |
289 | goto CLEANUP; | 291 | goto CLEANUP; |
290 | pos += len + 2; | 292 | pos += len + 2; |
291 | break; | 293 | break; |
292 | case 240: /* zzz2 */ | 294 | case 240: /* zzz2 */ |
293 | len = getShortAt (&data[pos + 1]); | 295 | len = getShortAt (&data[pos + 1]); |
294 | if (pos + 3 + len < size) | 296 | if ( (pos + 3 + len < size) && |
295 | if (0 != parseZZZ ((const char *) data, pos + 3, len, ec->proc, ec->cls)) | 297 | (0 != parseZZZ ((const char *) data, pos + 3, len, ec->proc, ec->cls)) ) |
296 | goto CLEANUP; | 298 | goto CLEANUP; |
297 | pos += len + 3; | 299 | pos += len + 3; |
298 | break; | 300 | break; |
299 | case 241: /* zzz3, who uses that? */ | 301 | case 241: /* zzz3, who uses that? */ |
300 | len = (getShortAt (&data[pos + 1])) + 65536 * data[pos + 3]; | 302 | len = (getShortAt (&data[pos + 1])) + 65536 * data[pos + 3]; |
301 | if (pos + 4 + len < size) | 303 | if ( (pos + 4 + len < size) && |
302 | if (0 != parseZZZ ((const char *) data, pos + 4, len, ec->proc, ec->cls)) | 304 | (0 != parseZZZ ((const char *) data, pos + 4, len, ec->proc, ec->cls)) ) |
303 | goto CLEANUP; | 305 | goto CLEANUP; |
304 | pos += len + 4; | 306 | pos += len + 4; |
305 | break; | 307 | break; |
306 | case 242: /* zzz4, hurray! */ | 308 | case 242: /* zzz4, hurray! */ |
307 | len = getIntAt (&data[pos + 1]); | 309 | len = getIntAt (&data[pos + 1]); |
308 | if (pos + 1 + len < size) | 310 | if ( (pos + 1 + len < size) && |
309 | if (0 != parseZZZ ((const char *) data, pos + 5, len, ec->proc, ec->cls)) | 311 | (0 != parseZZZ ((const char *) data, pos + 5, len, ec->proc, ec->cls)) ) |
310 | goto CLEANUP; | 312 | goto CLEANUP; |
311 | pos += len + 5; | 313 | pos += len + 5; |
312 | break; | 314 | break; |
313 | default: /* unsupported opcode, abort scan */ | 315 | default: /* unsupported opcode, abort scan */ |
314 | goto CLEANUP; | 316 | goto CLEANUP; |
315 | } | 317 | } |
316 | } | 318 | } |
317 | CLEANUP: | 319 | CLEANUP: |