git-svn: trunk@2927
Nigel Horne authored on 2007/03/10 09:34:19... | ... |
@@ -1,3 +1,9 @@ |
1 |
+Fri Mar 9 22:39:36 GMT 2007 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/pdf.c: When flatedecoder fails point out that the encoder |
|
4 |
+ was to blame for getting the length wrong, |
|
5 |
+ not clamAV |
|
6 |
+ |
|
1 | 7 |
Fri Mar 9 20:45:08 GMT 2007 (njh) |
2 | 8 |
---------------------------------- |
3 | 9 |
* libclamav/pdf.c: Bug 396 |
... | ... |
@@ -28,7 +34,7 @@ Thu Mar 8 20:34:36 EET 2007 (edwin) |
28 | 28 |
* libclamav/entitylist.h: new entitylist generated using |
29 | 29 |
contrib/entitynorm/generate_entitylist (bb #391) |
30 | 30 |
* libclamav/hashtab.c: fix bug in growing hash tables (must use hash on new |
31 |
- table) |
|
31 |
+ table) |
|
32 | 32 |
|
33 | 33 |
Thu Mar 8 12:22:36 CET 2007 (tk) |
34 | 34 |
--------------------------------- |
... | ... |
@@ -55,7 +55,7 @@ static char const rcsid[] = "$Id: pdf.c,v 1.61 2007/02/12 20:46:09 njh Exp $"; |
55 | 55 |
#include "pdf.h" |
56 | 56 |
|
57 | 57 |
#ifdef CL_DEBUG |
58 |
-#define SAVE_TMP /* Save the file being worked on in tmp */ |
|
58 |
+/*#define SAVE_TMP /* Save the file being worked on in tmp */ |
|
59 | 59 |
#endif |
60 | 60 |
|
61 | 61 |
static int try_flatedecode(unsigned char *buf, off_t real_len, off_t calculated_len, int fout, const cli_ctx *ctx); |
... | ... |
@@ -187,7 +187,7 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
187 | 187 |
while((p < xrefstart) && |
188 | 188 |
((q = pdf_nextobject(p, bytesleft)) != NULL) && |
189 | 189 |
(rc == CL_CLEAN)) { |
190 |
- int is_ascii85decode, is_flatedecode, fout, len; |
|
190 |
+ int is_ascii85decode, is_flatedecode, fout, len, has_cr; |
|
191 | 191 |
/*int object_number, generation_number;*/ |
192 | 192 |
const char *objstart, *objend, *streamstart, *streamend; |
193 | 193 |
char *md5digest; |
... | ... |
@@ -260,6 +260,36 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
260 | 260 |
length = atoi(q); |
261 | 261 |
while(isdigit(*q)) |
262 | 262 |
q++; |
263 |
+ /* |
|
264 |
+ * Note: incremental updates are not |
|
265 |
+ * supported |
|
266 |
+ */ |
|
267 |
+ if((bytesleft > 11) && strncmp(q, " 0 R", 4) == 0) { |
|
268 |
+ const char *r; |
|
269 |
+ char b[13]; |
|
270 |
+ |
|
271 |
+ q += 4; |
|
272 |
+ cli_dbgmsg("Length is in indirect obj %d\n", |
|
273 |
+ length); |
|
274 |
+ snprintf(b, sizeof(b), |
|
275 |
+ "%d 0 obj", length); |
|
276 |
+ length = strlen(b); |
|
277 |
+ r = cli_pmemstr(buf, size, b, |
|
278 |
+ length); |
|
279 |
+ if(r) { |
|
280 |
+ r += length - 1; |
|
281 |
+ r = pdf_nextobject(r, bytesleft - (r - q)); |
|
282 |
+ if(r) { |
|
283 |
+ length = atoi(r); |
|
284 |
+ while(isdigit(*r)) |
|
285 |
+ r++; |
|
286 |
+ cli_dbgmsg("length in '%s' %d\n", |
|
287 |
+ b, length); |
|
288 |
+ } |
|
289 |
+ } else |
|
290 |
+ cli_warnmsg("Couldn't find '%s'\n", |
|
291 |
+ b); |
|
292 |
+ } |
|
263 | 293 |
q--; |
264 | 294 |
} else if(strncmp(q, "Length2 ", 8) == 0) |
265 | 295 |
is_embedded_font = 1; |
... | ... |
@@ -316,12 +346,14 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
316 | 316 |
len -= (int)(q - streamstart); |
317 | 317 |
streamstart = q; |
318 | 318 |
streamend = cli_pmemstr(streamstart, len, "endstream\n", 10); |
319 |
+ has_cr = 0; |
|
319 | 320 |
if(streamend == NULL) { |
320 | 321 |
streamend = cli_pmemstr(streamstart, len, "endstream\r", 10); |
321 | 322 |
if(streamend == NULL) { |
322 | 323 |
cli_dbgmsg("No endstream\n"); |
323 | 324 |
break; |
324 | 325 |
} |
326 |
+ has_cr = 1; |
|
325 | 327 |
} |
326 | 328 |
snprintf(fullname, sizeof(fullname), "%s/pdfXXXXXX", dir); |
327 | 329 |
#if defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS) || defined(C_CYGWIN) |
... | ... |
@@ -357,14 +389,14 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
357 | 357 |
*/ |
358 | 358 |
if(*--streamend != '\n') |
359 | 359 |
streamend++; |
360 |
- else if(*--streamend != '\r') |
|
360 |
+ else if(has_cr && (*--streamend != '\r')) |
|
361 | 361 |
streamend++; |
362 | 362 |
|
363 | 363 |
if(streamend <= streamstart) { |
364 | 364 |
cli_dbgmsg("Empty stream\n"); |
365 | 365 |
continue; |
366 | 366 |
} |
367 |
- calculated_streamlen = (int)(streamend - streamstart) + 1; |
|
367 |
+ calculated_streamlen = (int)(streamend - streamstart); |
|
368 | 368 |
real_streamlen = length; |
369 | 369 |
|
370 | 370 |
if(calculated_streamlen != real_streamlen) |
... | ... |
@@ -461,7 +493,14 @@ try_flatedecode(unsigned char *buf, off_t real_len, off_t calculated_len, int fo |
461 | 461 |
if(real_len == calculated_len) |
462 | 462 |
return ret; |
463 | 463 |
|
464 |
- return flatedecode(buf, calculated_len, fout, ctx); |
|
464 |
+ ret = flatedecode(buf, calculated_len, fout, ctx); |
|
465 |
+ if(ret == Z_OK) |
|
466 |
+ return Z_OK; |
|
467 |
+ |
|
468 |
+ /* i.e. the PDF file is broken :-( */ |
|
469 |
+ cli_warnmsg("cli_pdf: Bad uncompressed block length in flate stream\n"); |
|
470 |
+ |
|
471 |
+ return ret; |
|
465 | 472 |
} |
466 | 473 |
|
467 | 474 |
static int |