[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Tomasz Kojm tkojm at clamav.net
Sun Apr 4 01:01:52 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit f461d74f2b2b8775d0fa8dc3ab28f29b432b8eee
Author: Tomasz Kojm <tkojm at clamav.net>
Date:   Mon Aug 24 22:09:38 2009 +0200

    libclamav: improve handling of PDF files (bb#1682)

diff --git a/ChangeLog b/ChangeLog
index 95e29ef..15fbf9a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Mon Aug 24 22:09:12 CEST 2009 (tk)
+----------------------------------
+ * libclamav: improve handling of PDF files (bb#1682)
+
 Fri Aug 21 15:53:35 CEST 2009 (tk)
 ----------------------------------
  * libclamav: handle relative offsets with cli_ac_data; fix offset logic
diff --git a/libclamav/pdf.c b/libclamav/pdf.c
index 5fa7230..51c1e44 100644
--- a/libclamav/pdf.c
+++ b/libclamav/pdf.c
@@ -57,6 +57,7 @@ static	char	const	rcsid[] = "$Id: pdf.c,v 1.61 2007/02/12 20:46:09 njh Exp $";
 #include "mbox.h"
 #include "pdf.h"
 #include "scanners.h"
+#include "str.h"
 
 #ifndef	O_BINARY
 #define	O_BINARY	0
@@ -72,7 +73,6 @@ static	int	flatedecode(unsigned char *buf, off_t len, int fout, cli_ctx *ctx);
 static	int	ascii85decode(const char *buf, off_t len, unsigned char *output);
 static	const	char	*pdf_nextlinestart(const char *ptr, size_t len);
 static	const	char	*pdf_nextobject(const char *ptr, size_t len);
-static	const	char	*cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns);
 
 int
 cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
@@ -87,6 +87,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 	int printed_predictor_message, printed_embedded_font_message, rc;
 	unsigned int files;
 	struct stat statb;
+	int opt_failed = 0;
 
 	cli_dbgmsg("in cli_pdf(%s)\n", dir);
 
@@ -145,7 +146,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 	 * q points to the end of the trailer section
 	 */
 	trailerlength = (long)(q - trailerstart);
-	if(cli_pmemstr(trailerstart, trailerlength, "Encrypt", 7)) {
+	if(cli_memstr(trailerstart, trailerlength, "Encrypt", 7)) {
 		/*
 		 * This tends to mean that the file is, in effect, read-only
 		 * http://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt
@@ -238,7 +239,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 
 		bytesleft -= (off_t)((q - p) + 3);
 		objstart = p = &q[3];
-		objend = cli_pmemstr(p, bytesleft, "endobj", 6);
+		objend = cli_memstr(p, bytesleft, "endobj", 6);
 		if(objend == NULL) {
 			cli_dbgmsg("cli_pdf: No matching endobj\n");
 			break;
@@ -248,7 +249,7 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 		objlen = (unsigned long)(objend - objstart);
 
 		/* Is this object a stream? */
-		streamstart = cli_pmemstr(objstart, objlen, "stream", 6);
+		streamstart = cli_memstr(objstart, objlen, "stream", 6);
 		if(streamstart == NULL)
 			continue;
 
@@ -274,7 +275,6 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 					 */
 					if((bytesleft > 11) && strncmp(q, " 0 R", 4) == 0) {
 						const char *r, *nq;
-						int opt_failed = 0;
 						size_t len;
 						char b[14];
 
@@ -286,10 +286,15 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 						length = (unsigned long)strlen(b);
 						/* optimization: assume objects
 						 * are sequential */
-						nq = q;
-						len = buf + size - q;
+						if(!opt_failed) {
+						    nq = q;
+						    len = buf + size - q;
+						} else {
+						    nq = buf;
+						    len = q - buf;
+						}
 						do {
-							r = cli_pmemstr(nq, len, b, length);
+							r = cli_memstr(nq, len, b, length);
 							if (r > nq) {
 								const char x = *(r-1);
 								if (x == '\n' || x=='\r') {
@@ -298,8 +303,8 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 								}
 							}
 							if (r) {
-								len -= r+1-nq;
-								nq = r + 1;
+								len -= r + length - nq;
+								nq = r + length;
 							} else if (!opt_failed) {
 								/* we failed optimized match,
 								 * try matching from the beginning
@@ -381,9 +386,9 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 			break;
 		len -= (int)(q - streamstart);
 		streamstart = q;
-		streamend = cli_pmemstr(streamstart, len, "endstream\n", 10);
+		streamend = cli_memstr(streamstart, len, "endstream\n", 10);
 		if(streamend == NULL) {
-			streamend = cli_pmemstr(streamstart, len, "endstream\r", 10);
+			streamend = cli_memstr(streamstart, len, "endstream\r", 10);
 			if(streamend == NULL) {
 				cli_dbgmsg("cli_pdf: No endstream\n");
 				break;
@@ -531,6 +536,10 @@ cli_pdf(const char *dir, int desc, cli_ctx *ctx, off_t offset)
 						rc = CL_EUNLINK;
 						break;
 					}
+					if(cli_updatelimits(ctx, real_streamlen) != CL_SUCCESS) {
+						rc = CL_CLEAN;
+						break;
+					}
 					continue;
 				} else
 					tableInsert(md5table, md5str, 1);
@@ -713,7 +722,7 @@ ascii85decode(const char *buf, off_t len, unsigned char *output)
 	int quintet = 0;
 	int ret = 0;
 
-	if(cli_pmemstr(buf, len, "~>", 2) == NULL)
+	if(cli_memstr(buf, len, "~>", 2) == NULL)
 		cli_dbgmsg("cli_pdf: ascii85decode: no EOF marker found\n");
 
 	ptr = buf;
@@ -842,45 +851,6 @@ pdf_nextobject(const char *ptr, size_t len)
 	return NULL;
 }
 
-/*
- * like cli_memstr - but returns the location of the match
- * FIXME: need a case insensitive version
- */
-static const char *
-cli_pmemstr(const char *haystack, size_t hs, const char *needle, size_t ns)
-{
-	const char *pt, *hay;
-	size_t n;
-
-	if(haystack == needle)
-		return haystack;
-
-	if(hs < ns)
-		return NULL;
-
-	if(memcmp(haystack, needle, ns) == 0)
-		return haystack;
-
-	pt = hay = haystack;
-	n = hs;
-
-	while((pt = memchr(hay, needle[0], n)) != NULL) {
-		n -= (size_t)(pt - hay);
-		if(n < ns)
-			break;
-
-		if(memcmp(pt, needle, ns) == 0)
-			return pt;
-
-		if(hay == pt) {
-			n--;
-			hay++;
-		} else
-			hay = pt;
-	}
-
-	return NULL;
-}
 #else	/*!HAVE_MMAP*/
 
 #include "clamav.h"
diff --git a/libclamav/str.c b/libclamav/str.c
index 220b844..d0d38b3 100644
--- a/libclamav/str.c
+++ b/libclamav/str.c
@@ -369,37 +369,33 @@ char *cli_strtokbuf(const char *input, int fieldno, const char *delim, char *out
     return output;
 }
 
-const char *cli_memstr(const char *haystack, int hs, const char *needle, int ns)
+const char *cli_memstr(const char *haystack, unsigned int hs, const char *needle, unsigned int ns)
 {
-	const char *pt, *hay;
-	int n;
+	unsigned int i, s1, s2;
 
-
-    if(hs < ns)
+    if(!hs || !ns || hs < ns)
 	return NULL;
 
-    if(haystack == needle)
-	return haystack;
-
-    if(!memcmp(haystack, needle, ns))
+    if(needle == haystack)
 	return haystack;
 
-    pt = hay = haystack;
-    n = hs;
+    if(ns == 1)
+	return memchr(haystack, needle[0], hs);
 
-    while((pt = memchr(hay, needle[0], n)) != NULL) {
-	n -= (int) (pt - hay);
-	if(n < ns)
-	    break;
-
-	if(!memcmp(pt, needle, ns))
-	    return pt;
-
-	if(hay == pt) {
-	    n--;
-	    hay++;
+    if(needle[0] == needle[1]) {
+	s1 = 2;
+	s2 = 1;
+    } else {
+	s1 = 1;
+	s2 = 2;
+    }
+    for(i = 0; i <= hs - ns; ) {
+	if(needle[1] != haystack[i + 1]) {
+	    i += s1;
 	} else {
-	    hay = pt;
+	    if((needle[0] == haystack[i]) && !memcmp(needle + 2, haystack + i + 2, ns - 2))
+		return &haystack[i];
+	    i += s2;
 	}
     }
 
diff --git a/libclamav/str.h b/libclamav/str.h
index 703d0eb..3fcb29e 100644
--- a/libclamav/str.h
+++ b/libclamav/str.h
@@ -42,7 +42,7 @@ int cli_hex2num(const char *hex);
 char *cli_str2hex(const char *string, unsigned int len);
 char *cli_utf16toascii(const char *str, unsigned int length);
 char *cli_strtokbuf(const char *input, int fieldno, const char *delim, char *output);
-const char *cli_memstr(const char *haystack, int hs, const char *needle, int ns);
+const char *cli_memstr(const char *haystack, unsigned int hs, const char *needle, unsigned int ns);
 char *cli_strrcpy(char *dest, const char *source);
 size_t cli_strtokenize(char *buffer, const char delim, const size_t token_count, const char **tokens);
 int cli_isnumber(const char *str);

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list