Browse code

Blame encoders not clamAV

git-svn: trunk@2927

Nigel Horne authored on 2007/03/10 09:34:19
Showing 2 changed files
... ...
@@ -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