[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