[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#770274: unblock: clamav/0.98.5+dfsg-1



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package clamav

This is your semi-standard (for clamav) release.  We already have the RC
in Jessie, so the diff (after removing docs and build cruft changes) is
only 10K lines.  Attached.  It does have one security issue fixed (didn't
realize this until after I uploaded it, so it's not in the changelog):

https://security-tracker.debian.org/tracker/CVE-2013-6497

Once this gets to testing, then I'll be able to upload for stable updates
too.

unblock clamav/0.98.5+dfsg-1
diff -Nru clamav-0.98.5~rc1+dfsg/ChangeLog clamav-0.98.5+dfsg/ChangeLog
--- clamav-0.98.5~rc1+dfsg/ChangeLog	2014-09-04 12:46:59.000000000 -0400
+++ clamav-0.98.5+dfsg/ChangeLog	2014-11-13 17:31:30.000000000 -0500
@@ -1,3 +1,23 @@
+Wed, 12 Nov 2014 14:30:39 EDT (swebb)
+-------------------------------------
+* bb11176 - Instruct OpenSSL to allow MD5 when in FIPS-compliant mode.
+  Patch submitted by Reinhard Max.
+
+Mon, 10 Nov 2014 11:03:29 EDT (swebb)
+-------------------------------------
+* bb11155 - Adjust the logic surrounding adjusting the PE section sizes
+  This fixes a crash with maliciously crafted yoda's crypter files and
+  also improves virus detections for PE files. 
+
+Thu, 6 Nov 2014 14:51:26 EDT (swebb)
+-------------------------------------
+* bb11088 - Merge in fixes for clamscan -a crash bug
+
+Mon, 20 Oct 2014 11:33:18 EDT (swebb)
+-------------------------------------
+* Revert "bb#10731 - Allow to specificy a group for the socket of which
+  the user is not a member"
+
 Thu, 31 Jul 2014 19:11:22 EDT (swebb)
 -------------------------------------
 * Add support for XDP PDF file format
diff -Nru clamav-0.98.5~rc1+dfsg/clamav-config.h.in clamav-0.98.5+dfsg/clamav-config.h.in
--- clamav-0.98.5~rc1+dfsg/clamav-config.h.in	2014-09-04 12:46:59.000000000 -0400
+++ clamav-0.98.5+dfsg/clamav-config.h.in	2014-11-13 17:31:30.000000000 -0500
@@ -191,6 +191,9 @@
 /* have getaddrinfo() */
 #undef HAVE_GETADDRINFO
 
+/* Define to 1 if you have the `getnameinfo' function. */
+#undef HAVE_GETNAMEINFO
+
 /* Define to 1 if getpagesize() is available */
 #undef HAVE_GETPAGESIZE
 
diff -Nru clamav-0.98.5~rc1+dfsg/clamav-milter/clamav-milter.c clamav-0.98.5+dfsg/clamav-milter/clamav-milter.c
--- clamav-0.98.5~rc1+dfsg/clamav-milter/clamav-milter.c	2014-09-03 17:26:52.000000000 -0400
+++ clamav-0.98.5+dfsg/clamav-milter/clamav-milter.c	2014-11-13 17:30:35.000000000 -0500
@@ -116,104 +116,6 @@
 	}
     }
 
-    if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
-	logg("!Please configure the MilterSocket directive\n");
-	logg_close();
-	optfree(opts);
-	return 1;
-    }
-
-    if(smfi_setconn(my_socket) == MI_FAILURE) {
-	logg("!smfi_setconn failed\n");
-	logg_close();
-	optfree(opts);
-	return 1;
-    }
-    if(smfi_register(descr) == MI_FAILURE) {
-	logg("!smfi_register failed\n");
-	logg_close();
-	optfree(opts);
-	return 1;
-    }
-    opt = optget(opts, "FixStaleSocket");
-    umsk = umask(0777); /* socket is created with 000 to avoid races */
-    if(smfi_opensocket(opt->enabled) == MI_FAILURE) {
-	logg("!Failed to create socket %s\n", my_socket);
-	logg_close();
-	optfree(opts);
-	return 1;
-    }
-    umask(umsk); /* restore umask */
-    if(strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) {
-	/* set group ownership and perms on the local socket */
-	char *sock_name = my_socket;
-	mode_t sock_mode;
-	if(!strncmp(my_socket, "unix:", 5))
-	    sock_name += 5;
-	if(!strncmp(my_socket, "local:", 6))
-	    sock_name += 6;
-	if(*my_socket == ':')
-	    sock_name ++;
-
-	if(optget(opts, "MilterSocketGroup")->enabled) {
-	    char *gname = optget(opts, "MilterSocketGroup")->strarg, *end;
-	    gid_t sock_gid = strtol(gname, &end, 10);
-	    if(*end) {
-		struct group *pgrp = getgrnam(gname);
-		if(!pgrp) {
-		    logg("!Unknown group %s\n", gname);
-		    logg_close();
-		    optfree(opts);
-		    return 1;
-		}
-		sock_gid = pgrp->gr_gid;
-	    }
-	    if(chown(sock_name, -1, sock_gid)) {
-		logg("!Failed to change socket ownership to group %s\n", gname);
-		logg_close();
-		optfree(opts);
-		return 1;
-	    }
-	}
-
-	if ((opt = optget(opts, "User"))->enabled) {
-	    struct passwd *user;
-	    if ((user = getpwnam(opt->strarg)) == NULL) {
-		logg("ERROR: Can't get information about user %s.\n",
-			opt->strarg);
-		logg_close();
-		optfree(opts);
-		return 1;
-	    }
-
-	    if(chown(sock_name, user->pw_uid, -1)) {
-		logg("!Failed to change socket ownership to user %s\n", user->pw_name);
-		optfree(opts);
-		logg_close();
-		return 1;
-	    }
-	}
-
-	if(optget(opts, "MilterSocketMode")->enabled) {
-	    char *end;
-	    sock_mode = strtol(optget(opts, "MilterSocketMode")->strarg, &end, 8);
-	    if(*end) {
-		logg("!Invalid MilterSocketMode %s\n", optget(opts, "MilterSocketMode")->strarg);
-		logg_close();
-		optfree(opts);
-		return 1;
-	    }
-	} else
-	    sock_mode = 0777 & ~umsk;
-
-	if(chmod(sock_name, sock_mode & 0666)) {
-	    logg("!Cannot set milter socket permission to %s\n", optget(opts, "MilterSocketMode")->strarg);
-	    logg_close();
-	    optfree(opts);
-	    return 1;
-	}
-    }
-
     if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
         struct passwd *user = NULL;
 	if((user = getpwnam(opt->strarg)) == NULL) {
@@ -346,6 +248,15 @@
 
     multircpt = optget(opts, "SupportMultipleRecipients")->enabled;
     
+    if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
+	logg("!Please configure the MilterSocket directive\n");
+	localnets_free();
+	whitelist_free();
+	logg_close();
+	optfree(opts);
+	return 1;
+    }
+
     if(!optget(opts, "Foreground")->enabled) {
 	if(daemonize() == -1) {
 	    logg("!daemonize() failed\n");
@@ -360,6 +271,92 @@
 	    logg("^Can't change current working directory to root\n");
     }
 
+    if(smfi_setconn(my_socket) == MI_FAILURE) {
+	logg("!smfi_setconn failed\n");
+	localnets_free();
+	whitelist_free();
+	logg_close();
+	optfree(opts);
+	return 1;
+    }
+    if(smfi_register(descr) == MI_FAILURE) {
+	logg("!smfi_register failed\n");
+	localnets_free();
+	whitelist_free();
+	logg_close();
+	optfree(opts);
+	return 1;
+    }
+    opt = optget(opts, "FixStaleSocket");
+    umsk = umask(0777); /* socket is created with 000 to avoid races */ 
+    if(smfi_opensocket(opt->enabled) == MI_FAILURE) {
+	logg("!Failed to create socket %s\n", my_socket);
+	localnets_free();
+	whitelist_free();
+	logg_close();
+	optfree(opts);
+	return 1;
+    }
+    umask(umsk); /* restore umask */
+    if(strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) {
+	/* set group ownership and perms on the local socket */
+	char *sock_name = my_socket;
+	mode_t sock_mode;
+	if(!strncmp(my_socket, "unix:", 5))
+	    sock_name += 5;
+	if(!strncmp(my_socket, "local:", 6))
+	    sock_name += 6;
+	if(*my_socket == ':')
+	    sock_name ++;
+
+	if(optget(opts, "MilterSocketGroup")->enabled) {
+	    char *gname = optget(opts, "MilterSocketGroup")->strarg, *end;
+	    gid_t sock_gid = strtol(gname, &end, 10);
+	    if(*end) {
+		struct group *pgrp = getgrnam(gname);
+		if(!pgrp) {
+		    logg("!Unknown group %s\n", gname);
+		    localnets_free();
+		    whitelist_free();
+		    logg_close();
+		    optfree(opts);
+		    return 1;
+		}
+		sock_gid = pgrp->gr_gid;
+	    }
+	    if(chown(sock_name, -1, sock_gid)) {
+		logg("!Failed to change socket ownership to group %s\n", gname);
+		localnets_free();
+		whitelist_free();
+		logg_close();
+		optfree(opts);
+		return 1;
+	    }
+	}
+	if(optget(opts, "MilterSocketMode")->enabled) {
+	    char *end;
+	    sock_mode = strtol(optget(opts, "MilterSocketMode")->strarg, &end, 8);
+	    if(*end) {
+		logg("!Invalid MilterSocketMode %s\n", optget(opts, "MilterSocketMode")->strarg);
+		localnets_free();
+		whitelist_free();
+		logg_close();
+		optfree(opts);
+		return 1;
+	    }
+	} else
+	    sock_mode = 0777 & ~umsk;
+
+	if(chmod(sock_name, sock_mode & 0666)) {
+	    logg("!Cannot set milter socket permission to %s\n", optget(opts, "MilterSocketMode")->strarg);
+	    localnets_free();
+	    whitelist_free();
+	    logg_close();
+	    optfree(opts);
+	    return 1;
+	}
+    }
+
     maxfilesize = optget(opts, "MaxFileSize")->numarg;
     if(!maxfilesize) {
 	logg("^Invalid MaxFileSize, using default (%d)\n", CLI_DEFAULT_MAXFILESIZE);
diff -Nru clamav-0.98.5~rc1+dfsg/clamd/server-th.c clamav-0.98.5+dfsg/clamd/server-th.c
--- clamav-0.98.5~rc1+dfsg/clamd/server-th.c	2014-09-03 17:26:52.000000000 -0400
+++ clamav-0.98.5+dfsg/clamd/server-th.c	2014-11-13 17:30:35.000000000 -0500
@@ -1441,6 +1441,7 @@
 	pthread_kill(fan_pid, SIGUSR1);
 	pthread_mutex_unlock(&logg_mutex);
 	pthread_join(fan_pid, NULL);
+    free(tharg);
     }
 #endif
     if(engine) {
diff -Nru clamav-0.98.5~rc1+dfsg/clamd/tcpserver.c clamav-0.98.5+dfsg/clamd/tcpserver.c
--- clamav-0.98.5~rc1+dfsg/clamd/tcpserver.c	2014-09-03 17:26:52.000000000 -0400
+++ clamav-0.98.5+dfsg/clamd/tcpserver.c	2014-11-13 17:30:35.000000000 -0500
@@ -49,6 +49,7 @@
 int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struct optstruct *opts)
 {
     struct addrinfo hints, *info, *p;
+    char host[NI_MAXHOST], serv[NI_MAXSERV];
     int *sockets;
     int sockfd, backlog;
     int *t;
@@ -66,19 +67,12 @@
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_flags = AI_PASSIVE;
 
-#if C_LINUX
-    if (!(ipaddr)) {
-        /*
-         * By default, getaddrinfo() will return 0.0.0.0 if NULL is passed in as the first parameter.
-         * Binding to 0.0.0.0 will prevent us from also binding IPv6 ::0 (errno = EADDRINUSE). However,
-         * if we bind to ::0 (or shorthand, ::), then Linux will bind to both IPv4 and IPv6.
-         */
-        ipaddr = "::";
-    }
+#ifdef AI_ADDRCONFIG
+    hints.ai_flags |= AI_ADDRCONFIG;
 #endif
 
     if ((res = getaddrinfo(ipaddr, port, &hints, &info))) {
-        logg("!TCP: getaddrinfo: %s\n", gai_strerror(res));
+        logg("!TCP: getaddrinfo failed: %s\n", gai_strerror(res));
         return -1;
     }
 
@@ -102,26 +96,41 @@
             logg("!TCP: setsocktopt(SO_REUSEADDR) error: %s\n", strerror(errno));
         }
 
+#ifdef IPV6_V6ONLY
+        if (p->ai_family == AF_INET6 &&
+            setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(yes)) == -1) {
+            estr = strerror(errno);
+            logg("!TCP: setsocktopt(IPV6_V6ONLY) error: %s\n", estr);
+        }
+#endif /* IPV6_V6ONLY */
+
+#ifdef HAVE_GETNAMEINFO
+        if ((res = getnameinfo(p->ai_addr, p->ai_addrlen, host, sizeof(host),
+                               serv, sizeof(serv), NI_NUMERICHOST|NI_NUMERICSERV))) {
+            logg("!TCP: getnameinfo failed: %s\n", gai_strerror(res));
+            host[0] = '\0';
+            serv[0] = '\0';
+        }
+#else
+        strncpy(host, ipaddr, sizeof(host));
+        host[sizeof(host)-1] = '\0';
+        snprintf(serv, sizeof(serv), "%u", (unsigned int)(optget(opts, "TCPSocket")->numarg));
+#endif
         if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
             estr = strerror(errno);
-            if (ipaddr || i == 0)
-                logg("!TCP: bind() error when trying to listen on [%s]:%s: %s\n", ipaddr, port, estr);
+            logg("!TCP: Cannot bind to [%s]:%s: %s\n", host, serv, estr);
             closesocket(sockfd);
 
             continue;
-        } else {
-            if((ipaddr))
-                logg("#TCP: Bound to address %s on port %u\n", ipaddr, (unsigned int) optget(opts, "TCPSocket")->numarg);
-            else
-                logg("#TCP: Bound to port %u\n", (unsigned int) optget(opts, "TCPSocket")->numarg);
         }
+        logg("#TCP: Bound to [%s]:%s\n", host, serv);
 
         backlog = optget(opts, "MaxConnectionQueueLength")->numarg;
         logg("#TCP: Setting connection queue length to %d\n", backlog);
 
         if(listen(sockfd, backlog) == -1) {
             estr = strerror(errno);
-            logg("!TCP: listen() error: %s\n", estr);
+            logg("!TCP: Cannot listen on [%s]:%s: %s\n", host, serv, estr);
             closesocket(sockfd);
 
             continue;
diff -Nru clamav-0.98.5~rc1+dfsg/clamscan/manager.c clamav-0.98.5+dfsg/clamscan/manager.c
--- clamav-0.98.5~rc1+dfsg/clamscan/manager.c	2014-10-02 17:24:09.000000000 -0400
+++ clamav-0.98.5+dfsg/clamscan/manager.c	2014-11-13 17:30:35.000000000 -0500
@@ -123,30 +123,36 @@
 
 struct metachain {
     char **chains;
-    unsigned lastadd;
-    unsigned lastvir;
-    unsigned level;
-    unsigned n;
+    size_t lastadd;
+    size_t lastvir;
+    size_t level;
+    size_t nchains;
 };
 
 static cl_error_t pre(int fd, const char *type, void *context)
 {
-    struct metachain *c = context;
+    struct metachain *c;
+
     UNUSEDPARAM(fd);
     UNUSEDPARAM(type);
 
-    if (c) {
-        c->level++;
-    }
+    if (!(context))
+        return CL_CLEAN;
+
+    c = (struct metachain *)context;
+
+    c->level++;
+
     return CL_CLEAN;
 }
 
-static int print_chain(struct metachain *c, char *str, unsigned len)
+static int print_chain(struct metachain *c, char *str, size_t len)
 {
-    unsigned i;
-    unsigned na = 0;
-    for (i=0;i<c->n-1;i++) {
-        unsigned int n = strlen(c->chains[i]);
+    size_t i;
+    size_t na = 0;
+
+    for (i=0;i<c->nchains-1;i++) {
+        size_t n = strlen(c->chains[i]);
 
         if (na)
             str[na++] = '!';
@@ -161,21 +167,23 @@
     str[na] = '\0';
     str[len-1] = '\0';
 
-    return i == c->n-1 ? 0 : 1;
+    return i == c->nchains-1 ? 0 : 1;
 }
 
 static cl_error_t post(int fd, int result, const char *virname, void *context)
 {
     struct metachain *c = context;
+    char str[128];
 
     UNUSEDPARAM(fd);
     UNUSEDPARAM(result);
 
-    if (c && c->n) {
-        char str[128];
+    if (c && c->nchains) {
         print_chain(c, str, sizeof(str));
+
         if (c->level == c->lastadd && !virname)
-            free(c->chains[--c->n]);
+            free(c->chains[--c->nchains]);
+
         if (virname && !c->lastvir)
             c->lastvir = c->level;
     }
@@ -187,12 +195,12 @@
 }
 
 static cl_error_t meta(const char* container_type, unsigned long fsize_container, const char *filename,
-		       unsigned long fsize_real,  int is_encrypted, unsigned int filepos_container, void *context)
+    unsigned long fsize_real,  int is_encrypted, unsigned int filepos_container, void *context)
 {
     char prev[128];
-    struct metachain *c = context;
-    const char *type = !strncmp(container_type,"CL_TYPE_",8) ? container_type + 8 : container_type;
-    unsigned n = strlen(type) + 1 + strlen(filename) + 1;
+    struct metachain *c;
+    const char *type;
+    size_t n;
     char *chain;
     char **chains;
     int toolong;
@@ -202,6 +210,10 @@
     UNUSEDPARAM(is_encrypted);
     UNUSEDPARAM(filepos_container);
 
+    c = (struct metachain *)context;
+    type = (strncmp(container_type, "CL_TYPE_", 8) == 0 ? container_type + 8 : container_type);
+    n = strlen(type) + strlen(filename) + 2;
+
     if (!c)
         return CL_CLEAN;
 
@@ -209,13 +221,14 @@
 
     if (!chain)
         return CL_CLEAN;
+
     if (!strcmp(type, "ANY"))
         snprintf(chain, n,"%s", filename);
     else
         snprintf(chain, n,"%s:%s", type, filename);
 
     if (c->lastadd != c->level) {
-        n = c->n + 1;
+        n = c->nchains + 1;
 
         chains = realloc(c->chains, n * sizeof(*chains));
         if (!chains) {
@@ -224,15 +237,20 @@
         }
 
         c->chains = chains;
-        c->n = n;
+        c->nchains = n;
         c->lastadd = c->level;
     } else {
-        free(c->chains[c->n-1]);
+        if (c->nchains > 0)
+            free(c->chains[c->nchains-1]);
     }
 
-    c->chains[c->n-1] = chain;
-    toolong = print_chain(c, prev, sizeof(prev));
-    logg("*Scanning %s%s!%s\n", prev,toolong ? "..." : "", chain);
+    if (c->nchains > 0) {
+        c->chains[c->nchains-1] = chain;
+        toolong = print_chain(c, prev, sizeof(prev));
+        logg("*Scanning %s%s!%s\n", prev,toolong ? "..." : "", chain);
+    } else {
+        free(chain);
+    }
 
     return CL_CLEAN;
 }
@@ -314,10 +332,10 @@
 
     memset(&chain, 0, sizeof(chain));
     if(optget(opts, "archive-verbose")->enabled) {
-        chain.chains = malloc(sizeof(*chain.chains));
+        chain.chains = malloc(sizeof(char **));
         if (chain.chains) {
             chain.chains[0] = strdup(filename);
-            chain.n = 1;
+            chain.nchains = 1;
         }
     }
 
@@ -336,13 +354,13 @@
             virname = virpp[0]; /* this is the first virus */
         }
         if(optget(opts, "archive-verbose")->enabled) {
-            if (chain.n > 1) {
+            if (chain.nchains > 1) {
                 char str[128];
                 int toolong = print_chain(&chain, str, sizeof(str));
 
-                logg("~%s%s!(%d)%s: %s FOUND\n", str, toolong ? "..." : "", chain.lastvir-1, chain.chains[chain.n-1], virname);
+                logg("~%s%s!(%u)%s: %s FOUND\n", str, toolong ? "..." : "", chain.lastvir-1, chain.chains[chain.nchains-1], virname);
             } else if (chain.lastvir) {
-                logg("~%s!(%d): %s FOUND\n", filename, chain.lastvir-1, virname);
+                logg("~%s!(%u): %s FOUND\n", filename, chain.lastvir-1, virname);
             }
         }
 
@@ -373,7 +391,7 @@
         info.errors++;
     }
 
-    for (i=0;i<chain.n;i++)
+    for (i=0;i<chain.nchains;i++)
         free(chain.chains[i]);
 
     free(chain.chains);
diff -Nru clamav-0.98.5~rc1+dfsg/config/test-driver clamav-0.98.5+dfsg/config/test-driver
--- clamav-0.98.5~rc1+dfsg/config/test-driver	1969-12-31 19:00:00.000000000 -0500
+++ clamav-0.98.5+dfsg/config/test-driver	2014-11-13 17:30:35.000000000 -0500
@@ -0,0 +1,127 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2012-06-27.10; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error.  This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+  echo "$0: $*" >&2
+  print_usage >&2
+  exit 2
+}
+
+print_usage ()
+{
+  cat <<END
+Usage:
+  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+              [--expect-failure={yes|no}] [--color-tests={yes|no}]
+              [--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+# TODO: better error handling in option parsing (in particular, ensure
+# TODO: $log_file, $trs_file and $test_name are defined).
+test_name= # Used for reporting.
+log_file=  # Where to save the output of the test script.
+trs_file=  # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+  case $1 in
+  --help) print_usage; exit $?;;
+  --version) echo "test-driver $scriptversion"; exit $?;;
+  --test-name) test_name=$2; shift;;
+  --log-file) log_file=$2; shift;;
+  --trs-file) trs_file=$2; shift;;
+  --color-tests) color_tests=$2; shift;;
+  --expect-failure) expect_failure=$2; shift;;
+  --enable-hard-errors) enable_hard_errors=$2; shift;;
+  --) shift; break;;
+  -*) usage_error "invalid option: '$1'";;
+  esac
+  shift
+done
+
+if test $color_tests = yes; then
+  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+  red='' # Red.
+  grn='' # Green.
+  lgn='' # Light green.
+  blu='' # Blue.
+  mgn='' # Magenta.
+  std=''     # No color.
+else
+  red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+  estatus=1
+fi
+
+case $estatus:$expect_failure in
+  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
+  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
+  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;
+  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;
+  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff -Nru clamav-0.98.5~rc1+dfsg/debian/changelog clamav-0.98.5+dfsg/debian/changelog
--- clamav-0.98.5~rc1+dfsg/debian/changelog	2014-11-13 19:31:09.000000000 -0500
+++ clamav-0.98.5+dfsg/debian/changelog	2014-11-20 01:02:46.000000000 -0500
@@ -1,3 +1,26 @@
+clamav (0.98.5+dfsg-1) unstable; urgency=medium
+
+  [ Sebastian Andrzej Siewior ]
+  * import new upsstream version, refresh patches:
+    dropped:
+     - LLVM-3.5-version-check-update.patch
+     - add-support-for-LLVM-3.5.patch
+     - fix-test-failure-on-powerpc-again.patch
+    updated:
+     - hardcode-LLVM-linker-flag-because-llvm-config-return
+     - added "bb-10731-Allow-to-specificy-a-group-for-the-socket-o" as
+       dependecy for "clamav-milter-add-additinal-SMFIF_-flags-before-invo"
+    (Closes: #763300)
+  * Add "Bump-.so-version-number", likely the RPM version of 769384.
+  * Add "llvm-don-t-use-system-libs", since we don't link against .a libs, we
+    don't need the deps either.
+
+  [ Scott Kitterman ]
+  * Update libclamav6: embedded-library lintian override for new libclamav6 so
+    version
+
+ -- Sebastian Andrzej Siewior <sebastian@breakpoint.cc>  Wed, 19 Nov 2014 22:28:22 +0100
+
 clamav (0.98.5~rc1+dfsg-4) unstable; urgency=medium
 
   * Bump the version requirement for the cl_retflevel symbol to 0.98.5~rc1,
diff -Nru clamav-0.98.5~rc1+dfsg/debian/libclamav6.lintian-overrides clamav-0.98.5+dfsg/debian/libclamav6.lintian-overrides
--- clamav-0.98.5~rc1+dfsg/debian/libclamav6.lintian-overrides	2014-10-18 11:57:20.000000000 -0400
+++ clamav-0.98.5+dfsg/debian/libclamav6.lintian-overrides	2014-11-20 01:02:00.000000000 -0500
@@ -1,4 +1,4 @@
 # This is sort of a false positive, because libclamav uses the packaged zlib.
 # It still embeds a modified version of zlib to support 64 bit decompression,
 # which is not part of zlib, see #308799.
-libclamav6 binary: embedded-library usr/lib/libclamav.so.6.1.22: zlib
+libclamav6 binary: embedded-library usr/lib/libclamav.so.6.1.24: zlib
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0010-hardcode-LLVM-linker-flag-because-llvm-config-return.patch clamav-0.98.5+dfsg/debian/patches/0010-hardcode-LLVM-linker-flag-because-llvm-config-return.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0010-hardcode-LLVM-linker-flag-because-llvm-config-return.patch	2014-10-18 11:57:20.000000000 -0400
+++ clamav-0.98.5+dfsg/debian/patches/0010-hardcode-LLVM-linker-flag-because-llvm-config-return.patch	2014-11-20 00:44:11.000000000 -0500
@@ -1,4 +1,4 @@
-From 61a3f531607948d4d821681789cf183cfb0c405b Mon Sep 17 00:00:00 2001
+From ff372c3f031462899b76beef71548b25fe78265a Mon Sep 17 00:00:00 2001
 From: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
 Date: Mon, 25 Aug 2014 22:54:37 +0200
 Subject: hardcode LLVM linker flag, because llvm-config returns only flags for
@@ -10,17 +10,17 @@
  1 file changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/libclamav/c++/configure.ac b/libclamav/c++/configure.ac
-index 1cadcda..aad7af3 100644
+index a6697ddd8e82..3c7c7e26fbf8 100644
 --- a/libclamav/c++/configure.ac
 +++ b/libclamav/c++/configure.ac
-@@ -76,8 +76,8 @@ AC_ARG_WITH([system-llvm], AC_HELP_STRING([--with-system-llvm],
- 
-      AC_SUBST(LLVMCONFIG_CXXFLAGS, [`$llvmconfig --cxxflags`])
-      AC_SUBST(LLVMCONFIG_LDFLAGS, [`$llvmconfig --ldflags`])
--     AC_SUBST(LLVMCONFIG_LIBS, [`$llvmconfig --libs jit nativecodegen scalaropts ipo`])
--     AC_SUBST(LLVMCONFIG_LIBFILES, [`$llvmconfig --libfiles jit nativecodegen scalaropts ipo`])
-+     AC_SUBST(LLVMCONFIG_LIBS, [-lLLVM-$llvmver])
-+     AC_SUBST(LLVMCONFIG_LIBFILES, [])
-      AC_MSG_NOTICE([Using external LLVM])
-      AC_MSG_NOTICE([CXXFLAGS from llvm-config: $LLVMCONFIG_CXXFLAGS])
-      AC_MSG_NOTICE([LDFLAGS from llvm-config: $LLVMCONFIG_LDFLAGS])
+@@ -121,8 +121,8 @@ if test "x$llvmconfig" != "x"; then
+     else
+         AC_SUBST(LLVMCONFIG_LDFLAGS, [`$llvmconfig --ldflags`])
+     fi
+-    AC_SUBST(LLVMCONFIG_LIBS, [`$llvmconfig --libs jit nativecodegen scalaropts ipo`])
+-    AC_SUBST(LLVMCONFIG_LIBFILES, [`$llvmconfig --libfiles jit nativecodegen scalaropts ipo`])
++    AC_SUBST(LLVMCONFIG_LIBS, [-lLLVM-$llvmver])
++    AC_SUBST(LLVMCONFIG_LIBFILES, [])
+     AC_MSG_NOTICE([CXXFLAGS from llvm-config: $LLVMCONFIG_CXXFLAGS])
+     AC_MSG_NOTICE([LDFLAGS from llvm-config: $LLVMCONFIG_LDFLAGS])
+     AC_MSG_NOTICE([LIBS from llvm-config: $LLVMCONFIG_LIBS])
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0015-bb-10731-Allow-to-specificy-a-group-for-the-socket-o.patch clamav-0.98.5+dfsg/debian/patches/0015-bb-10731-Allow-to-specificy-a-group-for-the-socket-o.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0015-bb-10731-Allow-to-specificy-a-group-for-the-socket-o.patch	1969-12-31 19:00:00.000000000 -0500
+++ clamav-0.98.5+dfsg/debian/patches/0015-bb-10731-Allow-to-specificy-a-group-for-the-socket-o.patch	2014-11-20 00:44:11.000000000 -0500
@@ -0,0 +1,229 @@
+From 7b31dd65f08c69533ab029f13abc338fe10e6c10 Mon Sep 17 00:00:00 2001
+From: Shawn Webb <swebb@sourcefire.com>
+Date: Thu, 31 Jul 2014 11:50:23 -0400
+Subject: bb#10731 - Allow to specificy a group for the socket of which the
+ user is not a member
+
+Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+---
+ clamav-milter/clamav-milter.c | 193 +++++++++++++++++++++---------------------
+ 1 file changed, 98 insertions(+), 95 deletions(-)
+
+diff --git a/clamav-milter/clamav-milter.c b/clamav-milter/clamav-milter.c
+index 2c7a4d7d3414..99e7fe7fac04 100644
+--- a/clamav-milter/clamav-milter.c
++++ b/clamav-milter/clamav-milter.c
+@@ -116,6 +116,104 @@ int main(int argc, char **argv) {
+ 	}
+     }
+ 
++    if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
++	logg("!Please configure the MilterSocket directive\n");
++	logg_close();
++	optfree(opts);
++	return 1;
++    }
++
++    if(smfi_setconn(my_socket) == MI_FAILURE) {
++	logg("!smfi_setconn failed\n");
++	logg_close();
++	optfree(opts);
++	return 1;
++    }
++    if(smfi_register(descr) == MI_FAILURE) {
++	logg("!smfi_register failed\n");
++	logg_close();
++	optfree(opts);
++	return 1;
++    }
++    opt = optget(opts, "FixStaleSocket");
++    umsk = umask(0777); /* socket is created with 000 to avoid races */
++    if(smfi_opensocket(opt->enabled) == MI_FAILURE) {
++	logg("!Failed to create socket %s\n", my_socket);
++	logg_close();
++	optfree(opts);
++	return 1;
++    }
++    umask(umsk); /* restore umask */
++    if(strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) {
++	/* set group ownership and perms on the local socket */
++	char *sock_name = my_socket;
++	mode_t sock_mode;
++	if(!strncmp(my_socket, "unix:", 5))
++	    sock_name += 5;
++	if(!strncmp(my_socket, "local:", 6))
++	    sock_name += 6;
++	if(*my_socket == ':')
++	    sock_name ++;
++
++	if(optget(opts, "MilterSocketGroup")->enabled) {
++	    char *gname = optget(opts, "MilterSocketGroup")->strarg, *end;
++	    gid_t sock_gid = strtol(gname, &end, 10);
++	    if(*end) {
++		struct group *pgrp = getgrnam(gname);
++		if(!pgrp) {
++		    logg("!Unknown group %s\n", gname);
++		    logg_close();
++		    optfree(opts);
++		    return 1;
++		}
++		sock_gid = pgrp->gr_gid;
++	    }
++	    if(chown(sock_name, -1, sock_gid)) {
++		logg("!Failed to change socket ownership to group %s\n", gname);
++		logg_close();
++		optfree(opts);
++		return 1;
++	    }
++	}
++
++	if ((opt = optget(opts, "User"))->enabled) {
++	    struct passwd *user;
++	    if ((user = getpwnam(opt->strarg)) == NULL) {
++		logg("ERROR: Can't get information about user %s.\n",
++			opt->strarg);
++		logg_close();
++		optfree(opts);
++		return 1;
++	    }
++
++	    if(chown(sock_name, user->pw_uid, -1)) {
++		logg("!Failed to change socket ownership to user %s\n", user->pw_name);
++		optfree(opts);
++		logg_close();
++		return 1;
++	    }
++	}
++
++	if(optget(opts, "MilterSocketMode")->enabled) {
++	    char *end;
++	    sock_mode = strtol(optget(opts, "MilterSocketMode")->strarg, &end, 8);
++	    if(*end) {
++		logg("!Invalid MilterSocketMode %s\n", optget(opts, "MilterSocketMode")->strarg);
++		logg_close();
++		optfree(opts);
++		return 1;
++	    }
++	} else
++	    sock_mode = 0777 & ~umsk;
++
++	if(chmod(sock_name, sock_mode & 0666)) {
++	    logg("!Cannot set milter socket permission to %s\n", optget(opts, "MilterSocketMode")->strarg);
++	    logg_close();
++	    optfree(opts);
++	    return 1;
++	}
++    }
++
+     if(geteuid() == 0 && (opt = optget(opts, "User"))->enabled) {
+         struct passwd *user = NULL;
+ 	if((user = getpwnam(opt->strarg)) == NULL) {
+@@ -248,15 +346,6 @@ int main(int argc, char **argv) {
+ 
+     multircpt = optget(opts, "SupportMultipleRecipients")->enabled;
+     
+-    if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
+-	logg("!Please configure the MilterSocket directive\n");
+-	localnets_free();
+-	whitelist_free();
+-	logg_close();
+-	optfree(opts);
+-	return 1;
+-    }
+-
+     if(!optget(opts, "Foreground")->enabled) {
+ 	if(daemonize() == -1) {
+ 	    logg("!daemonize() failed\n");
+@@ -271,92 +360,6 @@ int main(int argc, char **argv) {
+ 	    logg("^Can't change current working directory to root\n");
+     }
+ 
+-    if(smfi_setconn(my_socket) == MI_FAILURE) {
+-	logg("!smfi_setconn failed\n");
+-	localnets_free();
+-	whitelist_free();
+-	logg_close();
+-	optfree(opts);
+-	return 1;
+-    }
+-    if(smfi_register(descr) == MI_FAILURE) {
+-	logg("!smfi_register failed\n");
+-	localnets_free();
+-	whitelist_free();
+-	logg_close();
+-	optfree(opts);
+-	return 1;
+-    }
+-    opt = optget(opts, "FixStaleSocket");
+-    umsk = umask(0777); /* socket is created with 000 to avoid races */ 
+-    if(smfi_opensocket(opt->enabled) == MI_FAILURE) {
+-	logg("!Failed to create socket %s\n", my_socket);
+-	localnets_free();
+-	whitelist_free();
+-	logg_close();
+-	optfree(opts);
+-	return 1;
+-    }
+-    umask(umsk); /* restore umask */
+-    if(strncmp(my_socket, "inet:", 5) && strncmp(my_socket, "inet6:", 6)) {
+-	/* set group ownership and perms on the local socket */
+-	char *sock_name = my_socket;
+-	mode_t sock_mode;
+-	if(!strncmp(my_socket, "unix:", 5))
+-	    sock_name += 5;
+-	if(!strncmp(my_socket, "local:", 6))
+-	    sock_name += 6;
+-	if(*my_socket == ':')
+-	    sock_name ++;
+-
+-	if(optget(opts, "MilterSocketGroup")->enabled) {
+-	    char *gname = optget(opts, "MilterSocketGroup")->strarg, *end;
+-	    gid_t sock_gid = strtol(gname, &end, 10);
+-	    if(*end) {
+-		struct group *pgrp = getgrnam(gname);
+-		if(!pgrp) {
+-		    logg("!Unknown group %s\n", gname);
+-		    localnets_free();
+-		    whitelist_free();
+-		    logg_close();
+-		    optfree(opts);
+-		    return 1;
+-		}
+-		sock_gid = pgrp->gr_gid;
+-	    }
+-	    if(chown(sock_name, -1, sock_gid)) {
+-		logg("!Failed to change socket ownership to group %s\n", gname);
+-		localnets_free();
+-		whitelist_free();
+-		logg_close();
+-		optfree(opts);
+-		return 1;
+-	    }
+-	}
+-	if(optget(opts, "MilterSocketMode")->enabled) {
+-	    char *end;
+-	    sock_mode = strtol(optget(opts, "MilterSocketMode")->strarg, &end, 8);
+-	    if(*end) {
+-		logg("!Invalid MilterSocketMode %s\n", optget(opts, "MilterSocketMode")->strarg);
+-		localnets_free();
+-		whitelist_free();
+-		logg_close();
+-		optfree(opts);
+-		return 1;
+-	    }
+-	} else
+-	    sock_mode = 0777 & ~umsk;
+-
+-	if(chmod(sock_name, sock_mode & 0666)) {
+-	    logg("!Cannot set milter socket permission to %s\n", optget(opts, "MilterSocketMode")->strarg);
+-	    localnets_free();
+-	    whitelist_free();
+-	    logg_close();
+-	    optfree(opts);
+-	    return 1;
+-	}
+-    }
+-
+     maxfilesize = optget(opts, "MaxFileSize")->numarg;
+     if(!maxfilesize) {
+ 	logg("^Invalid MaxFileSize, using default (%d)\n", CLI_DEFAULT_MAXFILESIZE);
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0015-LLVM-3.5-version-check-update.patch clamav-0.98.5+dfsg/debian/patches/0015-LLVM-3.5-version-check-update.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0015-LLVM-3.5-version-check-update.patch	2014-10-18 11:57:20.000000000 -0400
+++ clamav-0.98.5+dfsg/debian/patches/0015-LLVM-3.5-version-check-update.patch	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-From 6411441e3866141660d412b7526387fca0a4a0ba Mon Sep 17 00:00:00 2001
-From: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
-Date: Tue, 14 Oct 2014 21:08:32 +0200
-Subject: LLVM 3.5 version check update
-
----
- libclamav/c++/configure.ac | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libclamav/c++/configure.ac b/libclamav/c++/configure.ac
-index 12ff0ff..4a2dece 100644
---- a/libclamav/c++/configure.ac
-+++ b/libclamav/c++/configure.ac
-@@ -109,9 +109,9 @@ if test "x$packaged_llvm" = "xyes"; then
- elif test $llvmver_test -lt 290; then
-     AC_MSG_RESULT([no ($llvmver)])
-     AC_MSG_ERROR([LLVM >= 2.9 required, but "$llvmver"($llvmver_test) found])
--elif test $llvmver_test -gt 342; then
-+elif test $llvmver_test -ge 360; then
-     AC_MSG_RESULT([no ($llvmver)])
--    AC_MSG_ERROR([LLVM <= 3.4.2 required, but "$llvmver"($llvmver_test) found])
-+    AC_MSG_ERROR([LLVM < 3.6 required, but "$llvmver"($llvmver_test) found])
- else
-     AC_MSG_RESULT([ok ($llvmver)])
- fi
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0016-add-support-for-LLVM-3.5.patch clamav-0.98.5+dfsg/debian/patches/0016-add-support-for-LLVM-3.5.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0016-add-support-for-LLVM-3.5.patch	2014-10-18 11:57:20.000000000 -0400
+++ clamav-0.98.5+dfsg/debian/patches/0016-add-support-for-LLVM-3.5.patch	1969-12-31 19:00:00.000000000 -0500
@@ -1,588 +0,0 @@
-From e94d068b6a0d76fa3d76bbf46dfd489e91a1bf32 Mon Sep 17 00:00:00 2001
-From: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
-Date: Tue, 14 Oct 2014 21:09:28 +0200
-Subject: add support for LLVM 3.5
-
----
- libclamav/c++/ClamBCRTChecks.cpp  | 78 +++++++++++++++++++++++++++----
- libclamav/c++/PointerTracking.cpp | 27 ++++++++++-
- libclamav/c++/PointerTracking.h   | 12 ++++-
- libclamav/c++/bytecode2llvm.cpp   | 98 +++++++++++++++++++++++++++++++++++----
- 4 files changed, 195 insertions(+), 20 deletions(-)
-
-diff --git a/libclamav/c++/ClamBCRTChecks.cpp b/libclamav/c++/ClamBCRTChecks.cpp
-index df014ef..5531ed3 100644
---- a/libclamav/c++/ClamBCRTChecks.cpp
-+++ b/libclamav/c++/ClamBCRTChecks.cpp
-@@ -29,13 +29,20 @@
- #include "llvm/ADT/PostOrderIterator.h"
- #include "llvm/ADT/SCCIterator.h"
- #include "llvm/Analysis/CallGraph.h"
--#include "llvm/Analysis/Verifier.h"
- #if LLVM_VERSION < 32
- #include "llvm/Analysis/DebugInfo.h"
--#else
-+#elif LLVM_VERSION < 35
- #include "llvm/DebugInfo.h"
-+#else
-+#include "llvm/IR/DebugInfo.h"
- #endif
-+#if LLVM_VERSION < 35
- #include "llvm/Analysis/Dominators.h"
-+#include "llvm/Analysis/Verifier.h"
-+#else
-+#include "llvm/IR/Dominators.h"
-+#include "llvm/IR/Verifier.h"
-+#endif
- #include "llvm/Analysis/ConstantFolding.h"
- #if LLVM_VERSION < 29
- //#include "llvm/Analysis/LiveValues.h" (unused)
-@@ -50,9 +57,14 @@
- #include "llvm/Config/config.h"
- #include "llvm/Pass.h"
- #include "llvm/Support/CommandLine.h"
-+#if LLVM_VERSION < 35
- #include "llvm/Support/DataFlow.h"
- #include "llvm/Support/InstIterator.h"
- #include "llvm/Support/GetElementPtrTypeIterator.h"
-+#else
-+#include "llvm/IR/InstIterator.h"
-+#include "llvm/IR/GetElementPtrTypeIterator.h"
-+#endif
- #include "llvm/ADT/DepthFirstIterator.h"
- #include "llvm/Transforms/Scalar.h"
- #include "llvm/Transforms/Utils/BasicBlockUtils.h"
-@@ -71,7 +83,6 @@
- #include "llvm/Intrinsics.h"
- #include "llvm/LLVMContext.h"
- #include "llvm/Module.h"
--#include "llvm/Support/InstVisitor.h"
- #else
- #include "llvm/IR/DerivedTypes.h"
- #include "llvm/IR/Instructions.h"
-@@ -79,7 +90,14 @@
- #include "llvm/IR/Intrinsics.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/Module.h"
-+#endif
-+
-+#if LLVM_VERSION < 33
-+#include "llvm/Support/InstVisitor.h"
-+#elif LLVM_VERSION < 35
- #include "llvm/InstVisitor.h"
-+#else
-+#include "llvm/IR/InstVisitor.h"
- #endif
- 
- #define DEFINEPASS(passname) passname() : FunctionPass(ID)
-@@ -103,10 +121,18 @@ namespace llvm {
-   private:
-       DenseSet<Function*> badFunctions;
-       std::vector<Instruction*> delInst;
-+#if LLVM_VERSION < 35
-       CallGraphNode *rootNode;
-+#else
-+      CallGraph *CG;
-+#endif
-   public:
-       static char ID;
-+#if LLVM_VERSION < 35
-       DEFINEPASS(PtrVerifier), rootNode(0), PT(), TD(), SE(), expander(),
-+#else
-+      DEFINEPASS(PtrVerifier), CG(0), PT(), TD(), SE(), expander(),
-+#endif
-           DT(), AbrtBB(), Changed(false), valid(false), EP() {
- #if LLVM_VERSION >= 29
-           initializePtrVerifierPass(*PassRegistry::getPassRegistry());
-@@ -133,12 +159,21 @@ namespace llvm {
-           AbrtBB = 0;
-           valid = true;
- 
-+#if LLVM_VERSION < 35
-           if (!rootNode) {
-               rootNode = getAnalysis<CallGraph>().getRoot();
-+#else
-+          if (!CG) {
-+              CG = &getAnalysis<CallGraphWrapperPass>().getCallGraph();
-+#endif
-               // No recursive functions for now.
-               // In the future we may insert runtime checks for stack depth.
-+#if LLVM_VERSION < 35
-               for (scc_iterator<CallGraphNode*> SCCI = scc_begin(rootNode),
-                        E = scc_end(rootNode); SCCI != E; ++SCCI) {
-+#else
-+              for (scc_iterator<CallGraph*> SCCI = scc_begin(CG); !SCCI.isAtEnd(); ++SCCI) {
-+#endif
-                   const std::vector<CallGraphNode*> &nextSCC = *SCCI;
-                   if (nextSCC.size() > 1 || SCCI.hasLoop()) {
-                       errs() << "INVALID: Recursion detected, callgraph SCC components: ";
-@@ -164,12 +199,19 @@ namespace llvm {
-           EP = &*It;
- #if LLVM_VERSION < 32
-           TD = &getAnalysis<TargetData>();
--#else
-+#elif LLVM_VERSION < 35
-           TD = &getAnalysis<DataLayout>();
-+#else
-+          DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
-+          TD = DLP ? &DLP->getDataLayout() : 0;
- #endif
-           SE = &getAnalysis<ScalarEvolution>();
-           PT = &getAnalysis<PointerTracking>();
-+#if LLVM_VERSION < 35
-           DT = &getAnalysis<DominatorTree>();
-+#else
-+          DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-+#endif
-           expander = new SCEVExpander(*SE OPT("SCEVexpander"));
- 
-           std::vector<Instruction*> insns;
-@@ -307,13 +349,23 @@ namespace llvm {
-       virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- #if LLVM_VERSION < 32
-           AU.addRequired<TargetData>();
--#else
-+#elif LLVM_VERSION < 35
-           AU.addRequired<DataLayout>();
-+#else
-+          AU.addRequired<DataLayoutPass>();
- #endif
-+#if LLVM_VERSION < 35
-           AU.addRequired<DominatorTree>();
-+#else
-+          AU.addRequired<DominatorTreeWrapperPass>();
-+#endif
-           AU.addRequired<ScalarEvolution>();
-           AU.addRequired<PointerTracking>();
-+#if LLVM_VERSION < 35
-           AU.addRequired<CallGraph>();
-+#else
-+          AU.addRequired<CallGraphWrapperPass>();
-+#endif
-       }
- 
-       bool isValid() const { return valid; }
-@@ -321,8 +373,10 @@ namespace llvm {
-       PointerTracking *PT;
- #if LLVM_VERSION < 32
-       TargetData *TD;
--#else
-+#elif LLVM_VERSION < 35
-       DataLayout *TD;
-+#else
-+      const DataLayout *TD;
- #endif
-       ScalarEvolution *SE;
-       SCEVExpander *expander;
-@@ -855,15 +909,23 @@ namespace llvm {
- INITIALIZE_PASS_BEGIN(PtrVerifier, "", "", false, false)
- #if LLVM_VERSION < 32
- INITIALIZE_PASS_DEPENDENCY(TargetData)
--#else
-+#elif LLVM_VERSION < 35
- INITIALIZE_PASS_DEPENDENCY(DataLayout)
-+#else
-+INITIALIZE_PASS_DEPENDENCY(DataLayoutPass)
- #endif
-+#if LLVM_VERSION < 35
- INITIALIZE_PASS_DEPENDENCY(DominatorTree)
-+#else
-+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-+#endif
- INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
- #if LLVM_VERSION < 34
- INITIALIZE_AG_DEPENDENCY(CallGraph)
--#else
-+#elif LLVM_VERSION < 35
- INITIALIZE_PASS_DEPENDENCY(CallGraph)
-+#else
-+INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
- #endif
- INITIALIZE_PASS_DEPENDENCY(PointerTracking)
- INITIALIZE_PASS_END(PtrVerifier, "clambc-rtchecks", "ClamBC RTchecks", false, false)
-diff --git a/libclamav/c++/PointerTracking.cpp b/libclamav/c++/PointerTracking.cpp
-index f88c7e0..8e17a4a 100644
---- a/libclamav/c++/PointerTracking.cpp
-+++ b/libclamav/c++/PointerTracking.cpp
-@@ -16,15 +16,19 @@
- #ifndef _WIN32
- 
- #include "llvm/Analysis/ConstantFolding.h"
--#include "llvm/Analysis/Dominators.h"
- #include "llvm/Analysis/LoopInfo.h"
- #include "llvm/Analysis/MemoryBuiltins.h"
- #include "llvm/Analysis/ValueTracking.h"
- #include "PointerTracking.h"
- #include "llvm/Analysis/ScalarEvolution.h"
- #include "llvm/Analysis/ScalarEvolutionExpressions.h"
-+#if LLVM_VERSION < 35
- #include "llvm/Support/CallSite.h"
- #include "llvm/Support/InstIterator.h"
-+#else
-+#include "llvm/IR/CallSite.h"
-+#include "llvm/IR/InstIterator.h"
-+#endif
- #include "llvm/Support/raw_ostream.h"
- #include "llvm/Target/TargetLibraryInfo.h"
- 
-@@ -61,10 +65,18 @@ namespace llvm {
- };
- INITIALIZE_PASS_BEGIN(PointerTracking, "pointertracking",
-                 "Track pointer bounds", false, true)
-+#if LLVM_VERSION < 35
- INITIALIZE_PASS_DEPENDENCY(DominatorTree)
-+#else
-+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-+#endif
- INITIALIZE_PASS_DEPENDENCY(LoopInfo)
- INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
-+#if LLVM_VERSION < 35
- INITIALIZE_PASS_DEPENDENCY(DominatorTree)
-+#else
-+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-+#endif
- INITIALIZE_PASS_END(PointerTracking, "pointertracking",
-                 "Track pointer bounds", false, true)
- #endif
-@@ -82,17 +94,28 @@ bool PointerTracking::runOnFunction(Function &F) {
-   FF = &F;
- #if LLVM_VERSION < 32
-   TD = getAnalysisIfAvailable<TargetData>();
--#else
-+#elif LLVM_VERSION < 35
-   TD = getAnalysisIfAvailable<DataLayout>();
-+#else
-+  DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
-+  TD = DLP ? &DLP->getDataLayout() : 0;
- #endif
-   SE = &getAnalysis<ScalarEvolution>();
-   LI = &getAnalysis<LoopInfo>();
-+#if LLVM_VERSION < 35
-   DT = &getAnalysis<DominatorTree>();
-+#else
-+  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-+#endif
-   return false;
- }
- 
- void PointerTracking::getAnalysisUsage(AnalysisUsage &AU) const {
-+#if LLVM_VERSION < 35
-   AU.addRequiredTransitive<DominatorTree>();
-+#else
-+  AU.addRequiredTransitive<DominatorTreeWrapperPass>();
-+#endif
-   AU.addRequiredTransitive<LoopInfo>();
-   AU.addRequiredTransitive<ScalarEvolution>();
-   AU.setPreservesAll();
-diff --git a/libclamav/c++/PointerTracking.h b/libclamav/c++/PointerTracking.h
-index a2f786c..6211800 100644
---- a/libclamav/c++/PointerTracking.h
-+++ b/libclamav/c++/PointerTracking.h
-@@ -28,9 +28,15 @@
- #define LLVM_ANALYSIS_POINTERTRACKING_H
- 
- #include "llvm/ADT/SmallPtrSet.h"
-+#if LLVM_VERSION < 35
- #include "llvm/Analysis/Dominators.h"
--#include "llvm/Pass.h"
- #include "llvm/Support/PredIteratorCache.h"
-+#else
-+#include "llvm/IR/Dominators.h"
-+#include "llvm/IR/PredIteratorCache.h"
-+#include "llvm/IR/DataLayout.h"
-+#endif
-+#include "llvm/Pass.h"
- #include "llvm30_compat.h"
- 
- #if LLVM_VERSION < 33
-@@ -117,8 +123,10 @@ namespace llvm {
-     Function *FF;
- #if LLVM_VERSION < 32
-     TargetData *TD;
--#else
-+#elif LLVM_VERSION < 35
-     DataLayout *TD;
-+#else
-+    const DataLayout *TD;
- #endif
-     ScalarEvolution *SE;
-     LoopInfo *LI;
-diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp
-index 8931977..2cc8a8c 100644
---- a/libclamav/c++/bytecode2llvm.cpp
-+++ b/libclamav/c++/bytecode2llvm.cpp
-@@ -44,8 +44,15 @@
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/Analysis/LoopInfo.h"
- #include "llvm/Analysis/ScalarEvolution.h"
-+#if LLVM_VERSION < 35
- #include "llvm/Analysis/Verifier.h"
- #include "llvm/AutoUpgrade.h"
-+#include "llvm/Support/TargetFolder.h"
-+#else
-+#include "llvm/IR/Verifier.h"
-+#include "llvm/IR/AutoUpgrade.h"
-+#include "llvm/Analysis/TargetFolder.h"
-+#endif
- #include "llvm/ExecutionEngine/ExecutionEngine.h"
- #include "llvm/ExecutionEngine/JIT.h"
- #include "llvm/ExecutionEngine/JITEventListener.h"
-@@ -100,15 +107,16 @@ void LLVMInitializePowerPCAsmPrinter();
- #endif
- 
- #include "llvm/Target/TargetOptions.h"
--#include "llvm/Support/TargetFolder.h"
- #include "llvm/Transforms/Scalar.h"
- #include "llvm/Transforms/IPO.h"
- #include "llvm/Transforms/Utils/BasicBlockUtils.h"
- 
- #if LLVM_VERSION < 32
- #include "llvm/Analysis/DebugInfo.h"
--#else
-+#elif LLVM_VERSION < 35
- #include "llvm/DebugInfo.h"
-+#else
-+#include "llvm/IR/DebugInfo.h"
- #endif
- 
- #if LLVM_VERSION < 32
-@@ -144,6 +152,10 @@ void LLVMInitializePowerPCAsmPrinter();
- #include "llvm/Analysis/CFG.h"
- #endif
- 
-+#if LLVM_VERSION >= 35
-+#include "llvm/IR/Dominators.h"
-+#endif
-+
- //#define TIMING
- #undef TIMING
- 
-@@ -657,7 +669,11 @@ public:
- 	}
- 	BBSetTy  needsTimeoutCheck;
- 	BBMapTy BBMap;
-+#if LLVM_VERSION < 35
- 	DominatorTree &DT = getAnalysis<DominatorTree>();
-+#else
-+	DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-+#endif
- 	for (Function::iterator I=F.begin(),E=F.end(); I != E; ++I) {
- 	    BasicBlock *BB = &*I;
- 	    unsigned apicalls = 0;
-@@ -784,7 +800,11 @@ public:
-       AU.setPreservesAll();
-       AU.addRequired<LoopInfo>();
-       AU.addRequired<ScalarEvolution>();
-+#if LLVM_VERSION < 35
-       AU.addRequired<DominatorTree>();
-+#else
-+      AU.addRequired<DominatorTreeWrapperPass>();
-+#endif
-     }
- };
- char RuntimeLimits::ID;
-@@ -1856,7 +1876,11 @@ public:
- 
- 	    // If successful so far, run verifyFunction
- 	    if (!broken) {
-+#if LLVM_VERSION < 35
- 		if (verifyFunction(*F, PrintMessageAction)) {
-+#else
-+		if (verifyFunction(*F, &errs())) {
-+#endif
- 		    // verification failed
- 		    broken = true;
- 		    cli_warnmsg("[Bytecode JIT]: Verification failed\n");
-@@ -1945,7 +1969,11 @@ public:
- 	ReturnInst::Create(Context, CI, BB);
- 
- 	delete [] Functions;
-+#if LLVM_VERSION < 35
- 	if (verifyFunction(*F, PrintMessageAction))
-+#else
-+	if (verifyFunction(*F, &errs()))
-+#endif
- 	    return 0;
- 
- /*			DEBUG(errs() << "Generating code\n");
-@@ -2125,7 +2153,11 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
- INITIALIZE_PASS_BEGIN(RuntimeLimits, "rl", "Runtime Limits", false, false)
- INITIALIZE_PASS_DEPENDENCY(LoopInfo)
- INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
-+#if LLVM_VERSION < 35
- INITIALIZE_PASS_DEPENDENCY(DominatorTree)
-+#else
-+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-+#endif
- INITIALIZE_PASS_END(RuntimeLimits, "rl" ,"Runtime Limits", false, false)
- #endif
- 
-@@ -2341,16 +2373,20 @@ static void setGuard(unsigned char* guardbuf)
- }
- #if LLVM_VERSION < 32
- static void addFPasses(FunctionPassManager &FPM, bool trusted, const TargetData *TD)
--#else
-+#elif LLVM_VERSION < 35
- static void addFPasses(FunctionPassManager &FPM, bool trusted, const DataLayout *TD)
-+#else
-+static void addFPasses(FunctionPassManager &FPM, bool trusted, const Module *M)
- #endif
- {
-     // Set up the optimizer pipeline.  Start with registering info about how
-     // the target lays out data structures.
- #if LLVM_VERSION < 32
-     FPM.add(new TargetData(*TD));
--#else
-+#elif LLVM_VERSION < 35
-     FPM.add(new DataLayout(*TD));
-+#else
-+    FPM.add(new DataLayoutPass(M));
- #endif
-     // Promote allocas to registers.
-     FPM.add(createPromoteMemoryToRegisterPass());
-@@ -2428,9 +2464,12 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
- #if LLVM_VERSION < 32
- 	addFPasses(OurFPM, true, EE->getTargetData());
- 	addFPasses(OurFPMUnsigned, false, EE->getTargetData());
--#else
-+#elif LLVM_VERSION < 35
- 	addFPasses(OurFPM, true, EE->getDataLayout());
- 	addFPasses(OurFPMUnsigned, false, EE->getDataLayout());
-+#else
-+	addFPasses(OurFPM, true, M);
-+	addFPasses(OurFPMUnsigned, false, M);
- #endif
- 
- 
-@@ -2541,8 +2580,10 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
- 	PassManager PM;
- #if LLVM_VERSION < 32
- 	PM.add(new TargetData(*EE->getTargetData()));
--#else
-+#elif LLVM_VERSION < 35
- 	PM.add(new DataLayout(*EE->getDataLayout()));
-+#else
-+	PM.add(new DataLayoutPass(M));
- #endif
- 	// TODO: only run this on the untrusted bytecodes, not all of them...
- 	if (has_untrusted)
-@@ -2601,10 +2642,17 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
- int bytecode_init(void)
- {
-     // If already initialized return
-+#if LLVM_VERSION < 35
-     if (llvm_is_multithreaded()) {
- 	cli_warnmsg("bytecode_init: already initialized\n");
- 	return CL_EARG;
-     }
-+#else
-+    if (!LLVMIsMultithreaded()) {
-+        cli_warnmsg("bytecode_init: LLVM is compiled without multithreading support\n");
-+    }
-+#endif
-+
-     llvm_install_error_handler(llvm_error_handler);
- #ifdef CL_DEBUG
-     sys::PrintStackTraceOnErrorSignal();
-@@ -2628,7 +2676,11 @@ int bytecode_init(void)
- #endif
-     llvm::DwarfExceptionHandling = false;
- #endif
-+#if LLVM_VERSION < 33
-     llvm_start_multithreaded();
-+#else
-+    // This is now deprecated/useless: Multi-threading can only be enabled/disabled with the compile time define LLVM_ENABLE_THREADS in LLVM.
-+#endif
- 
-     // If we have a native target, initialize it to ensure it is linked in and
-     // usable by the JIT.
-@@ -2638,7 +2690,11 @@ int bytecode_init(void)
-     InitializeAllTargets();
- #endif
- 
-+#if LLVM_VERSION < 35
-     if (!llvm_is_multithreaded()) {
-+#else
-+    if (!LLVMIsMultithreaded()) {
-+#endif
- 	//TODO:cli_dbgmsg
- 	DEBUG(errs() << "WARNING: ClamAV JIT built w/o atomic builtins\n"
- 	      << "On x86 for best performance ClamAV should be built for i686, not i386!\n");
-@@ -2710,7 +2766,7 @@ void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx)
- 	std::string ErrorMessage;
- #if LLVM_VERSION < 29
- 	lines->buffer = MemoryBuffer::getFile(path, &ErrorMessage);
--#else
-+#elif LLVM_VERSION < 35
- 	OwningPtr<MemoryBuffer> File;
- 	error_code ec = MemoryBuffer::getFile(path, File);
- 	if (ec) {
-@@ -2718,6 +2774,15 @@ void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx)
- 	    lines->buffer = 0;
- 	} else
- 	    lines->buffer = File.take();
-+#else
-+	ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = MemoryBuffer::getFile(path);
-+	if (!FileOrErr) {
-+		// TODO: How to handle ErrorMessage?
-+		lines->buffer = 0;
-+	}
-+	else {
-+		lines->buffer = FileOrErr.get().release();
-+	}
- #endif
- 	if (!lines->buffer) {
- 	    errs() << "Unable to open file '" << path << "'\n";
-@@ -2863,7 +2928,10 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
-   StringRef G;
-   StringRef H;
- #endif
-+#if LLVM_VERSION < 35
-   DIType TypeD;
-+#endif
-+  StringRef T;
- 
-   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) {
-     Value *DIGV = findDbgGlobalDeclare(GV);
-@@ -2880,7 +2948,11 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
-     G = Var.getFilename();
-     H = Var.getDirectory();
- #endif
-+#if LLVM_VERSION < 35
-     TypeD = Var.getType();
-+#else
-+    T = Var.getType().getName();
-+#endif
-   } else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){
-     Value *DIF = findDbgSubprogramDeclare(F);
-     if (!DIF) return false;
-@@ -2896,7 +2968,11 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
-     G = Var.getFilename();
-     H = Var.getDirectory();
- #endif
-+#if LLVM_VERSION < 35
-     TypeD = Var.getType();
-+#else
-+    T = Var.getType().getName();
-+#endif
-   } else {
-     const DbgDeclareInst *DDI = findDbgDeclare(V);
-     if (!DDI) return false;
-@@ -2913,10 +2989,16 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
-     G = StringRef();
-     H = StringRef();
- #endif
-+#if LLVM_VERSION < 35
-     TypeD = Var.getType();
-+#else
-+    T = Var.getType().getName();
-+#endif
-   }
- 
--  StringRef T = TypeD.getName();
-+#if LLVM_VERSION < 35
-+  T = TypeD.getName();
-+#endif
-   if (!T.empty())
-     Type = T;
- #if LLVM_VERSION < 33
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0016-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch clamav-0.98.5+dfsg/debian/patches/0016-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0016-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch	1969-12-31 19:00:00.000000000 -0500
+++ clamav-0.98.5+dfsg/debian/patches/0016-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch	2014-11-20 00:44:11.000000000 -0500
@@ -0,0 +1,86 @@
+From 7a06cb7ef2dd9847ae82727b5f49a6613f5bdcb3 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Date: Sun, 26 Oct 2014 12:11:09 +0100
+Subject: clamav-milter: add additinal SMFIF_* flags before invoking
+ smfi_register()
+
+unfortunately after the shifting of the code (so that the socket could
+be part of a group which is not part of the clamav user) I forgot (or
+did not see it) to have the header flags added before the
+smfi_register() was invoked. As a result the socket was working but it
+was unable to add the X-Virus-Scanned &  X-Virus-Status flags. This
+patch fixes the issue.
+
+https://bugzilla.clamav.net/show_bug.cgi?id=10731
+
+Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+---
+ clamav-milter/clamav-milter.c | 48 ++++++++++++++++++++++++-------------------
+ 1 file changed, 27 insertions(+), 21 deletions(-)
+
+diff --git a/clamav-milter/clamav-milter.c b/clamav-milter/clamav-milter.c
+index 99e7fe7fac04..22db98ab7c5e 100644
+--- a/clamav-milter/clamav-milter.c
++++ b/clamav-milter/clamav-milter.c
+@@ -116,6 +116,33 @@ int main(int argc, char **argv) {
+ 	}
+     }
+ 
++    pt = optget(opts, "AddHeader")->strarg;
++    if (strcasecmp(pt, "No")) {
++	char myname[255];
++
++	if (((opt = optget(opts, "ReportHostname"))->enabled &&
++	     strncpy(myname, opt->strarg, sizeof(myname))) ||
++	    !gethostname(myname, sizeof(myname))) {
++
++	    myname[sizeof(myname)-1] = '\0';
++	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s",
++		     get_version(), myname);
++	} else {
++	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s",
++		     get_version());
++	}
++	xvirushdr[sizeof(xvirushdr)-1] = '\0';
++
++	descr.xxfi_flags |= SMFIF_ADDHDRS;
++
++	if (strcasecmp(pt, "Add")) { /* Replace or Yes */
++	    descr.xxfi_flags |= SMFIF_CHGHDRS;
++	    addxvirus = 1;
++	} else { /* Add */
++	    addxvirus = 2;
++	}
++    }
++
+     if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
+ 	logg("!Please configure the MilterSocket directive\n");
+ 	logg_close();
+@@ -323,27 +350,6 @@ int main(int argc, char **argv) {
+ 	return 1;
+     }
+ 
+-    pt = optget(opts, "AddHeader")->strarg;
+-    if(strcasecmp(pt, "No")) {
+-	char myname[255];
+-
+-	if(((opt = optget(opts, "ReportHostname"))->enabled && strncpy(myname, opt->strarg, sizeof(myname))) || !gethostname(myname, sizeof(myname))) {
+-	    myname[sizeof(myname)-1] = '\0';
+-	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s", get_version(), myname);
+-	} else
+-	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s", get_version());
+-	xvirushdr[sizeof(xvirushdr)-1] = '\0';
+-
+-	descr.xxfi_flags |= SMFIF_ADDHDRS;
+-
+-	if(strcasecmp(pt, "Add")) { /* Replace or Yes */
+-	    descr.xxfi_flags |= SMFIF_CHGHDRS;
+-	    addxvirus = 1;
+-	} else { /* Add */
+-	    addxvirus = 2;
+-	}
+-    }
+-
+     multircpt = optget(opts, "SupportMultipleRecipients")->enabled;
+     
+     if(!optget(opts, "Foreground")->enabled) {
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0017-Bump-.so-version-number.patch clamav-0.98.5+dfsg/debian/patches/0017-Bump-.so-version-number.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0017-Bump-.so-version-number.patch	1969-12-31 19:00:00.000000000 -0500
+++ clamav-0.98.5+dfsg/debian/patches/0017-Bump-.so-version-number.patch	2014-11-20 00:44:11.000000000 -0500
@@ -0,0 +1,22 @@
+From f772ae0e4a230f56e061ecc7a687b1d421fe626e Mon Sep 17 00:00:00 2001
+From: Shawn Webb <swebb@sourcefire.com>
+Date: Wed, 19 Nov 2014 11:51:22 -0500
+Subject: Bump .so version number
+
+---
+ m4/reorganization/version.m4 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/m4/reorganization/version.m4 b/m4/reorganization/version.m4
+index ea263b28e647..f4fe8b1e150e 100644
+--- a/m4/reorganization/version.m4
++++ b/m4/reorganization/version.m4
+@@ -3,7 +3,7 @@ dnl VERSION="devel-`date +%Y%m%d`"
+ VERSION="0.98.5"
+ 
+ LC_CURRENT=7
+-LC_REVISION=22
++LC_REVISION=24
+ LC_AGE=1
+ LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
+ AC_SUBST([LIBCLAMAV_VERSION])
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0017-fix-test-failure-on-powerpc-again.patch clamav-0.98.5+dfsg/debian/patches/0017-fix-test-failure-on-powerpc-again.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0017-fix-test-failure-on-powerpc-again.patch	2014-10-18 11:57:20.000000000 -0400
+++ clamav-0.98.5+dfsg/debian/patches/0017-fix-test-failure-on-powerpc-again.patch	1969-12-31 19:00:00.000000000 -0500
@@ -1,105 +0,0 @@
-From 0471298187f9fafc9575e516f07cb11b5660b005 Mon Sep 17 00:00:00 2001
-From: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
-Date: Thu, 16 Oct 2014 23:18:36 +0200
-Subject: fix test failure on powerpc (again)
-
----
- libclamav/c++/bytecode2llvm.cpp | 33 +++++++++++----------------------
- 1 file changed, 11 insertions(+), 22 deletions(-)
-
-diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp
-index 2cc8a8c..3366c41 100644
---- a/libclamav/c++/bytecode2llvm.cpp
-+++ b/libclamav/c++/bytecode2llvm.cpp
-@@ -1721,8 +1721,7 @@ public:
- 			    Value *Dst = convertOperand(func, inst, inst->u.three[0]);
- 			    Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
- 			    Value *Val = convertOperand(func, Type::getInt8Ty(Context), inst->u.three[1]);
--			    //Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
--                            Value *Len = convertOperand(func, Type::getInt64Ty(Context), inst->u.three[2]);
-+			    Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
- #if LLVM_VERSION < 29
- 			    CallInst *c = Builder.CreateCall4(CF->FMemset, Dst, Val, Len,
- 								ConstantInt::get(Type::getInt32Ty(Context), 1));
-@@ -1743,8 +1742,7 @@ public:
- 			    Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
- 			    Value *Src = convertOperand(func, inst, inst->u.three[1]);
- 			    Src = Builder.CreatePointerCast(Src, PointerType::getUnqual(Type::getInt8Ty(Context)));
--			    //Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
--                            Value *Len = convertOperand(func, Type::getInt64Ty(Context), inst->u.three[2]);
-+			    Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
- #if LLVM_VERSION < 29
- 			    CallInst *c = Builder.CreateCall4(CF->FMemcpy, Dst, Src, Len,
- 								ConstantInt::get(Type::getInt32Ty(Context), 1));
-@@ -1765,8 +1763,7 @@ public:
- 			    Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
- 			    Value *Src = convertOperand(func, inst, inst->u.three[1]);
- 			    Src = Builder.CreatePointerCast(Src, PointerType::getUnqual(Type::getInt8Ty(Context)));
--                            //Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
--                            Value *Len = convertOperand(func, Type::getInt64Ty(Context), inst->u.three[2]);
-+			    Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
- #if LLVM_VERSION < 29
- 			    CallInst *c = Builder.CreateCall4(CF->FMemmove, Dst, Src, Len,
- 								ConstantInt::get(Type::getInt32Ty(Context), 1));
-@@ -2031,8 +2028,7 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
-     std::vector<constType*> args;
-     args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
-     args.push_back(Type::getInt8Ty(Context));
--    //args.push_back(Type::getInt32Ty(Context));
--    args.push_back(Type::getInt64Ty(Context));
-+    args.push_back(Type::getInt32Ty(Context));
-     args.push_back(Type::getInt32Ty(Context));
- #if LLVM_VERSION >= 29
-     args.push_back(Type::getInt1Ty(Context));
-@@ -2041,11 +2037,9 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
- 					       args, false);
-     CF->FMemset = Function::Create(FuncTy_3, GlobalValue::ExternalLinkage,
- #if LLVM_VERSION < 29
--                                   //"llvm.memset.i32",
--                                   "llvm.memset.i64",
-+                                   "llvm.memset.i32",
- #else
--                                   //"llvm.memset.p0i8.i32",
--                                   "llvm.memset.p0i8.i64",
-+                                   "llvm.memset.p0i8.i32",
- #endif
-                                    M);
-     CF->FMemset->setDoesNotThrow();
-@@ -2058,8 +2052,7 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
-     args.clear();
-     args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
-     args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
--    //args.push_back(Type::getInt32Ty(Context));
--    args.push_back(Type::getInt64Ty(Context));
-+    args.push_back(Type::getInt32Ty(Context));
-     args.push_back(Type::getInt32Ty(Context));
- #if LLVM_VERSION >= 29
-     args.push_back(Type::getInt1Ty(Context));
-@@ -2068,11 +2061,9 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
- 					       args, false);
-     CF->FMemmove = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage,
- #if LLVM_VERSION < 29
--                                    //"llvm.memmove.i32",
--                                    "llvm.memcpy.i64",
-+                                    "llvm.memmove.i32",
- #else
--                                    //"llvm.memmove.p0i8.i32",
--                                    "llvm.memmove.p0i8.i64",
-+                                    "llvm.memmove.p0i8.i32",
- #endif
-                                     M);
-     CF->FMemmove->setDoesNotThrow();
-@@ -2084,11 +2075,9 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
- 
-     CF->FMemcpy = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage,
- #if LLVM_VERSION < 29
--                                   //"llvm.memcpy.i32",
--                                   "llvm.memcpy.i64",
-+                                   "llvm.memcpy.i32",
- #else
--                                   //"llvm.memcpy.p0i8.p0i8.i32",
--                                   "llvm.memcpy.p0i8.p0i8.i64",
-+                                   "llvm.memcpy.p0i8.p0i8.i32",
- #endif
-                                    M);
-     CF->FMemcpy->setDoesNotThrow();
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0018-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch clamav-0.98.5+dfsg/debian/patches/0018-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0018-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch	2014-10-30 16:26:48.000000000 -0400
+++ clamav-0.98.5+dfsg/debian/patches/0018-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch	1969-12-31 19:00:00.000000000 -0500
@@ -1,86 +0,0 @@
-From ef4a9a712e15ffb2bb983cd8f337a7a4954332c6 Mon Sep 17 00:00:00 2001
-From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
-Date: Sun, 26 Oct 2014 12:11:09 +0100
-Subject: clamav-milter: add additinal SMFIF_* flags before invoking
- smfi_register()
-
-unfortunately after the shifting of the code (so that the socket could
-be part of a group which is not part of the clamav user) I forgot (or
-did not see it) to have the header flags added before the
-smfi_register() was invoked. As a result the socket was working but it
-was unable to add the X-Virus-Scanned &  X-Virus-Status flags. This
-patch fixes the issue.
-
-https://bugzilla.clamav.net/show_bug.cgi?id=10731
-
-Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
----
- clamav-milter/clamav-milter.c | 48 ++++++++++++++++++++++++-------------------
- 1 file changed, 27 insertions(+), 21 deletions(-)
-
-diff --git a/clamav-milter/clamav-milter.c b/clamav-milter/clamav-milter.c
-index 99e7fe7..22db98a 100644
---- a/clamav-milter/clamav-milter.c
-+++ b/clamav-milter/clamav-milter.c
-@@ -116,6 +116,33 @@ int main(int argc, char **argv) {
- 	}
-     }
- 
-+    pt = optget(opts, "AddHeader")->strarg;
-+    if (strcasecmp(pt, "No")) {
-+	char myname[255];
-+
-+	if (((opt = optget(opts, "ReportHostname"))->enabled &&
-+	     strncpy(myname, opt->strarg, sizeof(myname))) ||
-+	    !gethostname(myname, sizeof(myname))) {
-+
-+	    myname[sizeof(myname)-1] = '\0';
-+	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s",
-+		     get_version(), myname);
-+	} else {
-+	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s",
-+		     get_version());
-+	}
-+	xvirushdr[sizeof(xvirushdr)-1] = '\0';
-+
-+	descr.xxfi_flags |= SMFIF_ADDHDRS;
-+
-+	if (strcasecmp(pt, "Add")) { /* Replace or Yes */
-+	    descr.xxfi_flags |= SMFIF_CHGHDRS;
-+	    addxvirus = 1;
-+	} else { /* Add */
-+	    addxvirus = 2;
-+	}
-+    }
-+
-     if(!(my_socket = optget(opts, "MilterSocket")->strarg)) {
- 	logg("!Please configure the MilterSocket directive\n");
- 	logg_close();
-@@ -323,27 +350,6 @@ int main(int argc, char **argv) {
- 	return 1;
-     }
- 
--    pt = optget(opts, "AddHeader")->strarg;
--    if(strcasecmp(pt, "No")) {
--	char myname[255];
--
--	if(((opt = optget(opts, "ReportHostname"))->enabled && strncpy(myname, opt->strarg, sizeof(myname))) || !gethostname(myname, sizeof(myname))) {
--	    myname[sizeof(myname)-1] = '\0';
--	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s at %s", get_version(), myname);
--	} else
--	    snprintf(xvirushdr, sizeof(xvirushdr), "clamav-milter %s", get_version());
--	xvirushdr[sizeof(xvirushdr)-1] = '\0';
--
--	descr.xxfi_flags |= SMFIF_ADDHDRS;
--
--	if(strcasecmp(pt, "Add")) { /* Replace or Yes */
--	    descr.xxfi_flags |= SMFIF_CHGHDRS;
--	    addxvirus = 1;
--	} else { /* Add */
--	    addxvirus = 2;
--	}
--    }
--
-     multircpt = optget(opts, "SupportMultipleRecipients")->enabled;
-     
-     if(!optget(opts, "Foreground")->enabled) {
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/0018-llvm-don-t-use-system-libs.patch clamav-0.98.5+dfsg/debian/patches/0018-llvm-don-t-use-system-libs.patch
--- clamav-0.98.5~rc1+dfsg/debian/patches/0018-llvm-don-t-use-system-libs.patch	1969-12-31 19:00:00.000000000 -0500
+++ clamav-0.98.5+dfsg/debian/patches/0018-llvm-don-t-use-system-libs.patch	2014-11-20 00:44:11.000000000 -0500
@@ -0,0 +1,26 @@
+From 1e6bc6dd2b0b8eaf78e7dadf47790f97daf9b110 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Date: Wed, 19 Nov 2014 23:04:32 +0100
+Subject: llvm: don't use --system-libs
+
+this continues the saga of not linking the .a files so we don't care
+about the libs llvm links against (like -ledit)
+
+Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+---
+ libclamav/c++/configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libclamav/c++/configure.ac b/libclamav/c++/configure.ac
+index 43e187ff1f56..2d2d47b9d24c 100644
+--- a/libclamav/c++/configure.ac
++++ b/libclamav/c++/configure.ac
+@@ -115,7 +115,7 @@ if test "x$llvmconfig" != "x"; then
+     if test $llvmver_test -ge 350; then
+         dnl LLVM 3.5.0 and after splits linker flags into two sets
+         ldflags=`$llvmconfig --ldflags`
+-        syslibs=`$llvmconfig --system-libs`
++        syslibs=
+         AC_SUBST(LLVMCONFIG_LDFLAGS, ["$ldflags $syslibs"])
+     else
+         AC_SUBST(LLVMCONFIG_LDFLAGS, [`$llvmconfig --ldflags`])
diff -Nru clamav-0.98.5~rc1+dfsg/debian/patches/series clamav-0.98.5+dfsg/debian/patches/series
--- clamav-0.98.5~rc1+dfsg/debian/patches/series	2014-10-30 16:26:48.000000000 -0400
+++ clamav-0.98.5+dfsg/debian/patches/series	2014-11-20 00:44:11.000000000 -0500
@@ -12,7 +12,7 @@
 0012-allow-to-use-internal-libmspack-if-the-external-is-n.patch
 0013-fix-autoreconf-with-embedded-libmspack.patch
 0014-remove-AC_CONFIG_SRCDIR-llvm-configure-from-libclama.patch
-0015-LLVM-3.5-version-check-update.patch
-0016-add-support-for-LLVM-3.5.patch
-0017-fix-test-failure-on-powerpc-again.patch
-0018-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch
+0015-bb-10731-Allow-to-specificy-a-group-for-the-socket-o.patch
+0016-clamav-milter-add-additinal-SMFIF_-flags-before-invo.patch
+0017-Bump-.so-version-number.patch
+0018-llvm-don-t-use-system-libs.patch
diff -Nru clamav-0.98.5~rc1+dfsg/freshclam/manager.c clamav-0.98.5+dfsg/freshclam/manager.c
--- clamav-0.98.5~rc1+dfsg/freshclam/manager.c	2014-09-03 17:26:53.000000000 -0400
+++ clamav-0.98.5+dfsg/freshclam/manager.c	2014-11-13 17:30:38.000000000 -0500
@@ -1209,13 +1209,21 @@
 {
     char cvdfile[32];
 
-
     if (access (tmpdir, R_OK | W_OK) == -1)
     {
-        sprintf (cvdfile, "%s.cvd", dbname);
+        int ret;
+        ret = snprintf (cvdfile, sizeof(cvdfile), "%s.cvd", dbname);
+        if (ret >= sizeof(cvdfile) || ret == -1) {
+            logg ("!chdir_tmp: dbname parameter value too long to create cvd file name: %s\n", dbname);
+            return -1;
+        }
         if (access (cvdfile, R_OK) == -1)
         {
-            sprintf (cvdfile, "%s.cld", dbname);
+            ret = snprintf (cvdfile, sizeof(cvdfile), "%s.cld", dbname);
+            if (ret >= sizeof(cvdfile) || ret == -1) {
+                logg ("!chdir_tmp: dbname parameter value too long to create cld file name: %s\n", dbname);
+                return -1;
+            }
             if (access (cvdfile, R_OK) == -1)
             {
                 logg ("!chdir_tmp: Can't access local %s database\n", dbname);
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/asn1.c clamav-0.98.5+dfsg/libclamav/asn1.c
--- clamav-0.98.5~rc1+dfsg/libclamav/asn1.c	2014-09-03 17:26:53.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/asn1.c	2014-11-13 17:30:38.000000000 -0500
@@ -836,8 +836,10 @@
 		    break;
 		}
 	    }
-	    if(dsize)
-		break;
+	    if(dsize) {
+            crtmgr_free(&newcerts);
+            break;
+        }
 	    if(newcerts.crts) {
 		x509 = newcerts.crts;
 		cli_dbgmsg("asn1_parse_mscat: %u new certificates collected\n", newcerts.items);
@@ -877,8 +879,10 @@
 		    }
 		    x509 = x509->next;
 		}
-		if(x509)
+		if(x509) {
+            crtmgr_free(&newcerts);
 		    break;
+        }
 		if(newcerts.items)
 		    cli_dbgmsg("asn1_parse_mscat: %u certificates did not verify\n", newcerts.items);
 		crtmgr_free(&newcerts);
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/c++/bytecode2llvm.cpp clamav-0.98.5+dfsg/libclamav/c++/bytecode2llvm.cpp
--- clamav-0.98.5~rc1+dfsg/libclamav/c++/bytecode2llvm.cpp	2014-10-02 17:24:09.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/c++/bytecode2llvm.cpp	2014-11-13 17:30:40.000000000 -0500
@@ -44,8 +44,15 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
+#if LLVM_VERSION < 35
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/AutoUpgrade.h"
+#include "llvm/Support/TargetFolder.h"
+#else
+#include "llvm/IR/Verifier.h"
+#include "llvm/IR/AutoUpgrade.h"
+#include "llvm/Analysis/TargetFolder.h"
+#endif
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
 #include "llvm/ExecutionEngine/JIT.h"
 #include "llvm/ExecutionEngine/JITEventListener.h"
@@ -100,15 +107,16 @@
 #endif
 
 #include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/TargetFolder.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 
 #if LLVM_VERSION < 32
 #include "llvm/Analysis/DebugInfo.h"
-#else
+#elif LLVM_VERSION < 35
 #include "llvm/DebugInfo.h"
+#else
+#include "llvm/IR/DebugInfo.h"
 #endif
 
 #if LLVM_VERSION < 32
@@ -144,6 +152,10 @@
 #include "llvm/Analysis/CFG.h"
 #endif
 
+#if LLVM_VERSION >= 35
+#include "llvm/IR/Dominators.h"
+#endif
+
 //#define TIMING
 #undef TIMING
 
@@ -657,7 +669,11 @@
 	}
 	BBSetTy  needsTimeoutCheck;
 	BBMapTy BBMap;
+#if LLVM_VERSION < 35
 	DominatorTree &DT = getAnalysis<DominatorTree>();
+#else
+	DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+#endif
 	for (Function::iterator I=F.begin(),E=F.end(); I != E; ++I) {
 	    BasicBlock *BB = &*I;
 	    unsigned apicalls = 0;
@@ -784,7 +800,11 @@
       AU.setPreservesAll();
       AU.addRequired<LoopInfo>();
       AU.addRequired<ScalarEvolution>();
+#if LLVM_VERSION < 35
       AU.addRequired<DominatorTree>();
+#else
+      AU.addRequired<DominatorTreeWrapperPass>();
+#endif
     }
 };
 char RuntimeLimits::ID;
@@ -1701,8 +1721,7 @@
 			    Value *Dst = convertOperand(func, inst, inst->u.three[0]);
 			    Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
 			    Value *Val = convertOperand(func, Type::getInt8Ty(Context), inst->u.three[1]);
-			    //Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
-                            Value *Len = convertOperand(func, Type::getInt64Ty(Context), inst->u.three[2]);
+			    Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
 #if LLVM_VERSION < 29
 			    CallInst *c = Builder.CreateCall4(CF->FMemset, Dst, Val, Len,
 								ConstantInt::get(Type::getInt32Ty(Context), 1));
@@ -1723,8 +1742,7 @@
 			    Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
 			    Value *Src = convertOperand(func, inst, inst->u.three[1]);
 			    Src = Builder.CreatePointerCast(Src, PointerType::getUnqual(Type::getInt8Ty(Context)));
-			    //Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
-                            Value *Len = convertOperand(func, Type::getInt64Ty(Context), inst->u.three[2]);
+			    Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
 #if LLVM_VERSION < 29
 			    CallInst *c = Builder.CreateCall4(CF->FMemcpy, Dst, Src, Len,
 								ConstantInt::get(Type::getInt32Ty(Context), 1));
@@ -1745,8 +1763,7 @@
 			    Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
 			    Value *Src = convertOperand(func, inst, inst->u.three[1]);
 			    Src = Builder.CreatePointerCast(Src, PointerType::getUnqual(Type::getInt8Ty(Context)));
-                            //Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
-                            Value *Len = convertOperand(func, Type::getInt64Ty(Context), inst->u.three[2]);
+			    Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
 #if LLVM_VERSION < 29
 			    CallInst *c = Builder.CreateCall4(CF->FMemmove, Dst, Src, Len,
 								ConstantInt::get(Type::getInt32Ty(Context), 1));
@@ -1856,7 +1873,11 @@
 
 	    // If successful so far, run verifyFunction
 	    if (!broken) {
+#if LLVM_VERSION < 35
 		if (verifyFunction(*F, PrintMessageAction)) {
+#else
+		if (verifyFunction(*F, &errs())) {
+#endif
 		    // verification failed
 		    broken = true;
 		    cli_warnmsg("[Bytecode JIT]: Verification failed\n");
@@ -1945,7 +1966,11 @@
 	ReturnInst::Create(Context, CI, BB);
 
 	delete [] Functions;
+#if LLVM_VERSION < 35
 	if (verifyFunction(*F, PrintMessageAction))
+#else
+	if (verifyFunction(*F, &errs()))
+#endif
 	    return 0;
 
 /*			DEBUG(errs() << "Generating code\n");
@@ -2003,8 +2028,7 @@
     std::vector<constType*> args;
     args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
     args.push_back(Type::getInt8Ty(Context));
-    //args.push_back(Type::getInt32Ty(Context));
-    args.push_back(Type::getInt64Ty(Context));
+    args.push_back(Type::getInt32Ty(Context));
     args.push_back(Type::getInt32Ty(Context));
 #if LLVM_VERSION >= 29
     args.push_back(Type::getInt1Ty(Context));
@@ -2013,11 +2037,9 @@
 					       args, false);
     CF->FMemset = Function::Create(FuncTy_3, GlobalValue::ExternalLinkage,
 #if LLVM_VERSION < 29
-                                   //"llvm.memset.i32",
-                                   "llvm.memset.i64",
+                                   "llvm.memset.i32",
 #else
-                                   //"llvm.memset.p0i8.i32",
-                                   "llvm.memset.p0i8.i64",
+                                   "llvm.memset.p0i8.i32",
 #endif
                                    M);
     CF->FMemset->setDoesNotThrow();
@@ -2030,8 +2052,7 @@
     args.clear();
     args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
     args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
-    //args.push_back(Type::getInt32Ty(Context));
-    args.push_back(Type::getInt64Ty(Context));
+    args.push_back(Type::getInt32Ty(Context));
     args.push_back(Type::getInt32Ty(Context));
 #if LLVM_VERSION >= 29
     args.push_back(Type::getInt1Ty(Context));
@@ -2040,11 +2061,9 @@
 					       args, false);
     CF->FMemmove = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage,
 #if LLVM_VERSION < 29
-                                    //"llvm.memmove.i32",
-                                    "llvm.memcpy.i64",
+                                    "llvm.memmove.i32",
 #else
-                                    //"llvm.memmove.p0i8.i32",
-                                    "llvm.memmove.p0i8.i64",
+                                    "llvm.memmove.p0i8.i32",
 #endif
                                     M);
     CF->FMemmove->setDoesNotThrow();
@@ -2056,11 +2075,9 @@
 
     CF->FMemcpy = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage,
 #if LLVM_VERSION < 29
-                                   //"llvm.memcpy.i32",
-                                   "llvm.memcpy.i64",
+                                   "llvm.memcpy.i32",
 #else
-                                   //"llvm.memcpy.p0i8.p0i8.i32",
-                                   "llvm.memcpy.p0i8.p0i8.i64",
+                                   "llvm.memcpy.p0i8.p0i8.i32",
 #endif
                                    M);
     CF->FMemcpy->setDoesNotThrow();
@@ -2125,7 +2142,11 @@
 INITIALIZE_PASS_BEGIN(RuntimeLimits, "rl", "Runtime Limits", false, false)
 INITIALIZE_PASS_DEPENDENCY(LoopInfo)
 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
+#if LLVM_VERSION < 35
 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+#else
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+#endif
 INITIALIZE_PASS_END(RuntimeLimits, "rl" ,"Runtime Limits", false, false)
 #endif
 
@@ -2341,16 +2362,20 @@
 }
 #if LLVM_VERSION < 32
 static void addFPasses(FunctionPassManager &FPM, bool trusted, const TargetData *TD)
-#else
+#elif LLVM_VERSION < 35
 static void addFPasses(FunctionPassManager &FPM, bool trusted, const DataLayout *TD)
+#else
+static void addFPasses(FunctionPassManager &FPM, bool trusted, const Module *M)
 #endif
 {
     // Set up the optimizer pipeline.  Start with registering info about how
     // the target lays out data structures.
 #if LLVM_VERSION < 32
     FPM.add(new TargetData(*TD));
-#else
+#elif LLVM_VERSION < 35
     FPM.add(new DataLayout(*TD));
+#else
+    FPM.add(new DataLayoutPass(M));
 #endif
     // Promote allocas to registers.
     FPM.add(createPromoteMemoryToRegisterPass());
@@ -2428,9 +2453,12 @@
 #if LLVM_VERSION < 32
 	addFPasses(OurFPM, true, EE->getTargetData());
 	addFPasses(OurFPMUnsigned, false, EE->getTargetData());
-#else
+#elif LLVM_VERSION < 35
 	addFPasses(OurFPM, true, EE->getDataLayout());
 	addFPasses(OurFPMUnsigned, false, EE->getDataLayout());
+#else
+	addFPasses(OurFPM, true, M);
+	addFPasses(OurFPMUnsigned, false, M);
 #endif
 
 
@@ -2541,8 +2569,10 @@
 	PassManager PM;
 #if LLVM_VERSION < 32
 	PM.add(new TargetData(*EE->getTargetData()));
-#else
+#elif LLVM_VERSION < 35
 	PM.add(new DataLayout(*EE->getDataLayout()));
+#else
+	PM.add(new DataLayoutPass(M));
 #endif
 	// TODO: only run this on the untrusted bytecodes, not all of them...
 	if (has_untrusted)
@@ -2601,10 +2631,17 @@
 int bytecode_init(void)
 {
     // If already initialized return
+#if LLVM_VERSION < 35
     if (llvm_is_multithreaded()) {
 	cli_warnmsg("bytecode_init: already initialized\n");
 	return CL_EARG;
     }
+#else
+    if (!LLVMIsMultithreaded()) {
+        cli_warnmsg("bytecode_init: LLVM is compiled without multithreading support\n");
+    }
+#endif
+
     llvm_install_error_handler(llvm_error_handler);
 #ifdef CL_DEBUG
     sys::PrintStackTraceOnErrorSignal();
@@ -2628,7 +2665,11 @@
 #endif
     llvm::DwarfExceptionHandling = false;
 #endif
+#if LLVM_VERSION < 33
     llvm_start_multithreaded();
+#else
+    // This is now deprecated/useless: Multi-threading can only be enabled/disabled with the compile time define LLVM_ENABLE_THREADS in LLVM.
+#endif
 
     // If we have a native target, initialize it to ensure it is linked in and
     // usable by the JIT.
@@ -2638,7 +2679,11 @@
     InitializeAllTargets();
 #endif
 
+#if LLVM_VERSION < 35
     if (!llvm_is_multithreaded()) {
+#else
+    if (!LLVMIsMultithreaded()) {
+#endif
 	//TODO:cli_dbgmsg
 	DEBUG(errs() << "WARNING: ClamAV JIT built w/o atomic builtins\n"
 	      << "On x86 for best performance ClamAV should be built for i686, not i386!\n");
@@ -2710,7 +2755,7 @@
 	std::string ErrorMessage;
 #if LLVM_VERSION < 29
 	lines->buffer = MemoryBuffer::getFile(path, &ErrorMessage);
-#else
+#elif LLVM_VERSION < 35
 	OwningPtr<MemoryBuffer> File;
 	error_code ec = MemoryBuffer::getFile(path, File);
 	if (ec) {
@@ -2718,6 +2763,15 @@
 	    lines->buffer = 0;
 	} else
 	    lines->buffer = File.take();
+#else
+	ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = MemoryBuffer::getFile(path);
+	if (!FileOrErr) {
+		// TODO: How to handle ErrorMessage?
+		lines->buffer = 0;
+	}
+	else {
+		lines->buffer = FileOrErr.get().release();
+	}
 #endif
 	if (!lines->buffer) {
 	    errs() << "Unable to open file '" << path << "'\n";
@@ -2863,7 +2917,10 @@
   StringRef G;
   StringRef H;
 #endif
+#if LLVM_VERSION < 35
   DIType TypeD;
+#endif
+  StringRef T;
 
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) {
     Value *DIGV = findDbgGlobalDeclare(GV);
@@ -2880,7 +2937,11 @@
     G = Var.getFilename();
     H = Var.getDirectory();
 #endif
+#if LLVM_VERSION < 35
     TypeD = Var.getType();
+#else
+    T = Var.getType().getName();
+#endif
   } else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){
     Value *DIF = findDbgSubprogramDeclare(F);
     if (!DIF) return false;
@@ -2896,7 +2957,11 @@
     G = Var.getFilename();
     H = Var.getDirectory();
 #endif
+#if LLVM_VERSION < 35
     TypeD = Var.getType();
+#else
+    T = Var.getType().getName();
+#endif
   } else {
     const DbgDeclareInst *DDI = findDbgDeclare(V);
     if (!DDI) return false;
@@ -2913,10 +2978,16 @@
     G = StringRef();
     H = StringRef();
 #endif
+#if LLVM_VERSION < 35
     TypeD = Var.getType();
+#else
+    T = Var.getType().getName();
+#endif
   }
 
-  StringRef T = TypeD.getName();
+#if LLVM_VERSION < 35
+  T = TypeD.getName();
+#endif
   if (!T.empty())
     Type = T;
 #if LLVM_VERSION < 33
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/c++/ClamBCRTChecks.cpp clamav-0.98.5+dfsg/libclamav/c++/ClamBCRTChecks.cpp
--- clamav-0.98.5~rc1+dfsg/libclamav/c++/ClamBCRTChecks.cpp	2014-10-02 17:24:09.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/c++/ClamBCRTChecks.cpp	2014-11-13 17:30:38.000000000 -0500
@@ -29,13 +29,20 @@
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/SCCIterator.h"
 #include "llvm/Analysis/CallGraph.h"
-#include "llvm/Analysis/Verifier.h"
 #if LLVM_VERSION < 32
 #include "llvm/Analysis/DebugInfo.h"
-#else
+#elif LLVM_VERSION < 35
 #include "llvm/DebugInfo.h"
+#else
+#include "llvm/IR/DebugInfo.h"
 #endif
+#if LLVM_VERSION < 35
 #include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/Verifier.h"
+#else
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Verifier.h"
+#endif
 #include "llvm/Analysis/ConstantFolding.h"
 #if LLVM_VERSION < 29
 //#include "llvm/Analysis/LiveValues.h" (unused)
@@ -50,9 +57,14 @@
 #include "llvm/Config/config.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
+#if LLVM_VERSION < 35
 #include "llvm/Support/DataFlow.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
+#else
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
+#endif
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -71,7 +83,6 @@
 #include "llvm/Intrinsics.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
-#include "llvm/Support/InstVisitor.h"
 #else
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Instructions.h"
@@ -79,7 +90,14 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+#endif
+
+#if LLVM_VERSION < 33
+#include "llvm/Support/InstVisitor.h"
+#elif LLVM_VERSION < 35
 #include "llvm/InstVisitor.h"
+#else
+#include "llvm/IR/InstVisitor.h"
 #endif
 
 #define DEFINEPASS(passname) passname() : FunctionPass(ID)
@@ -103,10 +121,18 @@
   private:
       DenseSet<Function*> badFunctions;
       std::vector<Instruction*> delInst;
+#if LLVM_VERSION < 35
       CallGraphNode *rootNode;
+#else
+      CallGraph *CG;
+#endif
   public:
       static char ID;
+#if LLVM_VERSION < 35
       DEFINEPASS(PtrVerifier), rootNode(0), PT(), TD(), SE(), expander(),
+#else
+      DEFINEPASS(PtrVerifier), CG(0), PT(), TD(), SE(), expander(),
+#endif
           DT(), AbrtBB(), Changed(false), valid(false), EP() {
 #if LLVM_VERSION >= 29
           initializePtrVerifierPass(*PassRegistry::getPassRegistry());
@@ -133,12 +159,21 @@
           AbrtBB = 0;
           valid = true;
 
+#if LLVM_VERSION < 35
           if (!rootNode) {
               rootNode = getAnalysis<CallGraph>().getRoot();
+#else
+          if (!CG) {
+              CG = &getAnalysis<CallGraphWrapperPass>().getCallGraph();
+#endif
               // No recursive functions for now.
               // In the future we may insert runtime checks for stack depth.
+#if LLVM_VERSION < 35
               for (scc_iterator<CallGraphNode*> SCCI = scc_begin(rootNode),
                        E = scc_end(rootNode); SCCI != E; ++SCCI) {
+#else
+              for (scc_iterator<CallGraph*> SCCI = scc_begin(CG); !SCCI.isAtEnd(); ++SCCI) {
+#endif
                   const std::vector<CallGraphNode*> &nextSCC = *SCCI;
                   if (nextSCC.size() > 1 || SCCI.hasLoop()) {
                       errs() << "INVALID: Recursion detected, callgraph SCC components: ";
@@ -164,12 +199,19 @@
           EP = &*It;
 #if LLVM_VERSION < 32
           TD = &getAnalysis<TargetData>();
-#else
+#elif LLVM_VERSION < 35
           TD = &getAnalysis<DataLayout>();
+#else
+          DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
+          TD = DLP ? &DLP->getDataLayout() : 0;
 #endif
           SE = &getAnalysis<ScalarEvolution>();
           PT = &getAnalysis<PointerTracking>();
+#if LLVM_VERSION < 35
           DT = &getAnalysis<DominatorTree>();
+#else
+          DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+#endif
           expander = new SCEVExpander(*SE OPT("SCEVexpander"));
 
           std::vector<Instruction*> insns;
@@ -307,13 +349,23 @@
       virtual void getAnalysisUsage(AnalysisUsage &AU) const {
 #if LLVM_VERSION < 32
           AU.addRequired<TargetData>();
-#else
+#elif LLVM_VERSION < 35
           AU.addRequired<DataLayout>();
+#else
+          AU.addRequired<DataLayoutPass>();
 #endif
+#if LLVM_VERSION < 35
           AU.addRequired<DominatorTree>();
+#else
+          AU.addRequired<DominatorTreeWrapperPass>();
+#endif
           AU.addRequired<ScalarEvolution>();
           AU.addRequired<PointerTracking>();
+#if LLVM_VERSION < 35
           AU.addRequired<CallGraph>();
+#else
+          AU.addRequired<CallGraphWrapperPass>();
+#endif
       }
 
       bool isValid() const { return valid; }
@@ -321,8 +373,10 @@
       PointerTracking *PT;
 #if LLVM_VERSION < 32
       TargetData *TD;
-#else
+#elif LLVM_VERSION < 35
       DataLayout *TD;
+#else
+      const DataLayout *TD;
 #endif
       ScalarEvolution *SE;
       SCEVExpander *expander;
@@ -855,15 +909,23 @@
 INITIALIZE_PASS_BEGIN(PtrVerifier, "", "", false, false)
 #if LLVM_VERSION < 32
 INITIALIZE_PASS_DEPENDENCY(TargetData)
-#else
+#elif LLVM_VERSION < 35
 INITIALIZE_PASS_DEPENDENCY(DataLayout)
+#else
+INITIALIZE_PASS_DEPENDENCY(DataLayoutPass)
 #endif
+#if LLVM_VERSION < 35
 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+#else
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+#endif
 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
 #if LLVM_VERSION < 34
 INITIALIZE_AG_DEPENDENCY(CallGraph)
-#else
+#elif LLVM_VERSION < 35
 INITIALIZE_PASS_DEPENDENCY(CallGraph)
+#else
+INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
 #endif
 INITIALIZE_PASS_DEPENDENCY(PointerTracking)
 INITIALIZE_PASS_END(PtrVerifier, "clambc-rtchecks", "ClamBC RTchecks", false, false)
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/c++/PointerTracking.cpp clamav-0.98.5+dfsg/libclamav/c++/PointerTracking.cpp
--- clamav-0.98.5~rc1+dfsg/libclamav/c++/PointerTracking.cpp	2014-10-02 17:24:09.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/c++/PointerTracking.cpp	2014-11-13 17:30:39.000000000 -0500
@@ -16,15 +16,19 @@
 #ifndef _WIN32
 
 #include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "PointerTracking.h"
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#if LLVM_VERSION < 35
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/InstIterator.h"
+#else
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/InstIterator.h"
+#endif
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetLibraryInfo.h"
 
@@ -61,10 +65,18 @@
 };
 INITIALIZE_PASS_BEGIN(PointerTracking, "pointertracking",
                 "Track pointer bounds", false, true)
+#if LLVM_VERSION < 35
 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+#else
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+#endif
 INITIALIZE_PASS_DEPENDENCY(LoopInfo)
 INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
+#if LLVM_VERSION < 35
 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+#else
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+#endif
 INITIALIZE_PASS_END(PointerTracking, "pointertracking",
                 "Track pointer bounds", false, true)
 #endif
@@ -82,17 +94,28 @@
   FF = &F;
 #if LLVM_VERSION < 32
   TD = getAnalysisIfAvailable<TargetData>();
-#else
+#elif LLVM_VERSION < 35
   TD = getAnalysisIfAvailable<DataLayout>();
+#else
+  DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
+  TD = DLP ? &DLP->getDataLayout() : 0;
 #endif
   SE = &getAnalysis<ScalarEvolution>();
   LI = &getAnalysis<LoopInfo>();
+#if LLVM_VERSION < 35
   DT = &getAnalysis<DominatorTree>();
+#else
+  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+#endif
   return false;
 }
 
 void PointerTracking::getAnalysisUsage(AnalysisUsage &AU) const {
+#if LLVM_VERSION < 35
   AU.addRequiredTransitive<DominatorTree>();
+#else
+  AU.addRequiredTransitive<DominatorTreeWrapperPass>();
+#endif
   AU.addRequiredTransitive<LoopInfo>();
   AU.addRequiredTransitive<ScalarEvolution>();
   AU.setPreservesAll();
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/c++/PointerTracking.h clamav-0.98.5+dfsg/libclamav/c++/PointerTracking.h
--- clamav-0.98.5~rc1+dfsg/libclamav/c++/PointerTracking.h	2014-10-02 17:24:09.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/c++/PointerTracking.h	2014-11-13 17:30:39.000000000 -0500
@@ -28,9 +28,15 @@
 #define LLVM_ANALYSIS_POINTERTRACKING_H
 
 #include "llvm/ADT/SmallPtrSet.h"
+#if LLVM_VERSION < 35
 #include "llvm/Analysis/Dominators.h"
-#include "llvm/Pass.h"
 #include "llvm/Support/PredIteratorCache.h"
+#else
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/PredIteratorCache.h"
+#include "llvm/IR/DataLayout.h"
+#endif
+#include "llvm/Pass.h"
 #include "llvm30_compat.h"
 
 #if LLVM_VERSION < 33
@@ -117,8 +123,10 @@
     Function *FF;
 #if LLVM_VERSION < 32
     TargetData *TD;
-#else
+#elif LLVM_VERSION < 35
     DataLayout *TD;
+#else
+    const DataLayout *TD;
 #endif
     ScalarEvolution *SE;
     LoopInfo *LI;
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/crypto.c clamav-0.98.5+dfsg/libclamav/crypto.c
--- clamav-0.98.5~rc1+dfsg/libclamav/crypto.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/crypto.c	2014-11-13 17:30:43.000000000 -0500
@@ -151,6 +151,11 @@
         return NULL;
     }
 
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    /* we will be using MD5, which is not allowed under FIPS */
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+
     if (!EVP_DigestInit_ex(ctx, md, NULL)) {
         if (!(obuf))
             free(ret);
@@ -212,6 +217,11 @@
     if (!(ctx))
         return NULL;
 
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    /* we will be using MD5, which is not allowed under FIPS */
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+
     if (!EVP_DigestInit_ex(ctx, md, NULL)) {
         EVP_MD_CTX_destroy(ctx);
         return NULL;
@@ -321,6 +331,11 @@
 
     mdsz = EVP_MD_size(md);
 
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    /* we will be using MD5, which is not allowed under FIPS */
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+
     if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
         EVP_MD_CTX_destroy(ctx);
         return -1;
@@ -365,6 +380,11 @@
         return -1;
     }
 
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    /* we will be using MD5, which is not allowed under FIPS */
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+
     if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
         free(digest);
         EVP_MD_CTX_destroy(ctx);
@@ -435,6 +455,11 @@
         return -1;
     }
 
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    /* we will be using MD5, which is not allowed under FIPS */
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+
     if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
         free(digest);
         if (decode)
@@ -643,6 +668,11 @@
         return NULL;
     }
 
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    /* we will be using MD5, which is not allowed under FIPS */
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+
     if (!EVP_SignInit_ex(ctx, md, NULL)) {
         free(sig);
         EVP_MD_CTX_destroy(ctx);
@@ -1078,6 +1108,11 @@
         return NULL;
     }
 
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
+    /* we will be using MD5, which is not allowed under FIPS */
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+
     if (!EVP_DigestInit_ex(ctx, md, NULL)) {
         EVP_MD_CTX_destroy(ctx);
         return NULL;
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/filetypes.c clamav-0.98.5+dfsg/libclamav/filetypes.c
--- clamav-0.98.5~rc1+dfsg/libclamav/filetypes.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/filetypes.c	2014-11-13 17:30:43.000000000 -0500
@@ -267,7 +267,8 @@
             const unsigned char * znamep = buff;
             int32_t zlen = bread;
             int lhc = 0;
-            int zi;
+            int zi, likely_ooxml = 0;
+            cli_file_t ret2;
             
             for (zi=0; zi<32; zi++) {
                 znamep = (const unsigned char *)cli_memstr((const char *)znamep, zlen, lhdr_magic, 4);
@@ -284,9 +285,34 @@
                         } else if (0 == memcmp(znamep, "word/", 5)) {
                             cli_dbgmsg("Recognized OOXML Word file\n");
                             return CL_TYPE_OOXML_WORD;
+                        } else if (0 == memcmp(znamep, "docProps/", 5)) {
+                            likely_ooxml = 1;
+                        }
+
+                        if (++lhc > 2) {
+                            /* only check first three zip headers unless likely ooxml */
+                            if (likely_ooxml) {
+                                cli_dbgmsg("Likely OOXML, checking additional zip headers\n");
+                                if ((ret2 = cli_ooxml_filetype(NULL, map)) != CL_SUCCESS) {
+                                    /* either an error or retyping has occurred, return error or just CL_TYPE_ZIP? */
+                                    switch (ret2) {
+                                    case CL_TYPE_OOXML_XL:
+                                        cli_dbgmsg("Recognized OOXML XL file\n");
+                                        break;
+                                    case CL_TYPE_OOXML_PPT:
+                                        cli_dbgmsg("Recognized OOXML PPT file\n");
+                                        break;
+                                    case CL_TYPE_OOXML_WORD:
+                                        cli_dbgmsg("Recognized OOXML WORD file\n");
+                                        break;
+                                    default:
+                                        cli_dbgmsg("unexpected ooxml_filetype return: %i\n", ret2);
+                                    }
+                                    return ret2;
+                                }
+                            }
+                            break;
                         }
-                        if (++lhc > 2)
-                            break; /* only check first three zip headers */
                     }
                     else {
                         znamep = NULL; /* force to map more */
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/hashtab.c clamav-0.98.5+dfsg/libclamav/hashtab.c
--- clamav-0.98.5~rc1+dfsg/libclamav/hashtab.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/hashtab.c	2014-11-13 17:30:43.000000000 -0500
@@ -776,7 +776,7 @@
 		rc = cli_hashset_init_pool(&new_hs, hs->capacity << 1, hs->limit*100/hs->capacity, hs->mempool);
 	else
 		rc = cli_hashset_init(&new_hs, hs->capacity << 1, hs->limit*100/hs->capacity);
-	if(rc < 0)
+	if(rc != 0)
 		return rc;
 	/* and copy keys */
 	for(i=0;i < hs->capacity;i++) {
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/msdoc.c clamav-0.98.5+dfsg/libclamav/msdoc.c
--- clamav-0.98.5~rc1+dfsg/libclamav/msdoc.c	1969-12-31 19:00:00.000000000 -0500
+++ clamav-0.98.5+dfsg/libclamav/msdoc.c	2014-11-13 18:07:40.000000000 -0500
@@ -0,0 +1,982 @@
+/*
+ * Extract component parts of OLE2 files (e.g. MS Office Documents)
+ * 
+ * Copyright (C) 2007-2013 Sourcefire, Inc.
+ * 
+ * Authors: Trog
+ * 
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if HAVE_CONFIG_H
+#include "clamav-config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <conv.h>
+#ifdef	HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if HAVE_ICONV
+#include <iconv.h>
+#endif
+
+#include "clamav.h"
+#include "cltypes.h"
+#include "others.h"
+#include "msdoc.h"
+#include "scanners.h"
+#include "fmap.h"
+#include "json_api.h"
+
+#if HAVE_JSON
+static char *
+ole2_convert_utf(summary_ctx_t *sctx, char *begin, size_t sz, const char *encoding)
+{
+    char *outbuf=NULL;
+#if HAVE_ICONV
+    char *buf, *p1, *p2;
+    off_t offset;
+    size_t inlen, outlen, nonrev, sz2;
+    int i, try;
+    iconv_t cd;
+#endif
+    /* applies in the both case */
+    if (sctx->codepage == 20127 || sctx->codepage == 65001) {
+        char *track;
+        int bcnt, scnt;
+
+        outbuf = cli_calloc(1, sz+1);
+        if (!(outbuf))
+            return NULL;
+        memcpy(outbuf, begin, sz);
+
+        track = outbuf+sz-1;
+        if ((sctx->codepage == 65001) && (*track & 0x80)) { /* UTF-8 with a most significant bit */
+            /* locate the start of the last character */
+            for (bcnt = 1; (track != outbuf); track--, bcnt++) {
+                if (((uint8_t)*track & 0xC0) != 0x80)
+                    break;
+            }
+
+            /* count number of set (1) significant bits */
+            for (scnt = 0; scnt < sizeof(uint8_t)*8; scnt++) {
+                if (((uint8_t)*track & (0x80 >> scnt)) == 0)
+                    break;
+            }
+
+            if (bcnt != scnt) {
+                cli_dbgmsg("ole2_convert_utf: cleaning out %d bytes from incomplete "
+                           "utf-8 character length %d\n", bcnt, scnt);
+                for (; bcnt > 0; bcnt--, track++)
+                    *track = '\0';
+            }
+        }
+        return outbuf;
+    }
+
+#if HAVE_ICONV
+    p1 = buf = cli_calloc(1, sz);
+    if (!(buf))
+        return NULL;
+
+    memcpy(buf, begin, sz);
+    inlen = sz;
+
+    /* encoding lookup if not specified */
+    if (!encoding) {
+        for (i = 0; i < NUMCODEPAGES; ++i) {
+            if (sctx->codepage == codepage_entries[i].codepage)
+                encoding = codepage_entries[i].encoding;
+            else if (sctx->codepage < codepage_entries[i].codepage) {
+                /* assuming sorted array */
+                break;
+            }
+        }
+
+        if (!encoding) {
+            cli_warnmsg("ole2_convert_utf: could not locate codepage encoding for %d\n", sctx->codepage);
+            sctx->flags |= OLE2_CODEPAGE_ERROR_NOTFOUND;
+            free(buf);
+            return NULL;
+        }
+    }
+
+    cd = iconv_open("UTF-8", encoding);
+    if (cd == (iconv_t)(-1)) {
+        cli_errmsg("ole2_convert_utf: could not initialize iconv\n");
+        sctx->flags |= OLE2_CODEPAGE_ERROR_UNINITED;
+    }
+    else {
+        offset = 0;
+        for (try = 1; try <= 3; ++try) {
+            /* charset to UTF-8 should never exceed sz*6 */
+            sz2 = (try*2) * sz;
+            /* use cli_realloc, reuse the buffer that has already been translated */
+            outbuf = (char *)cli_realloc(outbuf, sz2+1);
+            if (!outbuf) {
+                free(buf);
+                return NULL;
+            }
+
+            outlen = sz2 - offset;
+            p2 = outbuf + offset;
+
+            /* conversion */
+            nonrev = iconv(cd, &p1, &inlen, &p2, &outlen);
+
+            if (errno == EILSEQ) {
+                cli_dbgmsg("ole2_convert_utf: input buffer contains invalid character for its encoding\n");
+                sctx->flags |= OLE2_CODEPAGE_ERROR_INVALID;
+                break;
+            }
+            else if (errno == EINVAL && nonrev == (size_t)-1) {
+                cli_dbgmsg("ole2_convert_utf: input buffer contains incomplete multibyte character\n");
+                sctx->flags |= OLE2_CODEPAGE_ERROR_INCOMPLETE;
+                break;
+            }
+            else if (inlen == 0) {
+                //cli_dbgmsg("ole2_convert_utf: input buffer is successfully translated\n");
+                break;
+            }
+
+            //outbuf[sz2 - outlen] = '\0';
+            //cli_dbgmsg("%u %s\n", inlen, outbuf);
+
+            offset = sz2 - outlen;
+            if (try < 3)
+                cli_dbgmsg("ole2_convert_utf: outbuf is too small, resizing %llu -> %llu\n",
+                           (long long unsigned)((try*2) * sz), (long long unsigned)(((try+1)*2) * sz));
+        }
+
+        if (errno == E2BIG && nonrev == (size_t)-1) {
+            cli_dbgmsg("ole2_convert_utf: buffer could not be fully translated\n");
+            sctx->flags |= OLE2_CODEPAGE_ERROR_OUTBUFTOOSMALL;
+        }
+
+        outbuf[sz2 - outlen] = '\0';
+    }
+
+    iconv_close(cd);
+    free(buf);
+#endif
+    /* this should force base64 encoding if NULL */
+    return outbuf;
+}
+
+static int
+ole2_process_property(summary_ctx_t *sctx, unsigned char *databuf, uint32_t offset)
+{
+    uint16_t proptype, padding;
+    int ret = CL_SUCCESS;
+
+    if (cli_json_timeout_cycle_check(sctx->ctx, &(sctx->toval)) != CL_SUCCESS) {
+        sctx->flags |= OLE2_SUMMARY_FLAG_TIMEOUT;
+        return CL_ETIMEOUT;
+    }
+
+    if (offset+sizeof(proptype)+sizeof(padding) > sctx->pssize) {
+        sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+        return CL_EFORMAT;
+    }
+
+    memcpy(&proptype, databuf+offset, sizeof(proptype));
+    offset+=sizeof(proptype);
+    memcpy(&padding, databuf+offset, sizeof(padding));
+    offset+=sizeof(padding);
+    /* endian conversion */
+    proptype = sum16_endian_convert(proptype);
+
+    //cli_dbgmsg("proptype: 0x%04x\n", proptype);
+    if (padding != 0) {
+        cli_dbgmsg("ole2_process_property: invalid padding value, non-zero\n");
+        sctx->flags |= OLE2_SUMMARY_ERROR_INVALID_ENTRY;
+        return CL_EFORMAT;
+    }
+
+    switch (proptype) {
+    case PT_EMPTY:
+    case PT_NULL:
+        ret = cli_jsonnull(sctx->summary, sctx->propname);
+        break;
+    case PT_INT16:
+	{
+            int16_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum16_endian_convert(dout);
+
+            if (sctx->writecp) {
+                sctx->codepage = (uint16_t)dout;
+                ret = cli_jsonint(sctx->summary, sctx->propname, sctx->codepage);
+            }
+            else
+                ret = cli_jsonint(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_INT32:
+    case PT_INT32v1:
+	{
+            int32_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum32_endian_convert(dout);
+
+            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_FLOAT32: /* review this please */
+	{
+            float dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum32_endian_convert(dout);
+
+            ret = cli_jsondouble(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_DATE:
+    case PT_DOUBLE64: /* review this please */
+	{
+            double dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum64_endian_convert(dout);
+
+            ret = cli_jsondouble(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_BOOL:
+	{
+            uint16_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* no need for endian conversion */
+
+            ret = cli_jsonbool(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_INT8v1:
+	{
+            int8_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* no need for endian conversion */
+
+            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_UINT8:
+	{
+            uint8_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* no need for endian conversion */
+
+            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_UINT16:
+	{
+            uint16_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum16_endian_convert(dout);
+
+            if (sctx->writecp)
+                sctx->codepage = dout;
+
+            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_UINT32:
+    case PT_UINT32v1:
+	{
+            uint32_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum32_endian_convert(dout);
+
+            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_INT64:
+	{
+            int64_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum64_endian_convert(dout);
+
+            ret = cli_jsonint64(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_UINT64:
+	{
+            uint64_t dout;
+            if (offset+sizeof(dout) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&dout, databuf+offset, sizeof(dout));
+            offset+=sizeof(dout);
+            /* endian conversion */
+            dout = sum64_endian_convert(dout);
+
+            ret = cli_jsonint64(sctx->summary, sctx->propname, dout);
+            break;
+	}
+    case PT_BSTR:
+    case PT_LPSTR:
+        if (sctx->codepage == 0) {
+            cli_dbgmsg("ole2_propset_json: current codepage is unknown, cannot parse char stream\n");
+            sctx->flags |= OLE2_SUMMARY_FLAG_CODEPAGE;
+        }
+        else {
+            uint32_t strsize;
+            char *outstr, *outstr2;
+
+            if (offset+sizeof(strsize) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+
+            memcpy(&strsize, databuf+offset, sizeof(strsize));
+            offset+=sizeof(strsize);
+            /* endian conversion? */
+            strsize = sum32_endian_convert(strsize);
+
+            if (offset+strsize > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+
+            /* limitation on string length */
+            if (strsize > PROPSTRLIMIT) {
+                cli_dbgmsg("ole2_process_property: property string sized %lu truncated to size %lu\n",
+                           (unsigned long)strsize, (unsigned long)PROPSTRLIMIT);
+                sctx->flags |= OLE2_SUMMARY_FLAG_TRUNC_STR;
+                strsize = PROPSTRLIMIT;
+            }
+
+            outstr = cli_calloc(strsize+1, 1); /* last char must be NULL */
+            if (!outstr) {
+                return CL_EMEM;
+            }
+            strncpy(outstr, (const char *)(databuf+offset), strsize);
+
+            /* conversion of various encodings to UTF-8 */
+            outstr2 = ole2_convert_utf(sctx, outstr, strsize, NULL);
+            if (!outstr2) {
+                /* use base64 encoding when all else fails! */
+                char b64jstr[PROPSTRLIMIT];
+
+                /* outstr2 should be 4/3 times the original (rounded up) */
+                outstr2 = cl_base64_encode(outstr, strsize);
+                if (!outstr2) {
+                    cli_dbgmsg("ole2_process_property: failed to convert to base64 string\n");
+                    return CL_EMEM;
+                }
+
+                snprintf(b64jstr, PROPSTRLIMIT, "%s_base64", sctx->propname);
+                ret = cli_jsonbool(sctx->summary, b64jstr, 1);
+                if (ret != CL_SUCCESS)
+                    return ret;
+            }
+
+            ret = cli_jsonstr(sctx->summary, sctx->propname, outstr2);
+            free(outstr);
+            free(outstr2);
+        }
+        break;
+    case PT_LPWSTR:
+	{
+            uint32_t strsize;
+            char *outstr, *outstr2;
+
+            if (offset+sizeof(strsize) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&strsize, databuf+offset, sizeof(strsize));
+            offset+=sizeof(strsize);
+            /* endian conversion; wide strings are by length, not size (x2) */
+            strsize = sum32_endian_convert(strsize)*2;
+
+            /* limitation on string length */
+            if (strsize > (2*PROPSTRLIMIT)) {
+                cli_dbgmsg("ole2_process_property: property string sized %lu truncated to size %lu\n",
+                           (unsigned long)strsize, (unsigned long)(2*PROPSTRLIMIT));
+                sctx->flags |= OLE2_SUMMARY_FLAG_TRUNC_STR;
+                strsize = (2*PROPSTRLIMIT);
+            }
+
+            if (offset+strsize > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            outstr = cli_calloc(strsize+2, 1); /* last two chars must be NULL */
+            if (!outstr) {
+                return CL_EMEM;
+            }
+            memcpy(outstr, (const char *)(databuf+offset), strsize);
+            /* conversion of 16-width char strings (UTF-16 or UTF-16LE??) to UTF-8 */
+            outstr2 = ole2_convert_utf(sctx, outstr, strsize, UTF16_MS);
+            if (!outstr2) {
+                /* use base64 encoding when all else fails! */
+                char b64jstr[PROPSTRLIMIT];
+
+                outstr2 = cl_base64_encode(outstr, strsize);
+                if (!outstr2) {
+                    free(outstr);
+                    return CL_EMEM;
+                }
+
+                snprintf(b64jstr, PROPSTRLIMIT, "%s_base64", sctx->propname);
+                ret = cli_jsonbool(sctx->summary, b64jstr, 1);
+                if (ret != CL_SUCCESS)
+                    return ret;
+            }
+
+            ret = cli_jsonstr(sctx->summary, sctx->propname, outstr2);
+            free(outstr);
+            free(outstr2);
+            break;
+	}
+    case PT_FILETIME:
+	{
+            uint32_t ltime, htime;
+            uint64_t wtime = 0, utime =0;
+
+            if (offset+sizeof(ltime)+sizeof(htime) > sctx->pssize) {
+                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+                return CL_EFORMAT;
+            }
+            memcpy(&ltime, databuf+offset, sizeof(ltime));
+            offset+=sizeof(ltime);
+            memcpy(&htime, databuf+offset, sizeof(htime));
+            offset+=sizeof(ltime);
+            ltime = sum32_endian_convert(ltime);
+            htime = sum32_endian_convert(htime);
+
+            /* UNIX timestamp formatting */
+            wtime = htime;
+            wtime <<= 32;
+            wtime |= ltime;
+
+            utime = wtime / 10000000;
+            utime -= 11644473600LL;
+
+            if ((uint32_t)((utime & 0xFFFFFFFF00000000) >> 32)) {
+                cli_dbgmsg("ole2_process_property: UNIX timestamp is larger than 32-bit number\n");
+            }
+            else {
+                ret = cli_jsonint(sctx->summary, sctx->propname, (uint32_t)(utime & 0xFFFFFFFF));
+            }
+            break;
+	}
+    default:
+        cli_dbgmsg("ole2_process_property: unhandled property type 0x%04x for %s property\n", 
+                   proptype, sctx->propname);
+        sctx->flags |= OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE;
+    }
+
+    return ret;
+}
+
+static void ole2_translate_docsummary_propid(summary_ctx_t *sctx, uint32_t propid)
+{
+    switch(propid) {
+    case DSPID_CODEPAGE:
+        sctx->writecp = 1; /* must be set ONLY for codepage */
+        sctx->propname = "CodePage";
+        break;
+    case DSPID_CATEGORY:
+        sctx->propname = "Category";
+        break;
+    case DSPID_PRESFORMAT:
+        sctx->propname = "PresentationTarget";
+        break;
+    case DSPID_BYTECOUNT:
+        sctx->propname = "Bytes";
+        break;
+    case DSPID_LINECOUNT:
+        sctx->propname = "Lines";
+        break;
+    case DSPID_PARCOUNT:
+        sctx->propname = "Paragraphs";
+        break;
+    case DSPID_SLIDECOUNT:
+        sctx->propname = "Slides";
+        break;
+    case DSPID_NOTECOUNT:
+        sctx->propname = "Notes";
+        break;
+    case DSPID_HIDDENCOUNT:
+        sctx->propname = "HiddenSlides";
+        break;
+    case DSPID_MMCLIPCOUNT:
+        sctx->propname = "MMClips";
+        break;
+    case DSPID_SCALE:
+        sctx->propname = "Scale";
+        break;
+    case DSPID_HEADINGPAIR: /* VT_VARIANT | VT_VECTOR */
+        sctx->propname = "HeadingPairs";
+        break;
+    case DSPID_DOCPARTS:    /* VT_VECTOR | VT_LPSTR */
+        sctx->propname = "DocPartTitles";
+        break;
+    case DSPID_MANAGER:
+        sctx->propname = "Manager";
+        break;
+    case DSPID_COMPANY:
+        sctx->propname = "Company";
+        break;
+    case DSPID_LINKSDIRTY:
+        sctx->propname = "LinksDirty";
+        break;
+    case DSPID_CCHWITHSPACES:
+        sctx->propname = "Char&WSCount";
+        break;
+    case DSPID_SHAREDDOC:   /* SHOULD BE FALSE! */
+        sctx->propname = "SharedDoc";
+        break;
+    case DSPID_LINKBASE:    /* moved to user-defined */
+        sctx->propname = "LinkBase";
+        break;
+    case DSPID_HLINKS:      /* moved to user-defined */
+        sctx->propname = "HyperLinks";
+        break;
+    case DSPID_HYPERLINKSCHANGED:
+        sctx->propname = "HyperLinksChanged";
+        break;
+    case DSPID_VERSION:
+        sctx->propname = "Version";
+        break;
+    case DSPID_DIGSIG:
+        sctx->propname = "DigitalSig";
+        break;
+    case DSPID_CONTENTTYPE:
+        sctx->propname = "ContentType";
+        break;
+    case DSPID_CONTENTSTATUS:
+        sctx->propname = "ContentStatus";
+        break;
+    case DSPID_LANGUAGE:
+        sctx->propname = "Language";
+        break;
+    case DSPID_DOCVERSION:
+        sctx->propname = "DocVersion";
+        break;
+    default:
+        cli_dbgmsg("ole2_docsum_propset_json: unrecognized propid!\n");
+        sctx->flags |= OLE2_SUMMARY_FLAG_UNKNOWN_PROPID;
+    }
+}
+
+static void ole2_translate_summary_propid(summary_ctx_t *sctx, uint32_t propid)
+{
+    switch(propid) {
+    case SPID_CODEPAGE:
+        sctx->writecp = 1; /* must be set ONLY for codepage */
+        sctx->propname = "CodePage";
+        break;
+    case SPID_TITLE:
+        sctx->propname = "Title";
+        break;
+    case SPID_SUBJECT:
+        sctx->propname = "Subject";
+        break;
+    case SPID_AUTHOR:
+        sctx->propname = "Author";
+        break;
+    case SPID_KEYWORDS:
+        sctx->propname = "Keywords";
+        break;
+    case SPID_COMMENTS:
+        sctx->propname = "Comments";
+        break;
+    case SPID_TEMPLATE:
+        sctx->propname = "Template";
+        break;
+    case SPID_LASTAUTHOR:
+        sctx->propname = "LastAuthor";
+        break;
+    case SPID_REVNUMBER:
+        sctx->propname = "RevNumber";
+        break;
+    case SPID_EDITTIME:
+        sctx->propname = "EditTime";
+        break;
+    case SPID_LASTPRINTED:
+        sctx->propname = "LastPrinted";
+        break;
+    case SPID_CREATEDTIME:
+        sctx->propname = "CreatedTime";
+        break;
+    case SPID_MODIFIEDTIME:
+        sctx->propname = "ModifiedTime";
+        break;
+    case SPID_PAGECOUNT:
+        sctx->propname = "PageCount";
+        break;
+    case SPID_WORDCOUNT:
+        sctx->propname = "WordCount";
+        break;
+    case SPID_CHARCOUNT:
+        sctx->propname = "CharCount";
+        break;
+    case SPID_THUMBNAIL:
+        sctx->propname = "Thumbnail";
+        break;
+    case SPID_APPNAME:
+        sctx->propname = "AppName";
+        break;
+    case SPID_SECURITY:
+        sctx->propname = "Security";
+        break;
+    default:
+        cli_dbgmsg("ole2_translate_summary_propid: unrecognized propid!\n");
+        sctx->flags |= OLE2_SUMMARY_FLAG_UNKNOWN_PROPID;
+    }
+}
+
+static int ole2_summary_propset_json(summary_ctx_t *sctx, off_t offset)
+{
+    unsigned char *hdr, *ps;
+    uint32_t numprops, limitprops;
+    off_t foff = offset, psoff = 0;
+    uint32_t poffset;
+    int ret;
+    unsigned int i;
+
+    cli_dbgmsg("in ole2_summary_propset_json\n");
+
+    /* summary ctx propset-specific setup*/
+    sctx->codepage = 0;
+    sctx->writecp = 0;
+    sctx->propname = NULL;
+
+    /* examine property set metadata */
+    if ((foff+(2*sizeof(uint32_t))) > sctx->maplen) {
+        sctx->flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
+        return CL_EFORMAT;
+    }
+    hdr = (unsigned char*)fmap_need_off_once(sctx->sfmap, foff, (2*sizeof(uint32_t)));
+    if (!hdr) {
+        sctx->flags |= OLE2_SUMMARY_ERROR_DATABUF;
+        return CL_EREAD;
+    }
+    //foff+=(2*sizeof(uint32_t)); // keep foff pointing to start of propset segment
+    psoff+=(2*sizeof(uint32_t));
+    memcpy(&(sctx->pssize), hdr, sizeof(sctx->pssize));
+    memcpy(&numprops, hdr+sizeof(sctx->pssize), sizeof(numprops));
+    /* endian conversion */
+    sctx->pssize = sum32_endian_convert(sctx->pssize);
+    numprops = sum32_endian_convert(numprops);
+    cli_dbgmsg("ole2_summary_propset_json: pssize: %u, numprops: %u\n", sctx->pssize, numprops);
+    if (numprops > PROPCNTLIMIT) {
+        sctx->flags |= OLE2_SUMMARY_LIMIT_PROPS;
+        limitprops = PROPCNTLIMIT;
+    }
+    else {
+        limitprops = numprops;
+    }
+    cli_dbgmsg("ole2_summary_propset_json: processing %u of %u (%u max) propeties\n",
+               limitprops, numprops, PROPCNTLIMIT);
+
+    /* extract remaining fragment of propset */
+    if ((size_t)(foff+(sctx->pssize)) > (size_t)(sctx->maplen)) {
+        sctx->flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
+        return CL_EFORMAT;
+    }
+    ps = (unsigned char*)fmap_need_off_once(sctx->sfmap, foff, sctx->pssize);
+    if (!ps) {
+        sctx->flags |= OLE2_SUMMARY_ERROR_DATABUF;
+        return CL_EREAD;
+    }
+
+    /* iterate over the properties */
+    for (i = 0; i < limitprops; ++i) {
+        uint32_t propid, propoff;
+
+        if (psoff+sizeof(propid)+sizeof(poffset) > sctx->pssize) {
+            sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
+            return CL_EFORMAT;
+        }
+        memcpy(&propid, ps+psoff, sizeof(propid));
+        psoff+=sizeof(propid);
+        memcpy(&propoff, ps+psoff, sizeof(propoff));
+        psoff+=sizeof(propoff);
+        /* endian conversion */
+        propid = sum32_endian_convert(propid);
+        propoff = sum32_endian_convert(propoff);
+        cli_dbgmsg("ole2_summary_propset_json: propid: 0x%08x, propoff: %u\n", propid, propoff);
+
+        sctx->propname = NULL; sctx->writecp = 0;
+        if (!sctx->mode)
+            ole2_translate_summary_propid(sctx, propid);
+        else
+            ole2_translate_docsummary_propid(sctx, propid);
+
+        if (sctx->propname != NULL) {
+            ret = ole2_process_property(sctx, ps, propoff);
+            if (ret != CL_SUCCESS)
+                return ret;
+        }
+        else {
+            /* add unknown propid flag */
+        }
+    }
+
+    return CL_SUCCESS;
+}
+
+static int cli_ole2_summary_json_cleanup(summary_ctx_t *sctx, int retcode)
+{
+    json_object *jarr;
+
+    cli_dbgmsg("in cli_ole2_summary_json_cleanup: %d[%x]\n", retcode, sctx->flags);
+
+    if (sctx->sfmap) {
+        funmap(sctx->sfmap);
+    }
+
+    if (sctx->flags) {
+        jarr = cli_jsonarray(sctx->summary, "ParseErrors");
+
+        /* summary errors */
+        if (sctx->flags & OLE2_SUMMARY_ERROR_TOOSMALL) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_TOOSMALL");
+        }
+        if (sctx->flags & OLE2_SUMMARY_ERROR_OOB) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_OOB");
+        }
+        if (sctx->flags & OLE2_SUMMARY_ERROR_DATABUF) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_DATABUF");
+        }
+        if (sctx->flags & OLE2_SUMMARY_ERROR_INVALID_ENTRY) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_INVALID_ENTRY");
+        }
+        if (sctx->flags & OLE2_SUMMARY_LIMIT_PROPS) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_LIMIT_PROPS");
+        }
+        if (sctx->flags & OLE2_SUMMARY_FLAG_TIMEOUT) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_TIMEOUT");
+        }
+        if (sctx->flags & OLE2_SUMMARY_FLAG_CODEPAGE) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_CODEPAGE");
+        }
+        if (sctx->flags & OLE2_SUMMARY_FLAG_UNKNOWN_PROPID) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_UNKNOWN_PROPID");
+        }
+        if (sctx->flags & OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE");
+        }
+        if (sctx->flags & OLE2_SUMMARY_FLAG_TRUNC_STR) {
+            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_TRUNC_STR");
+        }
+
+        /* codepage translation errors */
+        if (sctx->flags & OLE2_CODEPAGE_ERROR_NOTFOUND) {
+            cli_jsonstr(jarr, NULL, "OLE2_CODEPAGE_ERROR_NOTFOUND");
+        }
+        if (sctx->flags & OLE2_CODEPAGE_ERROR_UNINITED) {
+            cli_jsonstr(jarr, NULL, "OLE2_CODEPAGE_ERROR_UNINITED");
+        }
+        if (sctx->flags & OLE2_CODEPAGE_ERROR_INVALID) {
+            cli_jsonstr(jarr, NULL, "OLE2_CODEPAGE_ERROR_INVALID");
+        }
+        if (sctx->flags & OLE2_CODEPAGE_ERROR_INCOMPLETE) {
+            cli_jsonstr(jarr, NULL, "OLE2_CODEPAGE_ERROR_INCOMPLETE");
+        }
+        if (sctx->flags & OLE2_CODEPAGE_ERROR_OUTBUFTOOSMALL) {
+            cli_jsonstr(jarr, NULL, "OLE2_CODEPAGE_ERROR_OUTBUFTOOSMALL");
+        }
+    }
+
+    return retcode;
+}
+
+int cli_ole2_summary_json(cli_ctx *ctx, int fd, int mode)
+{
+    summary_ctx_t sctx;
+    STATBUF statbuf;
+    off_t foff = 0;
+    unsigned char *databuf;
+    summary_stub_t sumstub;
+    propset_entry_t pentry;
+    int ret = CL_SUCCESS;
+
+    cli_dbgmsg("in cli_ole2_summary_json\n");
+
+    /* preliminary sanity checks */
+    if (ctx == NULL) {
+        return CL_ENULLARG;
+    }
+
+    if (fd < 0) {
+        cli_dbgmsg("ole2_summary_json: invalid file descriptor\n");
+        return CL_ENULLARG; /* placeholder */
+    }
+
+    if (mode != 0 && mode != 1) {
+        cli_dbgmsg("ole2_summary_json: invalid mode specified\n");
+        return CL_ENULLARG; /* placeholder */
+    }
+
+    /* summary ctx setup */
+    memset(&sctx, 0, sizeof(sctx));
+    sctx.ctx = ctx;
+    sctx.mode = mode;
+
+    if (FSTAT(fd, &statbuf) == -1) {
+        cli_dbgmsg("ole2_summary_json: cannot stat file descriptor\n");
+        return CL_ESTAT;
+    }
+
+    sctx.sfmap = fmap(fd, 0, statbuf.st_size);
+    if (!sctx.sfmap) {
+        cli_dbgmsg("ole2_summary_json: failed to get fmap\n");
+        return CL_EMAP;
+    }
+    sctx.maplen = sctx.sfmap->len;
+    cli_dbgmsg("ole2_summary_json: streamsize: %u\n", sctx.maplen);
+
+    if (!mode)
+        sctx.summary = cli_jsonobj(ctx->wrkproperty, "SummaryInfo");
+    else
+        sctx.summary = cli_jsonobj(ctx->wrkproperty, "DocSummaryInfo");
+    if (!sctx.summary) {
+        cli_errmsg("ole2_summary_json: no memory for json object.\n");
+        return cli_ole2_summary_json_cleanup(&sctx, CL_EMEM);
+    }
+
+    sctx.codepage = 0;
+    sctx.writecp = 0;
+
+    /* acquire property stream metadata */
+    if (sctx.maplen < sizeof(summary_stub_t)) {
+        sctx.flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
+        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);
+    }
+    databuf = (unsigned char*)fmap_need_off_once(sctx.sfmap, foff, sizeof(summary_stub_t));
+    if (!databuf) {
+        sctx.flags |= OLE2_SUMMARY_ERROR_DATABUF;
+        return cli_ole2_summary_json_cleanup(&sctx, CL_EREAD);
+    }
+    foff += sizeof(summary_stub_t);
+    memcpy(&sumstub, databuf, sizeof(summary_stub_t));
+
+    /* endian conversion and checks */
+    sumstub.byte_order = le16_to_host(sumstub.byte_order);
+    if (sumstub.byte_order != 0xfffe) {
+        cli_dbgmsg("ole2_summary_json: byteorder 0x%x is invalid\n", sumstub.byte_order);
+        sctx.flags |= OLE2_SUMMARY_ERROR_INVALID_ENTRY;
+        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);;
+    }
+    sumstub.version = sum16_endian_convert(sumstub.version); /*unused*/
+    sumstub.system = sum32_endian_convert(sumstub.system); /*unused*/
+    sumstub.num_propsets = sum32_endian_convert(sumstub.num_propsets);
+    if (sumstub.num_propsets != 1 && sumstub.num_propsets != 2) {
+        cli_dbgmsg("ole2_summary_json: invalid number of property sets\n");
+        sctx.flags |= OLE2_SUMMARY_ERROR_INVALID_ENTRY;
+        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);
+    }
+
+    cli_dbgmsg("ole2_summary_json: byteorder 0x%x\n", sumstub.byte_order);
+    cli_dbgmsg("ole2_summary_json: %u property set(s) detected\n", sumstub.num_propsets);
+
+    /* first property set (index=0) is always SummaryInfo or DocSummaryInfo */
+    if ((sctx.maplen-foff) < sizeof(propset_entry_t)) {
+        sctx.flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
+        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);
+    }
+    databuf = (unsigned char*)fmap_need_off_once(sctx.sfmap, foff, sizeof(propset_entry_t));
+    if (!databuf) {
+        sctx.flags |= OLE2_SUMMARY_ERROR_DATABUF;
+        return cli_ole2_summary_json_cleanup(&sctx, CL_EREAD);
+    }
+    foff += sizeof(propset_entry_t);
+    memcpy(&pentry, databuf, sizeof(propset_entry_t));
+    /* endian conversion */
+    pentry.offset = sum32_endian_convert(pentry.offset);
+
+    if ((ret = ole2_summary_propset_json(&sctx, pentry.offset)) != CL_SUCCESS) {
+        return cli_ole2_summary_json_cleanup(&sctx, ret);
+    }
+
+    /* second property set (index=1) is always a custom property set (if present) */
+    if (sumstub.num_propsets == 2) {
+        cli_jsonbool(ctx->wrkproperty, "HasUserDefinedProperties", 1);
+    }
+
+    return cli_ole2_summary_json_cleanup(&sctx, CL_SUCCESS);
+}
+#endif /* HAVE_JSON */
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/msdoc.h clamav-0.98.5+dfsg/libclamav/msdoc.h
--- clamav-0.98.5~rc1+dfsg/libclamav/msdoc.h	1969-12-31 19:00:00.000000000 -0500
+++ clamav-0.98.5+dfsg/libclamav/msdoc.h	2014-11-13 17:30:43.000000000 -0500
@@ -0,0 +1,336 @@
+/*
+ *  Extract component parts of OLE2 files (e.g. MS Office Documents)
+ *
+ *  Copyright (C) 2007-2008 Sourcefire, Inc.
+ *
+ *  Authors: Trog
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ */
+
+#ifndef __MSDOC_H
+#define __MSDOC_H
+
+#include "others.h"
+#include "uniq.h"
+
+/* Summary and Document Information Parsing to JSON */
+#if HAVE_JSON
+
+#define PROPCNTLIMIT 25
+#define PROPSTRLIMIT 256 /* affects property strs, NOT sanitized strs (may result in a buffer allocating PROPSTRLIMIT*6) */
+#define UTF16_MS "UTF-16LE"
+
+#define sum16_endian_convert(v) le16_to_host((uint16_t)(v))
+#define sum32_endian_convert(v) le32_to_host((uint32_t)(v))
+#define sum64_endian_convert(v) le64_to_host((uint64_t)(v))
+
+enum summary_pidsi {
+    SPID_CODEPAGE   = 0x00000001,
+    SPID_TITLE      = 0x00000002,
+    SPID_SUBJECT    = 0x00000003,
+    SPID_AUTHOR     = 0x00000004,
+    SPID_KEYWORDS   = 0x00000005,
+    SPID_COMMENTS   = 0x00000006,
+    SPID_TEMPLATE   = 0x00000007,
+    SPID_LASTAUTHOR = 0x00000008,
+    SPID_REVNUMBER  = 0x00000009,
+    SPID_EDITTIME   = 0x0000000A,
+    SPID_LASTPRINTED  = 0x0000000B,
+    SPID_CREATEDTIME  = 0x0000000C,
+    SPID_MODIFIEDTIME = 0x0000000D,
+    SPID_PAGECOUNT = 0x0000000E,
+    SPID_WORDCOUNT = 0x0000000F,
+    SPID_CHARCOUNT = 0x00000010,
+    SPID_THUMBNAIL = 0x00000011,
+    SPID_APPNAME   = 0x00000012,
+    SPID_SECURITY  = 0x00000013
+};
+
+enum docsum_pidsi {
+    DSPID_CODEPAGE    = 0x00000001,
+    DSPID_CATEGORY    = 0x00000002,
+    DSPID_PRESFORMAT  = 0x00000003,
+    DSPID_BYTECOUNT   = 0x00000004,
+    DSPID_LINECOUNT   = 0x00000005,
+    DSPID_PARCOUNT    = 0x00000006,
+    DSPID_SLIDECOUNT  = 0x00000007,
+    DSPID_NOTECOUNT   = 0x00000008,
+    DSPID_HIDDENCOUNT = 0x00000009,
+    DSPID_MMCLIPCOUNT = 0x0000000A,
+    DSPID_SCALE       = 0x0000000B,
+    DSPID_HEADINGPAIR = 0x0000000C, /* VT_VARIANT | VT_VECTOR */
+    DSPID_DOCPARTS    = 0x0000000D, /* VT_VECTOR | VT_LPSTR */
+    DSPID_MANAGER     = 0x0000000E,
+    DSPID_COMPANY     = 0x0000000F,
+    DSPID_LINKSDIRTY  = 0x00000010,
+    DSPID_CCHWITHSPACES = 0x00000011,
+    DSPID_SHAREDDOC   = 0x00000013, /* must be false */
+    DSPID_LINKBASE    = 0x00000014, /* moved to user-defined */
+    DSPID_HLINKS      = 0x00000015, /* moved to user-defined */
+    DSPID_HYPERLINKSCHANGED = 0x00000016,
+    DSPID_VERSION     = 0x00000017,
+    DSPID_DIGSIG      = 0x00000018,
+    DSPID_CONTENTTYPE   = 0x0000001A,
+    DSPID_CONTENTSTATUS = 0x0000001B,
+    DSPID_LANGUAGE      = 0x0000001C,
+    DSPID_DOCVERSION    = 0x0000001D
+};
+
+enum property_type {
+    PT_EMPTY    = 0x0000,
+    PT_NULL     = 0x0001,
+    PT_INT16    = 0x0002,
+    PT_INT32    = 0x0003,
+    PT_FLOAT32  = 0x0004,
+    PT_DOUBLE64 = 0x0005,
+    PT_DATE     = 0x0007,
+    PT_BSTR     = 0x0008,
+    PT_BOOL    = 0x000B,
+    PT_INT8v1  = 0x0010,
+    PT_UINT8   = 0x0011,
+    PT_UINT16  = 0x0012,
+    PT_UINT32  = 0x0013,
+    PT_INT64   = 0x0014,
+    PT_UINT64  = 0x0015,
+    PT_INT32v1  = 0x0016,
+    PT_UINT32v1 = 0x0017,
+    PT_LPSTR  = 0x001E,
+    PT_LPWSTR = 0x001F,
+    PT_FILETIME = 0x0040,
+	
+    /* More Types not currently handled */
+};
+
+typedef struct summary_stub {
+    uint16_t byte_order;
+    uint16_t version;
+    uint32_t system; /* implementation-specific */
+    uint8_t CLSID[16];
+
+    uint32_t num_propsets; /* 1 or 2 */
+} summary_stub_t;
+
+typedef struct propset_summary_entry {
+    uint8_t FMTID[16];
+    uint32_t offset;
+} propset_entry_t;
+
+/* error codes */
+#define OLE2_SUMMARY_ERROR_TOOSMALL      0x00000001
+#define OLE2_SUMMARY_ERROR_OOB           0x00000002
+#define OLE2_SUMMARY_ERROR_DATABUF       0x00000004
+#define OLE2_SUMMARY_ERROR_INVALID_ENTRY 0x00000008
+#define OLE2_SUMMARY_LIMIT_PROPS         0x00000010
+#define OLE2_SUMMARY_FLAG_TIMEOUT        0x00000020
+#define OLE2_SUMMARY_FLAG_CODEPAGE       0x00000040
+#define OLE2_SUMMARY_FLAG_UNKNOWN_PROPID 0x00000080
+#define OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE 0x00000100
+#define OLE2_SUMMARY_FLAG_TRUNC_STR      0x00000200
+
+#define OLE2_CODEPAGE_ERROR_NOTFOUND     0x00000400
+#define OLE2_CODEPAGE_ERROR_UNINITED     0x00000800
+#define OLE2_CODEPAGE_ERROR_INVALID      0x00001000
+#define OLE2_CODEPAGE_ERROR_INCOMPLETE   0x00002000
+#define OLE2_CODEPAGE_ERROR_OUTBUFTOOSMALL 0x00002000
+
+/* metadata structures */
+typedef struct summary_ctx {
+    cli_ctx *ctx;
+    int mode;
+    fmap_t *sfmap;
+    json_object *summary;
+    size_t maplen;
+    uint32_t flags;
+
+    /* propset metadata */
+    uint32_t pssize; /* track from propset start, not tail start */
+    uint16_t codepage;
+    int writecp;
+
+    /* property metadata */
+    const char *propname;
+
+    /* timeout meta */
+    int toval;
+} summary_ctx_t;
+
+/* string conversion */
+struct codepage_entry {
+    int16_t codepage;
+    const char *encoding;
+};
+
+#define NUMCODEPAGES sizeof(codepage_entries)/sizeof(struct codepage_entry)
+/* MAINTAIN - the array in codepage value sorted order */
+static const struct codepage_entry codepage_entries[] = {
+    { 37,    "IBM037" },      /* IBM EBCDIC US-Canada */
+    { 437,   "IBM437" },      /* OEM United States */
+    { 500,   "IBM500" },      /* IBM EBCDIC International */
+    { 708,   "ASMO-708" },    /* Arabic (ASMO 708) */
+    { 709,   NULL },          /* Arabic (ASMO-449+, BCON V4) */
+    { 710,   NULL },          /* Arabic - Transparent Arabic */
+    { 720,   NULL },          /* Arabic (Transparent ASMO); Arabic (DOS) */
+    { 737,   NULL },          /* OEM Greek (formerly 437G); Greek (DOS) */
+    { 775,   "IBM775" },      /* OEM Baltic; Baltic (DOS) */
+    { 850,   "IBM850" },      /* OEM Multilingual Latin 1; Western European (DOS) */
+    { 852,   "IBM852" },      /* OEM Latin 2; Central European (DOS) */
+    { 855,   "IBM855" },      /* OEM Cyrillic (primarily Russian) */
+    { 857,   "IBM857" },      /* OEM Turkish; Turkish (DOS) */
+    { 858,   NULL },          /* OEM Multilingual Latin 1 + Euro symbol */
+    { 860,   "IBM860" },      /* OEM Portuguese; Portuguese (DOS) */
+    { 861,   "IBM861" },      /* OEM Icelandic; Icelandic (DOS) */
+    { 862,   NULL },          /* OEM Hebrew; Hebrew (DOS) */
+    { 863,   "IBM863" },      /* OEM French Canadian; French Canadian (DOS) */
+    { 864,   "IBM864" },      /* OEM Arabic; Arabic (864) */
+    { 865,   "IBM865" },      /* OEM Nordic; Nordic (DOS) */
+    { 866,   "CP866" },       /* OEM Russian; Cyrillic (DOS) */
+    { 869,   "IBM869" },      /* OEM Modern Greek; Greek, Modern (DOS) */
+    { 870,   "IBM870" },      /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */
+    { 874,   "WINDOWS-874" }, /* ANSI/OEM Thai (ISO 8859-11); Thai (Windows) */
+    { 875,   "CP875" },       /* IBM EBCDIC Greek Modern */
+    { 932,   "SHIFT_JIS" },   /* ANSI/OEM Japanese; Japanese (Shift-JIS) */
+    { 936,   "GB2312" },      /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */
+    { 949,   NULL },          /* ANSI/OEM Korean (Unified Hangul Code) */
+    { 950,   "BIG5" },        /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */
+    { 1026,  "IBM1026" },     /* IBM EBCDIC Turkish (Latin 5) */
+    { 1047,  NULL },          /* IBM EBCDIC Latin 1/Open System */
+    { 1140,  NULL },          /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */
+    { 1141,  NULL },          /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */
+    { 1142,  NULL },          /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */
+    { 1143,  NULL },          /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */
+    { 1144,  NULL },          /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */
+    { 1145,  NULL },          /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */
+    { 1146,  NULL },          /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */
+    { 1147,  NULL },          /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */
+    { 1148,  NULL },          /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */
+    { 1149,  NULL },          /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */
+    { 1200,  "UTF-16LE" },    /* Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications */
+    { 1201,  "UTF-16BE" },    /* Unicode UTF-16, big endian byte order; available only to managed applications */
+    { 1250,  "WINDOWS-1250" }, /* ANSI Central European; Central European (Windows) */
+    { 1251,  "WINDOWS-1251" }, /* ANSI Cyrillic; Cyrillic (Windows) */
+    { 1252,  "WINDOWS-1252" }, /* ANSI Latin 1; Western European (Windows) */
+    { 1253,  "WINDOWS-1253" }, /* ANSI Greek; Greek (Windows) */
+    { 1254,  "WINDOWS-1254" }, /* ANSI Turkish; Turkish (Windows) */
+    { 1255,  "WINDOWS-1255" }, /* ANSI Hebrew; Hebrew (Windows) */
+    { 1256,  "WINDOWS-1256" }, /* ANSI Arabic; Arabic (Windows) */
+    { 1257,  "WINDOWS-1257" }, /* ANSI Baltic; Baltic (Windows) */
+    { 1258,  "WINDOWS-1258" }, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */
+    { 1361,  "JOHAB" },       /* Korean (Johab) */
+    { 10000, "MACINTOSH" },   /* MAC Roman; Western European (Mac) */
+    { 10001, NULL },          /* Japanese (Mac) */
+    { 10002, NULL },          /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */
+    { 10003, NULL },          /* Korean (Mac) */
+    { 10004, NULL },          /* Arabic (Mac) */
+    { 10005, NULL },          /* Hebrew (Mac) */
+    { 10006, NULL },          /* Greek (Mac) */
+    { 10007, NULL },          /* Cyrillic (Mac) */
+    { 10008, NULL },          /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */
+    { 10010, NULL },          /* Romanian (Mac) */
+    { 10017, NULL },          /* Ukrainian (Mac) */
+    { 10021, NULL },          /* Thai (Mac) */
+    { 10029, NULL },          /* MAC Latin 2; Central European (Mac) */
+    { 10079, NULL },          /* Icelandic (Mac) */
+    { 10081, NULL },          /* Turkish (Mac) */
+    { 10082, NULL },          /* Croatian (Mac) */
+    { 12000, "UTF-32LE" },    /* Unicode UTF-32, little endian byte order; available only to managed applications */
+    { 12001, "UTF-32BE" },    /* Unicode UTF-32, big endian byte order; available only to managed applications */
+    { 20000, NULL },          /* CNS Taiwan; Chinese Traditional (CNS) */
+    { 20001, NULL },          /* TCA Taiwan */
+    { 20002, NULL },          /* Eten Taiwan; Chinese Traditional (Eten) */
+    { 20003, NULL },          /* IBM5550 Taiwan */
+    { 20004, NULL },          /* TeleText Taiwan */
+    { 20005, NULL },          /* Wang Taiwan */
+    { 20105, NULL },          /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */
+    { 20106, NULL },          /* IA5 German (7-bit) */
+    { 20107, NULL },          /* IA5 Swedish (7-bit) */
+    { 20108, NULL },          /* IA5 Norwegian (7-bit) */
+    { 20127, "US-ASCII" },    /* US-ASCII (7-bit) */
+    { 20261, NULL },          /* T.61 */
+    { 20269, NULL },          /* ISO 6937 Non-Spacing Accent */
+    { 20273, "IBM273" },      /* IBM EBCDIC Germany */
+    { 20277, "IBM277" },      /* IBM EBCDIC Denmark-Norway */
+    { 20278, "IBM278" },      /* IBM EBCDIC Finland-Sweden */
+    { 20280, "IBM280" },      /* IBM EBCDIC Italy */
+    { 20284, "IBM284" },      /* IBM EBCDIC Latin America-Spain */
+    { 20285, "IBM285" },      /* IBM EBCDIC United Kingdom */
+    { 20290, "IBM290" },      /* IBM EBCDIC Japanese Katakana Extended */
+    { 20297, "IBM297" },      /* IBM EBCDIC France */
+    { 20420, "IBM420" },      /* IBM EBCDIC Arabic */
+    { 20423, "IBM423" },      /* IBM EBCDIC Greek */
+    { 20424, "IBM424" },      /* IBM EBCDIC Hebrew */
+    { 20833, NULL },          /* IBM EBCDIC Korean Extended */
+    { 20838, NULL },          /* IBM EBCDIC Thai */
+    { 20866, "KOI8-R" },      /* Russian (KOI8-R); Cyrillic (KOI8-R) */
+    { 20871, "IBM871" },      /* IBM EBCDIC Icelandic */
+    { 20880, "IBM880" },      /* IBM EBCDIC Cyrillic Russian */
+    { 20905, "IBM905" },      /* IBM EBCDIC Turkish */
+    { 20924, NULL },          /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */
+    { 20932, "EUC-JP" },      /* Japanese (JIS 0208-1990 and 0212-1990) */
+    { 20936, NULL },          /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */
+    { 20949, NULL },          /* Korean Wansung */
+    { 21025, "CP1025" },      /* IBM EBCDIC Cyrillic Serbian-Bulgarian */
+    { 21027, NULL },          /* (deprecated) */
+    { 21866, "KOI8-U" },      /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */
+    { 28591, "ISO-8859-1" },  /* ISO 8859-1 Latin 1; Western European (ISO) */
+    { 28592, "ISO-8859-2" },  /* ISO 8859-2 Central European; Central European (ISO) */
+    { 28593, "ISO-8859-3" },  /* ISO 8859-3 Latin 3 */
+    { 28594, "ISO-8859-4" },  /* ISO 8859-4 Baltic */
+    { 28595, "ISO-8859-5" },  /* ISO 8859-5 Cyrillic */
+    { 28596, "ISO-8859-6" },  /* ISO 8859-6 Arabic */
+    { 28597, "ISO-8859-7" },  /* ISO 8859-7 Greek */
+    { 28598, "ISO-8859-8" },  /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
+    { 28599, "ISO-8859-9" },  /* ISO 8859-9 Turkish */
+    { 28603, "ISO-8859-13" }, /* ISO 8859-13 Estonian */
+    { 28605, "ISO-8859-15" }, /* ISO 8859-15 Latin 9 */
+    { 29001, NULL },          /* Europa 3 */
+    { 38598, NULL },          /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
+    { 50220, "ISO-2022-JP" },   /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) (guess) */
+    { 50221, "ISO-2022-JP-2" }, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) (guess) */
+    { 50222, "ISO-2022-JP-3" }, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) (guess) */
+    { 50225, "ISO-2022-KR" }, /* ISO 2022 Korean */
+    { 50227, NULL },          /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */
+    { 50229, NULL },          /* ISO 2022 Traditional Chinese */
+    { 50930, NULL },          /* EBCDIC Japanese (Katakana) Extended */
+    { 50931, NULL },          /* EBCDIC US-Canada and Japanese */
+    { 50933, NULL },          /* EBCDIC Korean Extended and Korean */
+    { 50935, NULL },          /* EBCDIC Simplified Chinese Extended and Simplified Chinese */
+    { 50936, NULL },          /* EBCDIC Simplified Chinese */
+    { 50937, NULL },          /* EBCDIC US-Canada and Traditional Chinese */
+    { 50939, NULL },          /* EBCDIC Japanese (Latin) Extended and Japanese */
+    { 51932, "EUC-JP" },      /* EUC Japanese */
+    { 51936, "EUC-CN" },      /* EUC Simplified Chinese; Chinese Simplified (EUC) */
+    { 51949, "EUC-KR" },      /* EUC Korean */
+    { 51950, NULL },          /* EUC Traditional Chinese */
+    { 52936, NULL },          /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */
+    { 54936, "GB18030" },     /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */
+    { 57002, NULL },          /* ISCII Devanagari */
+    { 57003, NULL },          /* ISCII Bengali */
+    { 57004, NULL },          /* ISCII Tamil */
+    { 57005, NULL },          /* ISCII Telugu */
+    { 57006, NULL },          /* ISCII Assamese */
+    { 57007, NULL },          /* ISCII Oriya */
+    { 57008, NULL },          /* ISCII Kannada */
+    { 57009, NULL },          /* ISCII Malayalam */
+    { 57010, NULL },          /* ISCII Gujarati */
+    { 57011, NULL },          /* ISCII Punjabi */
+    { 65000, "UTF-7" },       /* Unicode (UTF-7) */
+    { 65001, "UTF-8" }        /* Unicode (UTF-8) */
+};
+
+int cli_ole2_summary_json(cli_ctx *ctx, int fd, int mode);
+#endif /* HAVE_JSON */
+
+#endif /* __MSDOC_H_ */
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/ole2_extract.c clamav-0.98.5+dfsg/libclamav/ole2_extract.c
--- clamav-0.98.5~rc1+dfsg/libclamav/ole2_extract.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/ole2_extract.c	2014-11-13 17:30:43.000000000 -0500
@@ -28,12 +28,13 @@
 #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <conv.h>
 #ifdef	HAVE_UNISTD_H
 #include <unistd.h>
 #endif
-#include <ctype.h>
-#include <stdlib.h>
-#include "clamav.h"
 
 #include "clamav.h"
 #include "cltypes.h"
@@ -42,6 +43,9 @@
 #include "scanners.h"
 #include "fmap.h"
 #include "json_api.h"
+#if HAVE_JSON
+#include "msdoc.h"
+#endif
 
 #ifdef DEBUG_OLE2_LIST
 #define ole2_listmsg(...) cli_dbgmsg( __VA_ARGS__)
@@ -1312,897 +1316,3 @@
 
     return ret == CL_BREAK ? CL_CLEAN : ret;
 }
-
-/* Summary and Document Information Parsing to JSON */
-#if HAVE_JSON
-
-#define WINUNICODE 0x04B0
-#define PROPCNTLIMIT 25
-#define PROPSTRLIMIT 62
-
-#define sum16_endian_convert(v) le16_to_host((uint16_t)(v))
-#define sum32_endian_convert(v) le32_to_host((uint32_t)(v))
-#define sum64_endian_convert(v) le64_to_host((uint64_t)(v))
-
-enum summary_pidsi {
-    SPID_CODEPAGE   = 0x00000001,
-    SPID_TITLE      = 0x00000002,
-    SPID_SUBJECT    = 0x00000003,
-    SPID_AUTHOR     = 0x00000004,
-    SPID_KEYWORDS   = 0x00000005,
-    SPID_COMMENTS   = 0x00000006,
-    SPID_TEMPLATE   = 0x00000007,
-    SPID_LASTAUTHOR = 0x00000008,
-    SPID_REVNUMBER  = 0x00000009,
-    SPID_EDITTIME   = 0x0000000A,
-    SPID_LASTPRINTED  = 0x0000000B,
-    SPID_CREATEDTIME  = 0x0000000C,
-    SPID_MODIFIEDTIME = 0x0000000D,
-    SPID_PAGECOUNT = 0x0000000E,
-    SPID_WORDCOUNT = 0x0000000F,
-    SPID_CHARCOUNT = 0x00000010,
-    SPID_THUMBNAIL = 0x00000011,
-    SPID_APPNAME   = 0x00000012,
-    SPID_SECURITY  = 0x00000013
-};
-
-enum docsum_pidsi {
-    DSPID_CODEPAGE    = 0x00000001,
-    DSPID_CATEGORY    = 0x00000002,
-    DSPID_PRESFORMAT  = 0x00000003,
-    DSPID_BYTECOUNT   = 0x00000004,
-    DSPID_LINECOUNT   = 0x00000005,
-    DSPID_PARCOUNT    = 0x00000006,
-    DSPID_SLIDECOUNT  = 0x00000007,
-    DSPID_NOTECOUNT   = 0x00000008,
-    DSPID_HIDDENCOUNT = 0x00000009,
-    DSPID_MMCLIPCOUNT = 0x0000000A,
-    DSPID_SCALE       = 0x0000000B,
-    DSPID_HEADINGPAIR = 0x0000000C, /* VT_VARIANT | VT_VECTOR */
-    DSPID_DOCPARTS    = 0x0000000D, /* VT_VECTOR | VT_LPSTR */
-    DSPID_MANAGER     = 0x0000000E,
-    DSPID_COMPANY     = 0x0000000F,
-    DSPID_LINKSDIRTY  = 0x00000010,
-    DSPID_CCHWITHSPACES = 0x00000011,
-    DSPID_SHAREDDOC   = 0x00000013, /* must be false */
-    DSPID_LINKBASE    = 0x00000014, /* moved to user-defined */
-    DSPID_HLINKS      = 0x00000015, /* moved to user-defined */
-    DSPID_HYPERLINKSCHANGED = 0x00000016,
-    DSPID_VERSION     = 0x00000017,
-    DSPID_DIGSIG      = 0x00000018,
-    DSPID_CONTENTTYPE   = 0x0000001A,
-    DSPID_CONTENTSTATUS = 0x0000001B,
-    DSPID_LANGUAGE      = 0x0000001C,
-    DSPID_DOCVERSION    = 0x0000001D
-};
-
-enum property_type {
-    PT_EMPTY    = 0x0000,
-    PT_NULL     = 0x0001,
-    PT_INT16    = 0x0002,
-    PT_INT32    = 0x0003,
-    PT_FLOAT32  = 0x0004,
-    PT_DOUBLE64 = 0x0005,
-    PT_DATE     = 0x0007,
-    PT_BSTR     = 0x0008,
-    PT_BOOL    = 0x000B,
-    PT_INT8v1  = 0x0010,
-    PT_UINT8   = 0x0011,
-    PT_UINT16  = 0x0012,
-    PT_UINT32  = 0x0013,
-    PT_INT64   = 0x0014,
-    PT_UINT64  = 0x0015,
-    PT_INT32v1  = 0x0016,
-    PT_UINT32v1 = 0x0017,
-    PT_LPSTR  = 0x001E,
-    PT_LPWSTR = 0x001F,
-    PT_FILETIME = 0x0040,
-	
-    /* More Types not currently handled */
-};
-
-typedef struct summary_stub {
-    uint16_t byte_order;
-    uint16_t version;
-    uint32_t system; /* implementation-specific */
-    uint8_t CLSID[16];
-
-    uint32_t num_propsets; /* 1 or 2 */
-} summary_stub_t;
-
-typedef struct propset_summary_entry {
-    uint8_t FMTID[16];
-    uint32_t offset;
-} propset_entry_t;
-
-/* metadata structures */
-#define OLE2_SUMMARY_ERROR_TOOSMALL      0x00000001
-#define OLE2_SUMMARY_ERROR_OOB           0x00000002
-#define OLE2_SUMMARY_ERROR_DATABUF       0x00000004
-#define OLE2_SUMMARY_ERROR_INVALID_ENTRY 0x00000008
-#define OLE2_SUMMARY_LIMIT_PROPS         0x00000010
-#define OLE2_SUMMARY_FLAG_TIMEOUT        0x00000020
-#define OLE2_SUMMARY_FLAG_CODEPAGE       0x00000040
-#define OLE2_SUMMARY_FLAG_UNKNOWN_PROPID 0x00000080
-#define OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE 0x00000100
-#define OLE2_SUMMARY_FLAG_TRUNC_STR      0x00000200
-
-typedef struct summary_ctx {
-    cli_ctx *ctx;
-    int mode;
-    fmap_t *sfmap;
-    json_object *summary;
-    size_t maplen;
-    uint32_t flags;
-
-    /* propset metadata */
-    uint32_t pssize; /* track from propset start, not tail start */
-    int16_t codepage;
-    int writecp;
-
-    /* property metadata */
-    const char *propname;
-
-    /* timeout meta */
-    int toval;
-} summary_ctx_t;
-
-static int
-ole2_process_property(summary_ctx_t *sctx, unsigned char *databuf, uint32_t offset)
-{
-    uint16_t proptype, padding;
-    int ret = CL_SUCCESS;
-
-    if (cli_json_timeout_cycle_check(sctx->ctx, &(sctx->toval)) != CL_SUCCESS) {
-        sctx->flags |= OLE2_SUMMARY_FLAG_TIMEOUT;
-        return CL_ETIMEOUT;
-    }
-
-    if (offset+sizeof(proptype)+sizeof(padding) > sctx->pssize) {
-        sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-        return CL_EFORMAT;
-    }
-
-    memcpy(&proptype, databuf+offset, sizeof(proptype));
-    offset+=sizeof(proptype);
-    memcpy(&padding, databuf+offset, sizeof(padding));
-    offset+=sizeof(padding);
-    /* endian conversion */
-    proptype = sum16_endian_convert(proptype);
-
-    //cli_dbgmsg("proptype: 0x%04x\n", proptype);
-    if (padding != 0) {
-        cli_dbgmsg("ole2_process_property: invalid padding value, non-zero\n");
-        sctx->flags |= OLE2_SUMMARY_ERROR_INVALID_ENTRY;
-        return CL_EFORMAT;
-    }
-
-    switch (proptype) {
-    case PT_EMPTY:
-    case PT_NULL:
-        ret = cli_jsonnull(sctx->summary, sctx->propname);
-        break;
-    case PT_INT16:
-	{
-            int16_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum16_endian_convert(dout);
-
-            if (sctx->writecp)
-                sctx->codepage = dout;
-
-            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_INT32:
-    case PT_INT32v1:
-	{
-            int32_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum32_endian_convert(dout);
-
-            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_FLOAT32: /* review this please */
-	{
-            float dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum32_endian_convert(dout);
-
-            ret = cli_jsondouble(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_DATE:
-    case PT_DOUBLE64: /* review this please */
-	{
-            double dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum64_endian_convert(dout);
-
-            ret = cli_jsondouble(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_BOOL:
-	{
-            uint16_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* no need for endian conversion */
-
-            ret = cli_jsonbool(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_INT8v1:
-	{
-            int8_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* no need for endian conversion */
-
-            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_UINT8:
-	{
-            uint8_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* no need for endian conversion */
-
-            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_UINT16:
-	{
-            uint16_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum16_endian_convert(dout);
-
-            if (sctx->writecp)
-                sctx->codepage = dout;
-
-            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_UINT32:
-    case PT_UINT32v1:
-	{
-            uint32_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum32_endian_convert(dout);
-
-            ret = cli_jsonint(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_INT64:
-	{
-            int64_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum64_endian_convert(dout);
-
-            ret = cli_jsonint64(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_UINT64:
-	{
-            uint64_t dout;
-            if (offset+sizeof(dout) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&dout, databuf+offset, sizeof(dout));
-            offset+=sizeof(dout);
-            /* endian conversion */
-            dout = sum64_endian_convert(dout);
-
-            ret = cli_jsonint64(sctx->summary, sctx->propname, dout);
-            break;
-	}
-    case PT_BSTR:
-    case PT_LPSTR:
-        if (sctx->codepage == 0) {
-            cli_dbgmsg("ole2_propset_json: current codepage is unknown, cannot parse char stream\n");
-            sctx->flags |= OLE2_SUMMARY_FLAG_CODEPAGE;
-            break;
-        }
-        else if (sctx->codepage != WINUNICODE) {
-            uint32_t strsize;
-            char *outstr;
-
-            if (offset+sizeof(strsize) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-
-            memcpy(&strsize, databuf+offset, sizeof(strsize));
-            offset+=sizeof(strsize);
-            /* endian conversion */
-            strsize = sum32_endian_convert(strsize);
-
-            if (offset+strsize > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-
-            /* limitation on string length */
-            if (strsize > PROPSTRLIMIT) {
-                cli_dbgmsg("ole2_process_property: property string sized %lu truncated to size %lu\n",
-                           (unsigned long)strsize, (unsigned long)PROPSTRLIMIT);
-                sctx->flags |= OLE2_SUMMARY_FLAG_TRUNC_STR;
-                strsize = PROPSTRLIMIT;
-            }
-
-            outstr = cli_calloc(strsize+1, 1); /* last char must be NULL */
-            if (!outstr) {
-                return CL_EMEM;
-            }
-            strncpy(outstr, (const char *)(databuf+offset), strsize);
-            ret = cli_jsonstr(sctx->summary, sctx->propname, outstr);
-            free(outstr);
-            break;
-        }
-        /* fall-through for unicode strings */
-    case PT_LPWSTR:
-	{
-            uint32_t strsize;
-            char *outstr, *outstr2;
-
-            if (offset+sizeof(strsize) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&strsize, databuf+offset, sizeof(strsize));
-            offset+=sizeof(strsize);
-            /* endian conversion */
-            strsize = sum32_endian_convert(strsize);
-            
-            if (proptype == PT_LPSTR) { /* fall-through specifics */
-                if (strsize % 2) {
-                    cli_dbgmsg("ole2_process_property: LPSTR using wchar not sized a multiple of 2\n");
-                    sctx->flags |= OLE2_SUMMARY_ERROR_INVALID_ENTRY;
-                    return CL_EFORMAT;
-                }
-            }
-            else {
-                strsize*=2; /* Unicode strings are by length, not size */
-            }
-
-            /* limitation on string length */
-            if (strsize > (2*PROPSTRLIMIT)) {
-                cli_dbgmsg("ole2_process_property: property string sized %lu truncated to size %lu\n",
-                           (unsigned long)strsize, (unsigned long)(2*PROPSTRLIMIT));
-                sctx->flags |= OLE2_SUMMARY_FLAG_TRUNC_STR;
-                strsize = (2*PROPSTRLIMIT);
-            }
-
-            if (offset+strsize > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            outstr = cli_calloc(strsize+2, 1); /* last two chars must be NULL */
-            if (!outstr) {
-                return CL_EMEM;
-            }
-            strncpy(outstr, (const char *)(databuf+offset), strsize);
-            outstr2 = (char*)get_property_name2(outstr, strsize);
-            if (outstr2) {
-                ret = cli_jsonstr(sctx->summary, sctx->propname, outstr2);
-                free(outstr2);
-            }
-            free(outstr);
-            break;
-	}
-    case PT_FILETIME:
-	{
-            uint32_t ltime, htime;
-            uint64_t wtime = 0, utime =0;
-
-            if (offset+sizeof(ltime)+sizeof(htime) > sctx->pssize) {
-                sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-                return CL_EFORMAT;
-            }
-            memcpy(&ltime, databuf+offset, sizeof(ltime));
-            offset+=sizeof(ltime);
-            memcpy(&htime, databuf+offset, sizeof(htime));
-            offset+=sizeof(ltime);
-            ltime = sum32_endian_convert(ltime);
-            htime = sum32_endian_convert(htime);
-
-            /* UNIX timestamp formatting */
-            wtime = htime;
-            wtime <<= 32;
-            wtime |= ltime;
-
-            utime = wtime / 10000000;
-            utime -= 11644473600LL;
-
-            if ((uint32_t)((utime & 0xFFFFFFFF00000000) >> 32)) {
-                cli_dbgmsg("ole2_process_property: UNIX timestamp is larger than 32-bit number\n");
-            }
-            else {
-                ret = cli_jsonint(sctx->summary, sctx->propname, (uint32_t)(utime & 0xFFFFFFFF));
-            }
-            break;
-	}
-    default:
-        cli_dbgmsg("ole2_process_property: unhandled property type 0x%04x for %s property\n", 
-                   proptype, sctx->propname);
-        sctx->flags |= OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE;
-    }
-
-    return ret;
-}
-
-static void ole2_translate_docsummary_propid(summary_ctx_t *sctx, uint32_t propid)
-{
-    switch(propid) {
-    case DSPID_CODEPAGE:
-        sctx->writecp = 1; /* must be set ONLY for codepage */
-        sctx->propname = "CodePage";
-        break;
-    case DSPID_CATEGORY:
-        sctx->propname = "Category";
-        break;
-    case DSPID_PRESFORMAT:
-        sctx->propname = "PresentationTarget";
-        break;
-    case DSPID_BYTECOUNT:
-        sctx->propname = "Bytes";
-        break;
-    case DSPID_LINECOUNT:
-        sctx->propname = "Lines";
-        break;
-    case DSPID_PARCOUNT:
-        sctx->propname = "Paragraphs";
-        break;
-    case DSPID_SLIDECOUNT:
-        sctx->propname = "Slides";
-        break;
-    case DSPID_NOTECOUNT:
-        sctx->propname = "Notes";
-        break;
-    case DSPID_HIDDENCOUNT:
-        sctx->propname = "HiddenSlides";
-        break;
-    case DSPID_MMCLIPCOUNT:
-        sctx->propname = "MMClips";
-        break;
-    case DSPID_SCALE:
-        sctx->propname = "Scale";
-        break;
-    case DSPID_HEADINGPAIR: /* VT_VARIANT | VT_VECTOR */
-        sctx->propname = "HeadingPairs";
-        break;
-    case DSPID_DOCPARTS:    /* VT_VECTOR | VT_LPSTR */
-        sctx->propname = "DocPartTitles";
-        break;
-    case DSPID_MANAGER:
-        sctx->propname = "Manager";
-        break;
-    case DSPID_COMPANY:
-        sctx->propname = "Company";
-        break;
-    case DSPID_LINKSDIRTY:
-        sctx->propname = "LinksDirty";
-        break;
-    case DSPID_CCHWITHSPACES:
-        sctx->propname = "Char&WSCount";
-        break;
-    case DSPID_SHAREDDOC:   /* SHOULD BE FALSE! */
-        sctx->propname = "SharedDoc";
-        break;
-    case DSPID_LINKBASE:    /* moved to user-defined */
-        sctx->propname = "LinkBase";
-        break;
-    case DSPID_HLINKS:      /* moved to user-defined */
-        sctx->propname = "HyperLinks";
-        break;
-    case DSPID_HYPERLINKSCHANGED:
-        sctx->propname = "HyperLinksChanged";
-        break;
-    case DSPID_VERSION:
-        sctx->propname = "Version";
-        break;
-    case DSPID_DIGSIG:
-        sctx->propname = "DigitalSig";
-        break;
-    case DSPID_CONTENTTYPE:
-        sctx->propname = "ContentType";
-        break;
-    case DSPID_CONTENTSTATUS:
-        sctx->propname = "ContentStatus";
-        break;
-    case DSPID_LANGUAGE:
-        sctx->propname = "Language";
-        break;
-    case DSPID_DOCVERSION:
-        sctx->propname = "DocVersion";
-        break;
-    default:
-        cli_dbgmsg("ole2_docsum_propset_json: unrecognized propid!\n");
-        sctx->flags |= OLE2_SUMMARY_FLAG_UNKNOWN_PROPID;
-    }
-}
-
-static void ole2_translate_summary_propid(summary_ctx_t *sctx, uint32_t propid)
-{
-    switch(propid) {
-    case SPID_CODEPAGE:
-        sctx->writecp = 1; /* must be set ONLY for codepage */
-        sctx->propname = "CodePage";
-        break;
-    case SPID_TITLE:
-        sctx->propname = "Title";
-        break;
-    case SPID_SUBJECT:
-        sctx->propname = "Subject";
-        break;
-    case SPID_AUTHOR:
-        sctx->propname = "Author";
-        break;
-    case SPID_KEYWORDS:
-        sctx->propname = "Keywords";
-        break;
-    case SPID_COMMENTS:
-        sctx->propname = "Comments";
-        break;
-    case SPID_TEMPLATE:
-        sctx->propname = "Template";
-        break;
-    case SPID_LASTAUTHOR:
-        sctx->propname = "LastAuthor";
-        break;
-    case SPID_REVNUMBER:
-        sctx->propname = "RevNumber";
-        break;
-    case SPID_EDITTIME:
-        sctx->propname = "EditTime";
-        break;
-    case SPID_LASTPRINTED:
-        sctx->propname = "LastPrinted";
-        break;
-    case SPID_CREATEDTIME:
-        sctx->propname = "CreatedTime";
-        break;
-    case SPID_MODIFIEDTIME:
-        sctx->propname = "ModifiedTime";
-        break;
-    case SPID_PAGECOUNT:
-        sctx->propname = "PageCount";
-        break;
-    case SPID_WORDCOUNT:
-        sctx->propname = "WordCount";
-        break;
-    case SPID_CHARCOUNT:
-        sctx->propname = "CharCount";
-        break;
-    case SPID_THUMBNAIL:
-        sctx->propname = "Thumbnail";
-        break;
-    case SPID_APPNAME:
-        sctx->propname = "AppName";
-        break;
-    case SPID_SECURITY:
-        sctx->propname = "Security";
-        break;
-    default:
-        cli_dbgmsg("ole2_translate_summary_propid: unrecognized propid!\n");
-        sctx->flags |= OLE2_SUMMARY_FLAG_UNKNOWN_PROPID;
-    }
-}
-
-static int ole2_summary_propset_json(summary_ctx_t *sctx, off_t offset)
-{
-    unsigned char *hdr, *ps;
-    uint32_t numprops, limitprops;
-    off_t foff = offset, psoff = 0;
-    uint32_t poffset;
-    int ret;
-    unsigned int i;
-
-    cli_dbgmsg("in ole2_summary_propset_json\n");
-
-    /* summary ctx propset-specific setup*/
-    sctx->codepage = 0;
-    sctx->writecp = 0;
-    sctx->propname = NULL;
-
-    /* examine property set metadata */
-    if ((foff+(2*sizeof(uint32_t))) > sctx->maplen) {
-        sctx->flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
-        return CL_EFORMAT;
-    }
-    hdr = (unsigned char*)fmap_need_off_once(sctx->sfmap, foff, (2*sizeof(uint32_t)));
-    if (!hdr) {
-        sctx->flags |= OLE2_SUMMARY_ERROR_DATABUF;
-        return CL_EREAD;
-    }
-    //foff+=(2*sizeof(uint32_t)); // keep foff pointing to start of propset segment
-    psoff+=(2*sizeof(uint32_t));
-    memcpy(&(sctx->pssize), hdr, sizeof(sctx->pssize));
-    memcpy(&numprops, hdr+sizeof(sctx->pssize), sizeof(numprops));
-    /* endian conversion */
-    sctx->pssize = sum32_endian_convert(sctx->pssize);
-    numprops = sum32_endian_convert(numprops);
-    cli_dbgmsg("ole2_summary_propset_json: pssize: %u, numprops: %u\n", sctx->pssize, numprops);
-    if (numprops > PROPCNTLIMIT) {
-        sctx->flags |= OLE2_SUMMARY_LIMIT_PROPS;
-        limitprops = PROPCNTLIMIT;
-    }
-    else {
-        limitprops = numprops;
-    }
-    cli_dbgmsg("ole2_summary_propset_json: processing %u of %u (%u max) propeties\n",
-               limitprops, numprops, PROPCNTLIMIT);
-
-    /* extract remaining fragment of propset */
-    if ((size_t)(foff+(sctx->pssize)) > (size_t)(sctx->maplen)) {
-        sctx->flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
-        return CL_EFORMAT;
-    }
-    ps = (unsigned char*)fmap_need_off_once(sctx->sfmap, foff, sctx->pssize);
-    if (!ps) {
-        sctx->flags |= OLE2_SUMMARY_ERROR_DATABUF;
-        return CL_EREAD;
-    }
-
-    /* iterate over the properties */
-    for (i = 0; i < limitprops; ++i) {
-        uint32_t propid, propoff;
-
-        if (psoff+sizeof(propid)+sizeof(poffset) > sctx->pssize) {
-            sctx->flags |= OLE2_SUMMARY_ERROR_OOB;
-            return CL_EFORMAT;
-        }
-        memcpy(&propid, ps+psoff, sizeof(propid));
-        psoff+=sizeof(propid);
-        memcpy(&propoff, ps+psoff, sizeof(propoff));
-        psoff+=sizeof(propoff);
-        /* endian conversion */
-        propid = sum32_endian_convert(propid);
-        propoff = sum32_endian_convert(propoff);
-        cli_dbgmsg("ole2_summary_propset_json: propid: 0x%08x, propoff: %u\n", propid, propoff);
-
-        sctx->propname = NULL; sctx->writecp = 0;
-        if (!sctx->mode)
-            ole2_translate_summary_propid(sctx, propid);
-        else
-            ole2_translate_docsummary_propid(sctx, propid);
-
-        if (sctx->propname != NULL) {
-            ret = ole2_process_property(sctx, ps, propoff);
-            if (ret != CL_SUCCESS)
-                return ret;
-        }
-        else {
-            /* add unknown propid flag */
-        }
-    }
-
-    return CL_SUCCESS;
-}
-
-static int cli_ole2_summary_json_cleanup(summary_ctx_t *sctx, int retcode)
-{
-    json_object *jarr;
-
-    cli_dbgmsg("in cli_ole2_summary_json_cleanup: %d[%x]\n", retcode, sctx->flags);
-
-    if (sctx->sfmap) {
-        funmap(sctx->sfmap);
-    }
-
-    if (sctx->flags) {
-        jarr = cli_jsonarray(sctx->summary, "ParseErrors");
-
-        /* check errors */
-        if (sctx->flags & OLE2_SUMMARY_ERROR_TOOSMALL) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_TOOSMALL");
-        }
-        if (sctx->flags & OLE2_SUMMARY_ERROR_OOB) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_OOB");
-        }
-        if (sctx->flags & OLE2_SUMMARY_ERROR_DATABUF) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_DATABUF");
-        }
-        if (sctx->flags & OLE2_SUMMARY_ERROR_INVALID_ENTRY) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_ERROR_INVALID_ENTRY");
-        }
-        if (sctx->flags & OLE2_SUMMARY_LIMIT_PROPS) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_LIMIT_PROPS");
-        }
-        if (sctx->flags & OLE2_SUMMARY_FLAG_TIMEOUT) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_TIMEOUT");
-        }
-        if (sctx->flags & OLE2_SUMMARY_FLAG_CODEPAGE) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_CODEPAGE");
-        }
-        if (sctx->flags & OLE2_SUMMARY_FLAG_UNKNOWN_PROPID) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_UNKNOWN_PROPID");
-        }
-        if (sctx->flags & OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_UNHANDLED_PROPTYPE");
-        }
-        if (sctx->flags & OLE2_SUMMARY_FLAG_TRUNC_STR) {
-            cli_jsonstr(jarr, NULL, "OLE2_SUMMARY_FLAG_TRUNC_STR");
-        }
-    }
-
-    return retcode;
-}
-
-
-#endif /* HAVE_JSON */
-
-#if HAVE_JSON
-int cli_ole2_summary_json(cli_ctx *ctx, int fd, int mode)
-{
-    summary_ctx_t sctx;
-    STATBUF statbuf;
-    off_t foff = 0;
-    unsigned char *databuf;
-    summary_stub_t sumstub;
-    propset_entry_t pentry;
-    int ret = CL_SUCCESS;
-
-    cli_dbgmsg("in cli_ole2_summary_json\n");
-
-    /* preliminary sanity checks */
-    if (ctx == NULL) {
-        return CL_ENULLARG;
-    }
-
-    if (fd < 0) {
-        cli_dbgmsg("ole2_summary_json: invalid file descriptor\n");
-        return CL_ENULLARG; /* placeholder */
-    }
-
-    if (mode != 0 && mode != 1) {
-        cli_dbgmsg("ole2_summary_json: invalid mode specified\n");
-        return CL_ENULLARG; /* placeholder */
-    }
-
-    /* summary ctx setup */
-    memset(&sctx, 0, sizeof(sctx));
-    sctx.ctx = ctx;
-    sctx.mode = mode;
-
-    if (FSTAT(fd, &statbuf) == -1) {
-        cli_dbgmsg("ole2_summary_json: cannot stat file descriptor\n");
-        return CL_ESTAT;
-    }
-
-    sctx.sfmap = fmap(fd, 0, statbuf.st_size);
-    if (!sctx.sfmap) {
-        cli_dbgmsg("ole2_summary_json: failed to get fmap\n");
-        return CL_EMAP;
-    }
-    sctx.maplen = sctx.sfmap->len;
-    cli_dbgmsg("ole2_summary_json: streamsize: %u\n", sctx.maplen);
-
-    if (!mode)
-        sctx.summary = cli_jsonobj(ctx->wrkproperty, "SummaryInfo");
-    else
-        sctx.summary = cli_jsonobj(ctx->wrkproperty, "DocSummaryInfo");
-    if (!sctx.summary) {
-        cli_errmsg("ole2_summary_json: no memory for json object.\n");
-        return cli_ole2_summary_json_cleanup(&sctx, CL_EMEM);
-    }
-
-    sctx.codepage = 0;
-    sctx.writecp = 0;
-
-    /* acquire property stream metadata */
-    if (sctx.maplen < sizeof(summary_stub_t)) {
-        sctx.flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
-        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);
-    }
-    databuf = (unsigned char*)fmap_need_off_once(sctx.sfmap, foff, sizeof(summary_stub_t));
-    if (!databuf) {
-        sctx.flags |= OLE2_SUMMARY_ERROR_DATABUF;
-        return cli_ole2_summary_json_cleanup(&sctx, CL_EREAD);
-    }
-    foff += sizeof(summary_stub_t);
-    memcpy(&sumstub, databuf, sizeof(summary_stub_t));
-
-    /* endian conversion and checks */
-    sumstub.byte_order = le16_to_host(sumstub.byte_order);
-    if (sumstub.byte_order != 0xfffe) {
-        cli_dbgmsg("ole2_summary_json: byteorder 0x%x is invalid\n", sumstub.byte_order);
-        sctx.flags |= OLE2_SUMMARY_ERROR_INVALID_ENTRY;
-        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);;
-    }
-    sumstub.version = sum16_endian_convert(sumstub.version); /*unused*/
-    sumstub.system = sum32_endian_convert(sumstub.system); /*unused*/
-    sumstub.num_propsets = sum32_endian_convert(sumstub.num_propsets);
-    if (sumstub.num_propsets != 1 && sumstub.num_propsets != 2) {
-        cli_dbgmsg("ole2_summary_json: invalid number of property sets\n");
-        sctx.flags |= OLE2_SUMMARY_ERROR_INVALID_ENTRY;
-        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);
-    }
-
-    cli_dbgmsg("ole2_summary_json: byteorder 0x%x\n", sumstub.byte_order);
-    cli_dbgmsg("ole2_summary_json: %u property set(s) detected\n", sumstub.num_propsets);
-
-    /* first property set (index=0) is always SummaryInfo or DocSummaryInfo */
-    if ((sctx.maplen-foff) < sizeof(propset_entry_t)) {
-        sctx.flags |= OLE2_SUMMARY_ERROR_TOOSMALL;
-        return cli_ole2_summary_json_cleanup(&sctx, CL_EFORMAT);
-    }
-    databuf = (unsigned char*)fmap_need_off_once(sctx.sfmap, foff, sizeof(propset_entry_t));
-    if (!databuf) {
-        sctx.flags |= OLE2_SUMMARY_ERROR_DATABUF;
-        return cli_ole2_summary_json_cleanup(&sctx, CL_EREAD);
-    }
-    foff += sizeof(propset_entry_t);
-    memcpy(&pentry, databuf, sizeof(propset_entry_t));
-    /* endian conversion */
-    pentry.offset = sum32_endian_convert(pentry.offset);
-
-    if ((ret = ole2_summary_propset_json(&sctx, pentry.offset)) != CL_SUCCESS) {
-        return cli_ole2_summary_json_cleanup(&sctx, ret);
-    }
-
-    /* second property set (index=1) is always a custom property set (if present) */
-    if (sumstub.num_propsets == 2) {
-        cli_jsonbool(ctx->wrkproperty, "HasUserDefinedProperties", 1);
-    }
-
-    return cli_ole2_summary_json_cleanup(&sctx, CL_SUCCESS);
-}
-#endif /* HAVE_JSON */
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/ooxml.c clamav-0.98.5+dfsg/libclamav/ooxml.c
--- clamav-0.98.5~rc1+dfsg/libclamav/ooxml.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/ooxml.c	2014-11-13 17:30:43.000000000 -0500
@@ -482,7 +482,7 @@
         if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-package.core-properties+xml")) {
             if (!core) {
                 /* default: /docProps/core.xml*/
-                tmp = unzip_search(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
+                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
                 if (tmp == CL_ETIMEOUT) {
                     ret = tmp;
                 }
@@ -500,7 +500,7 @@
         else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.extended-properties+xml")) {
             if (!extn) {
                 /* default: /docProps/app.xml */
-                tmp = unzip_search(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
+                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
                 if (tmp == CL_ETIMEOUT) {
                     ret = tmp;
                 }
@@ -518,7 +518,7 @@
         else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.custom-properties+xml")) {
             if (!cust) {
                 /* default: /docProps/custom.xml */
-                tmp = unzip_search(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
+                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
                 if (tmp == CL_ETIMEOUT) {
                     ret = tmp;
                 }
@@ -537,10 +537,11 @@
             dsig++;
         }
 
-        if (ret != CL_SUCCESS)
+        if (ret != CL_BREAK && ret != CL_SUCCESS)
             goto ooxml_content_exit;
     }
 
+ ooxml_content_exit:
     if (core)
         cli_jsonint(ctx->wrkproperty, "CorePropertiesFileCount", core);
     else if (!mcore)
@@ -566,13 +567,45 @@
         cli_jsonint(ctx->wrkproperty, "DigitalSignaturesCount", dsig);
     }
 
- ooxml_content_exit:
     xmlTextReaderClose(reader);
     xmlFreeTextReader(reader);
     return ret;
 }
 #endif /* HAVE_LIBXML2 && HAVE_JSON */
 
+int cli_ooxml_filetype(cli_ctx *ctx, fmap_t *map)
+{
+    struct zip_requests requests;
+    int ret;
+
+    memset(&requests, 0, sizeof(struct zip_requests));
+
+    if ((ret = unzip_search_add(&requests, "xl/", 3)) != CL_SUCCESS) {
+        return CL_SUCCESS;
+    }
+    if ((ret = unzip_search_add(&requests, "ppt/", 4)) != CL_SUCCESS) {
+        return CL_SUCCESS;
+    }
+    if ((ret = unzip_search_add(&requests, "word/", 5)) != CL_SUCCESS) {
+        return CL_SUCCESS;
+    }
+
+    if ((ret = unzip_search(ctx, map, &requests)) == CL_VIRUS) {
+        switch (requests.found) {
+        case 0:
+            return CL_TYPE_OOXML_XL;
+        case 1:
+            return CL_TYPE_OOXML_PPT;
+        case 2:
+            return CL_TYPE_OOXML_WORD;
+        default:
+            return CL_SUCCESS;
+        }
+    }
+
+    return CL_SUCCESS;
+}
+
 int cli_process_ooxml(cli_ctx *ctx)
 {
 #if HAVE_LIBXML2 && HAVE_JSON
@@ -585,7 +618,7 @@
     }
 
     /* find "[Content Types].xml" */
-    tmp = unzip_search(ctx, "[Content_Types].xml", 18, &loff);
+    tmp = unzip_search_single(ctx, "[Content_Types].xml", 18, &loff);
     if (tmp == CL_ETIMEOUT) {
         return CL_ETIMEOUT;
     }
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/ooxml.h clamav-0.98.5+dfsg/libclamav/ooxml.h
--- clamav-0.98.5~rc1+dfsg/libclamav/ooxml.h	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/ooxml.h	2014-11-13 17:30:43.000000000 -0500
@@ -26,6 +26,7 @@
 #endif
 
 #include "others.h"
+int cli_ooxml_filetype(cli_ctx *, fmap_t *);
 int cli_process_ooxml(cli_ctx *);
 
 #endif
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/pdfng.c clamav-0.98.5+dfsg/libclamav/pdfng.c
--- clamav-0.98.5~rc1+dfsg/libclamav/pdfng.c	2014-09-04 12:46:31.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/pdfng.c	2014-11-13 17:30:43.000000000 -0500
@@ -127,7 +127,7 @@
 
     return res;
 #else
-    res = cli_calloc(begin, sz+1);
+    res = cli_calloc(sz+1, 1);
     if ((res)) {
         memcpy(res, begin, sz);
         res[sz] = '\0';
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/pe.c clamav-0.98.5+dfsg/libclamav/pe.c
--- clamav-0.98.5~rc1+dfsg/libclamav/pe.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/pe.c	2014-11-13 17:30:43.000000000 -0500
@@ -111,8 +111,8 @@
 
 #define CLI_TMPUNLK() if(!ctx->engine->keeptmp) { \
     if (cli_unlink(tempfile)) { \
-	free(tempfile); \
-	return CL_EUNLINK; \
+        free(tempfile); \
+        return CL_EUNLINK; \
     } \
 }
 
@@ -126,70 +126,70 @@
 
 #define FSGCASE(NAME,FREESEC) \
     case 0: /* Unpacked and NOT rebuilt */ \
-	cli_dbgmsg(NAME": Successfully decompressed\n"); \
-	close(ndesc); \
-	if (cli_unlink(tempfile)) { \
-	    free(exe_sections); \
-	    free(tempfile); \
-	    FREESEC; \
-	    return CL_EUNLINK; \
-	} \
-	free(tempfile); \
-	FREESEC; \
-	found = 0; \
-	upx_success = 1; \
-	break; /* FSG ONLY! - scan raw data after upx block */
+    cli_dbgmsg(NAME": Successfully decompressed\n"); \
+    close(ndesc); \
+    if (cli_unlink(tempfile)) { \
+        free(exe_sections); \
+        free(tempfile); \
+        FREESEC; \
+        return CL_EUNLINK; \
+    } \
+    free(tempfile); \
+    FREESEC; \
+    found = 0; \
+    upx_success = 1; \
+    break; /* FSG ONLY! - scan raw data after upx block */
 
 #define SPINCASE() \
     case 2: \
-	free(spinned); \
-	close(ndesc); \
-	if (cli_unlink(tempfile)) { \
-	    free(exe_sections); \
-	    free(tempfile); \
-	    return CL_EUNLINK; \
-	} \
-	cli_dbgmsg("PESpin: Size exceeded\n"); \
-	free(tempfile); \
-	break; \
+    free(spinned); \
+    close(ndesc); \
+    if (cli_unlink(tempfile)) { \
+        free(exe_sections); \
+        free(tempfile); \
+        return CL_EUNLINK; \
+    } \
+    cli_dbgmsg("PESpin: Size exceeded\n"); \
+    free(tempfile); \
+    break; \
 
 #define CLI_UNPRESULTS_(NAME,FSGSTUFF,EXPR,GOOD,FREEME) \
     switch(EXPR) { \
     case GOOD: /* Unpacked and rebuilt */ \
-	if(ctx->engine->keeptmp) \
-	    cli_dbgmsg(NAME": Unpacked and rebuilt executable saved in %s\n", tempfile); \
-	else \
-	    cli_dbgmsg(NAME": Unpacked and rebuilt executable\n"); \
-	cli_multifree FREEME; \
+        if(ctx->engine->keeptmp) \
+            cli_dbgmsg(NAME": Unpacked and rebuilt executable saved in %s\n", tempfile); \
+        else \
+            cli_dbgmsg(NAME": Unpacked and rebuilt executable\n"); \
+        cli_multifree FREEME; \
         free(exe_sections); \
-	lseek(ndesc, 0, SEEK_SET); \
-	cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); \
-	SHA_OFF; \
-	if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { \
-	    close(ndesc); \
-	    CLI_TMPUNLK(); \
-	    free(tempfile); \
-	    SHA_RESET; \
-	    return CL_VIRUS; \
-	} \
-	SHA_RESET; \
-	close(ndesc); \
-	CLI_TMPUNLK(); \
-	free(tempfile); \
-	return CL_CLEAN; \
+        lseek(ndesc, 0, SEEK_SET); \
+        cli_dbgmsg("***** Scanning rebuilt PE file *****\n"); \
+        SHA_OFF; \
+        if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) { \
+            close(ndesc); \
+            CLI_TMPUNLK(); \
+            free(tempfile); \
+            SHA_RESET; \
+            return CL_VIRUS; \
+        } \
+        SHA_RESET; \
+        close(ndesc); \
+        CLI_TMPUNLK(); \
+        free(tempfile); \
+        return CL_CLEAN; \
 \
 FSGSTUFF; \
 \
     default: \
-	cli_dbgmsg(NAME": Unpacking failed\n"); \
-	close(ndesc); \
-	if (cli_unlink(tempfile)) { \
-	    free(exe_sections); \
-	    free(tempfile); \
-	    cli_multifree FREEME; \
-	    return CL_EUNLINK; \
-	} \
-	cli_multifree FREEME; \
+        cli_dbgmsg(NAME": Unpacking failed\n"); \
+        close(ndesc); \
+        if (cli_unlink(tempfile)) { \
+            free(exe_sections); \
+            free(tempfile); \
+            cli_multifree FREEME; \
+            return CL_EUNLINK; \
+        } \
+        cli_multifree FREEME; \
         free(tempfile); \
     }
 
@@ -227,7 +227,7 @@
     cli_dbgmsg("versioninfo_cb: type: %x, name: %x, lang: %x, rva: %x\n", type, name, lang, rva);
     vlist->rvas[vlist->count] = rva;
     if(++vlist->count == sizeof(vlist->rvas) / sizeof(vlist->rvas[0]))
-	return 1;
+        return 1;
     return 0;
 }
 
@@ -238,24 +238,25 @@
     uint32_t ret;
 
     if (rva<hdr_size) { /* Out of section EP - mapped to imagebase+rva */
-	if (rva >= fsize) {
-	    *err=1;
-	    return 0;
-	}
+        if (rva >= fsize) {
+            *err=1;
+            return 0;
+        }
+
         *err=0;
-	return rva;
+        return rva;
     }
 
     for(i = nos-1; i >= 0; i--) {
         if(shp[i].rsz && shp[i].rva <= rva && shp[i].rsz > rva - shp[i].rva) {
-	    found = 1;
-	    break;
-	}
+            found = 1;
+            break;
+        }
     }
 
     if(!found) {
-	*err = 1;
-	return 0;
+        *err = 1;
+        return 0;
     }
 
     ret = rva - shp[i].rva + shp[i].raw;
@@ -263,61 +264,6 @@
     return ret;
 }
 
-
-/*
-static int cli_ddump(int desc, int offset, int size, const char *file) {
-	int pos, ndesc, bread, sum = 0;
-	char buff[FILEBUFF];
-
-
-    cli_dbgmsg("in ddump()\n");
-
-    if((pos = lseek(desc, 0, SEEK_CUR)) == -1) {
-	cli_dbgmsg("Invalid descriptor\n");
-	return -1;
-    }
-
-    if(lseek(desc, offset, SEEK_SET) == -1) {
-	cli_dbgmsg("lseek() failed\n");
-	lseek(desc, pos, SEEK_SET);
-	return -1;
-    }
-
-    if((ndesc = open(file, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) {
-	cli_dbgmsg("Can't create file %s\n", file);
-	lseek(desc, pos, SEEK_SET);
-	return -1;
-    }
-
-    while((bread = cli_readn(desc, buff, FILEBUFF)) > 0) {
-	if(sum + bread >= size) {
-	    if(write(ndesc, buff, size - sum) == -1) {
-		cli_dbgmsg("Can't write to file\n");
-		lseek(desc, pos, SEEK_SET);
-		close(ndesc);
-		cli_unlink(file);
-		return -1;
-	    }
-	    break;
-	} else {
-	    if(write(ndesc, buff, bread) == -1) {
-		cli_dbgmsg("Can't write to file\n");
-		lseek(desc, pos, SEEK_SET);
-		close(ndesc);
-		cli_unlink(file);
-		return -1;
-	    }
-	}
-	sum += bread;
-    }
-
-    close(ndesc);
-    lseek(desc, pos, SEEK_SET);
-    return 0;
-}
-*/
-
-
 /* 
    void findres(uint32_t by_type, uint32_t by_name, uint32_t res_rva, cli_ctx *ctx, struct cli_exe_section *exe_sections, uint16_t nsections, uint32_t hdr_size, int (*cb)(void *, uint32_t, uint32_t, uint32_t, uint32_t), void *opaque)
    callback based res lookup
@@ -722,49 +668,49 @@
 
 int cli_scanpe(cli_ctx *ctx)
 {
-	uint16_t e_magic; /* DOS signature ("MZ") */
-	uint16_t nsections;
-	uint32_t e_lfanew; /* address of new exe header */
-	uint32_t ep, vep; /* entry point (raw, virtual) */
-	uint8_t polipos = 0;
-	time_t timestamp;
-	struct pe_image_file_hdr file_hdr;
-	union {
-	    struct pe_image_optional_hdr64 opt64;
-	    struct pe_image_optional_hdr32 opt32;
-	} pe_opt;
-	struct pe_image_section_hdr *section_hdr;
-	char sname[9], epbuff[4096], *tempfile;
-	uint32_t epsize;
-	ssize_t bytes, at;
-	unsigned int i, found, upx_success = 0, min = 0, max = 0, err, overlays = 0;
-	unsigned int ssize = 0, dsize = 0, dll = 0, pe_plus = 0, corrupted_cur;
-	int (*upxfn)(const char *, uint32_t, char *, uint32_t *, uint32_t, uint32_t, uint32_t) = NULL;
-	const char *src = NULL;
-	char *dest = NULL;
-	int ndesc, ret = CL_CLEAN, upack = 0, native=0;
-	size_t fsize;
-	uint32_t valign, falign, hdr_size, j;
-	struct cli_exe_section *exe_sections;
-	char timestr[32];
-	struct pe_image_data_dir *dirs;
-	struct cli_bc_ctx *bc_ctx;
-	fmap_t *map;
-	struct cli_pe_hook_data pedata;
+    uint16_t e_magic; /* DOS signature ("MZ") */
+    uint16_t nsections;
+    uint32_t e_lfanew; /* address of new exe header */
+    uint32_t ep, vep; /* entry point (raw, virtual) */
+    uint8_t polipos = 0;
+    time_t timestamp;
+    struct pe_image_file_hdr file_hdr;
+    union {
+        struct pe_image_optional_hdr64 opt64;
+        struct pe_image_optional_hdr32 opt32;
+    } pe_opt;
+    struct pe_image_section_hdr *section_hdr;
+    char sname[9], epbuff[4096], *tempfile;
+    uint32_t epsize;
+    ssize_t bytes, at;
+    unsigned int i, j, found, upx_success = 0, min = 0, max = 0, err, overlays = 0, rescan = 1;
+    unsigned int ssize = 0, dsize = 0, dll = 0, pe_plus = 0, corrupted_cur;
+    int (*upxfn)(const char *, uint32_t, char *, uint32_t *, uint32_t, uint32_t, uint32_t) = NULL;
+    const char *src = NULL;
+    char *dest = NULL;
+    int ndesc, ret = CL_CLEAN, upack = 0, native=0;
+    size_t fsize;
+    uint32_t valign, falign, hdr_size;
+    struct cli_exe_section *exe_sections;
+    char timestr[32];
+    struct pe_image_data_dir *dirs;
+    struct cli_bc_ctx *bc_ctx;
+    fmap_t *map;
+    struct cli_pe_hook_data pedata;
 #ifdef HAVE__INTERNAL__SHA_COLLECT
-	int sha_collect = ctx->sha_collect;
+    int sha_collect = ctx->sha_collect;
 #endif
     const char *archtype=NULL, *subsystem=NULL;
-	uint32_t viruses_found = 0;
+    uint32_t viruses_found = 0;
 #if HAVE_JSON
-        int toval = 0;
-        struct json_object *pe_json=NULL;
-        char jsonbuf[128];
+    int toval = 0;
+    struct json_object *pe_json=NULL;
+    char jsonbuf[128];
 #endif
 
     if(!ctx) {
-	cli_errmsg("cli_scanpe: ctx == NULL\n");
-	return CL_ENULLARG;
+        cli_errmsg("cli_scanpe: ctx == NULL\n");
+        return CL_ENULLARG;
     }
 
 #if HAVE_JSON
@@ -778,41 +724,42 @@
 #endif
     map = *ctx->fmap;
     if(fmap_readn(map, &e_magic, 0, sizeof(e_magic)) != sizeof(e_magic)) {
-	cli_dbgmsg("Can't read DOS signature\n");
-	return CL_CLEAN;
+        cli_dbgmsg("Can't read DOS signature\n");
+        return CL_CLEAN;
     }
 
     if(EC16(e_magic) != PE_IMAGE_DOS_SIGNATURE && EC16(e_magic) != PE_IMAGE_DOS_SIGNATURE_OLD) {
-	cli_dbgmsg("Invalid DOS signature\n");
-	return CL_CLEAN;
+        cli_dbgmsg("Invalid DOS signature\n");
+        return CL_CLEAN;
     }
 
     if(fmap_readn(map, &e_lfanew, 58 + sizeof(e_magic), sizeof(e_lfanew)) != sizeof(e_lfanew)) {
-	cli_dbgmsg("Can't read new header address\n");
-	/* truncated header? */
-	if(DETECT_BROKEN_PE) {
-	    cli_append_virus(ctx,"Heuristics.Broken.Executable");
-	    return CL_VIRUS;
-	}
-	return CL_CLEAN;
+        cli_dbgmsg("Can't read new header address\n");
+        /* truncated header? */
+        if(DETECT_BROKEN_PE) {
+            cli_append_virus(ctx,"Heuristics.Broken.Executable");
+            return CL_VIRUS;
+        }
+
+        return CL_CLEAN;
     }
 
     e_lfanew = EC32(e_lfanew);
     cli_dbgmsg("e_lfanew == %d\n", e_lfanew);
     if(!e_lfanew) {
-	cli_dbgmsg("Not a PE file\n");
-	return CL_CLEAN;
+        cli_dbgmsg("Not a PE file\n");
+        return CL_CLEAN;
     }
 
     if(fmap_readn(map, &file_hdr, e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
-	/* bad information in e_lfanew - probably not a PE file */
-	cli_dbgmsg("Can't read file header\n");
-	return CL_CLEAN;
+        /* bad information in e_lfanew - probably not a PE file */
+        cli_dbgmsg("Can't read file header\n");
+        return CL_CLEAN;
     }
 
     if(EC32(file_hdr.Magic) != PE_IMAGE_NT_SIGNATURE) {
-	cli_dbgmsg("Invalid PE signature (probably NE file)\n");
-	return CL_CLEAN;
+        cli_dbgmsg("Invalid PE signature (probably NE file)\n");
+        return CL_CLEAN;
     }
 
     if(EC16(file_hdr.Characteristics) & 0x2000) {
@@ -820,108 +767,108 @@
         if ((pe_json))
             cli_jsonstr(pe_json, "Type", "DLL");
 #endif
-	cli_dbgmsg("File type: DLL\n");
-	dll = 1;
+        cli_dbgmsg("File type: DLL\n");
+        dll = 1;
     } else if(EC16(file_hdr.Characteristics) & 0x01) {
 #if HAVE_JSON
         if ((pe_json))
             cli_jsonstr(pe_json, "Type", "EXE");
 #endif
-	cli_dbgmsg("File type: Executable\n");
+        cli_dbgmsg("File type: Executable\n");
     }
 
     switch(EC16(file_hdr.Machine)) {
-	case 0x0:
+    case 0x0:
         archtype = "Unknown";
-	    break;
-	case 0x14c:
+        break;
+    case 0x14c:
         archtype = "80386";
-	    break;
-	case 0x14d:
+        break;
+    case 0x14d:
         archtype = "80486";
-	    break;
-	case 0x14e:
+        break;
+    case 0x14e:
         archtype = "80586";
-	    break;
-	case 0x160:
+        break;
+    case 0x160:
         archtype = "R30000 (big-endian)";
-	    break;
-	case 0x162:
+        break;
+    case 0x162:
         archtype = "R3000";
-	    break;
-	case 0x166:
+        break;
+    case 0x166:
         archtype = "R4000";
-	    break;
-	case 0x168:
+        break;
+    case 0x168:
         archtype = "R10000";
-	    break;
-	case 0x184:
+        break;
+    case 0x184:
         archtype = "DEC Alpha AXP";
-	    break;
-	case 0x284:
+        break;
+    case 0x284:
         archtype = "DEC Alpha AXP 64bit";
-	    break;
-	case 0x1f0:
+        break;
+    case 0x1f0:
         archtype = "PowerPC";
-	    break;
-	case 0x200:
+        break;
+    case 0x200:
         archtype = "IA64";
-	    break;
-	case 0x268:
+        break;
+    case 0x268:
         archtype = "M68k";
-	    break;
-	case 0x266:
+        break;
+    case 0x266:
         archtype = "MIPS16";
-	    break;
-	case 0x366:
+        break;
+    case 0x366:
         archtype = "MIPS+FPU";
-	    break;
-	case 0x466:
+        break;
+    case 0x466:
         archtype = "MIPS16+FPU";
-	    break;
-	case 0x1a2:
+        break;
+    case 0x1a2:
         archtype = "Hitachi SH3";
-	    break;
-	case 0x1a3:
+        break;
+    case 0x1a3:
         archtype = "Hitachi SH3-DSP";
-	    break;
-	case 0x1a4:
+        break;
+    case 0x1a4:
         archtype = "Hitachi SH3-E";
-	    break;
-	case 0x1a6:
+        break;
+    case 0x1a6:
         archtype = "Hitachi SH4";
-	    break;
-	case 0x1a8:
+        break;
+    case 0x1a8:
         archtype = "Hitachi SH5";
-	    break;
-	case 0x1c0:
+        break;
+    case 0x1c0:
         archtype = "ARM";
-	    break;
-	case 0x1c2:
+        break;
+    case 0x1c2:
         archtype = "THUMB";
-	    break;
-	case 0x1d3:
+        break;
+    case 0x1d3:
         archtype = "AM33";
-	    break;
-	case 0x520:
+        break;
+    case 0x520:
         archtype = "Infineon TriCore";
-	    break;
-	case 0xcef:
+        break;
+    case 0xcef:
         archtype = "CEF";
-	    break;
-	case 0xebc:
+        break;
+    case 0xebc:
         archtype = "EFI Byte Code";
-	    break;
-	case 0x9041:
+        break;
+    case 0x9041:
         archtype = "M32R";
-	    break;
-	case 0xc0ee:
+        break;
+    case 0xc0ee:
         archtype = "CEEE";
-	    break;
-	case 0x8664:
+        break;
+    case 0x8664:
         archtype = "AMD64";
-	    break;
-	default:
+        break;
+    default:
         archtype = "Unknown";
     }
 
@@ -937,18 +884,21 @@
 #if HAVE_JSON
         pe_add_heuristic_property(ctx, "BadNumberOfSections");
 #endif
-	if(DETECT_BROKEN_PE) {
-	    cli_append_virus(ctx,"Heuristics.Broken.Executable");
-	    return CL_VIRUS;
-	}
-	if(!ctx->corrupted_input) {
-	    if(nsections)
-		cli_warnmsg("PE file contains %d sections\n", nsections);
-	    else
-		cli_warnmsg("PE file contains no sections\n");
-	}
-	return CL_CLEAN;
+        if(DETECT_BROKEN_PE) {
+            cli_append_virus(ctx,"Heuristics.Broken.Executable");
+            return CL_VIRUS;
+        }
+
+        if(!ctx->corrupted_input) {
+            if(nsections)
+            cli_warnmsg("PE file contains %d sections\n", nsections);
+            else
+            cli_warnmsg("PE file contains no sections\n");
+        }
+
+        return CL_CLEAN;
     }
+
     cli_dbgmsg("NumberOfSections: %d\n", nsections);
 
     timestamp = (time_t) EC32(file_hdr.TimeDateStamp);
@@ -969,21 +919,23 @@
         pe_add_heuristic_property(ctx, "BadOptionalHeaderSize");
 #endif
         cli_dbgmsg("SizeOfOptionalHeader too small\n");
-	if(DETECT_BROKEN_PE) {
-	    cli_append_virus(ctx,"Heuristics.Broken.Executable");
-	    return CL_VIRUS;
-	}
-	return CL_CLEAN;
+        if(DETECT_BROKEN_PE) {
+            cli_append_virus(ctx,"Heuristics.Broken.Executable");
+            return CL_VIRUS;
+        }
+
+        return CL_CLEAN;
     }
 
     at = e_lfanew + sizeof(struct pe_image_file_hdr);
     if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
         cli_dbgmsg("Can't read optional file header\n");
-	if(DETECT_BROKEN_PE) {
-	    cli_append_virus(ctx,"Heuristics.Broken.Executable");
-	    return CL_VIRUS;
-	}
-	return CL_CLEAN;
+        if(DETECT_BROKEN_PE) {
+            cli_append_virus(ctx,"Heuristics.Broken.Executable");
+            return CL_VIRUS;
+        }
+
+        return CL_CLEAN;
     }
     at += sizeof(struct pe_image_optional_hdr32);
 
@@ -993,125 +945,129 @@
         pe_add_heuristic_property(ctx, "BadOptionalHeaderSizePE32Plus");
 #endif
         if(EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr64)) {
-	    /* FIXME: need to play around a bit more with xp64 */
-	    cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
-	    if(DETECT_BROKEN_PE) {
-		cli_append_virus(ctx,"Heuristics.Broken.Executable");
-		return CL_VIRUS;
-	    }
-	    return CL_CLEAN;
-	}
-	pe_plus = 1;
+            /* FIXME: need to play around a bit more with xp64 */
+            cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
+
+            if(DETECT_BROKEN_PE) {
+                cli_append_virus(ctx,"Heuristics.Broken.Executable");
+                return CL_VIRUS;
+            }
+
+            return CL_CLEAN;
+        }
+        pe_plus = 1;
     }
 
     if(!pe_plus) { /* PE */
-	if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
-	    /* Seek to the end of the long header */
-	    at += EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32);
-	}
+        if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
+            /* Seek to the end of the long header */
+            at += EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32);
+        }
 
-	if(DCONF & PE_CONF_UPACK)
-	    upack = (EC16(file_hdr.SizeOfOptionalHeader)==0x148);
+        if(DCONF & PE_CONF_UPACK)
+            upack = (EC16(file_hdr.SizeOfOptionalHeader)==0x148);
 
-	vep = EC32(optional_hdr32.AddressOfEntryPoint);
-	hdr_size = EC32(optional_hdr32.SizeOfHeaders);
-	cli_dbgmsg("File format: PE\n");
-
-	cli_dbgmsg("MajorLinkerVersion: %d\n", optional_hdr32.MajorLinkerVersion);
-	cli_dbgmsg("MinorLinkerVersion: %d\n", optional_hdr32.MinorLinkerVersion);
-	cli_dbgmsg("SizeOfCode: 0x%x\n", EC32(optional_hdr32.SizeOfCode));
-	cli_dbgmsg("SizeOfInitializedData: 0x%x\n", EC32(optional_hdr32.SizeOfInitializedData));
-	cli_dbgmsg("SizeOfUninitializedData: 0x%x\n", EC32(optional_hdr32.SizeOfUninitializedData));
-	cli_dbgmsg("AddressOfEntryPoint: 0x%x\n", vep);
-	cli_dbgmsg("BaseOfCode: 0x%x\n", EC32(optional_hdr32.BaseOfCode));
-	cli_dbgmsg("SectionAlignment: 0x%x\n", EC32(optional_hdr32.SectionAlignment));
-	cli_dbgmsg("FileAlignment: 0x%x\n", EC32(optional_hdr32.FileAlignment));
-	cli_dbgmsg("MajorSubsystemVersion: %d\n", EC16(optional_hdr32.MajorSubsystemVersion));
-	cli_dbgmsg("MinorSubsystemVersion: %d\n", EC16(optional_hdr32.MinorSubsystemVersion));
-	cli_dbgmsg("SizeOfImage: 0x%x\n", EC32(optional_hdr32.SizeOfImage));
-	cli_dbgmsg("SizeOfHeaders: 0x%x\n", hdr_size);
-	cli_dbgmsg("NumberOfRvaAndSizes: %d\n", EC32(optional_hdr32.NumberOfRvaAndSizes));
-	dirs = optional_hdr32.DataDirectory;
-#if HAVE_JSON
-    cli_jsonint(pe_json, "MajorLinkerVersion", optional_hdr32.MajorLinkerVersion);
-    cli_jsonint(pe_json, "MinorLinkerVersion", optional_hdr32.MinorLinkerVersion);
-    cli_jsonint(pe_json, "SizeOfCode", EC32(optional_hdr32.SizeOfCode));
-    cli_jsonint(pe_json, "SizeOfInitializedData", EC32(optional_hdr32.SizeOfInitializedData));
-    cli_jsonint(pe_json, "SizeOfUninitializedData", EC32(optional_hdr32.SizeOfUninitializedData));
-    cli_jsonint(pe_json, "NumberOfRvaAndSizes", EC32(optional_hdr32.NumberOfRvaAndSizes));
-    cli_jsonint(pe_json, "MajorSubsystemVersion", EC16(optional_hdr32.MajorSubsystemVersion));
-    cli_jsonint(pe_json, "MinorSubsystemVersion", EC16(optional_hdr32.MinorSubsystemVersion));
-
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.BaseOfCode));
-    cli_jsonstr(pe_json, "BaseOfCode", jsonbuf);
-
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.SectionAlignment));
-    cli_jsonstr(pe_json, "SectionAlignment", jsonbuf);
+        vep = EC32(optional_hdr32.AddressOfEntryPoint);
+        hdr_size = EC32(optional_hdr32.SizeOfHeaders);
+        cli_dbgmsg("File format: PE\n");
+
+        cli_dbgmsg("MajorLinkerVersion: %d\n", optional_hdr32.MajorLinkerVersion);
+        cli_dbgmsg("MinorLinkerVersion: %d\n", optional_hdr32.MinorLinkerVersion);
+        cli_dbgmsg("SizeOfCode: 0x%x\n", EC32(optional_hdr32.SizeOfCode));
+        cli_dbgmsg("SizeOfInitializedData: 0x%x\n", EC32(optional_hdr32.SizeOfInitializedData));
+        cli_dbgmsg("SizeOfUninitializedData: 0x%x\n", EC32(optional_hdr32.SizeOfUninitializedData));
+        cli_dbgmsg("AddressOfEntryPoint: 0x%x\n", vep);
+        cli_dbgmsg("BaseOfCode: 0x%x\n", EC32(optional_hdr32.BaseOfCode));
+        cli_dbgmsg("SectionAlignment: 0x%x\n", EC32(optional_hdr32.SectionAlignment));
+        cli_dbgmsg("FileAlignment: 0x%x\n", EC32(optional_hdr32.FileAlignment));
+        cli_dbgmsg("MajorSubsystemVersion: %d\n", EC16(optional_hdr32.MajorSubsystemVersion));
+        cli_dbgmsg("MinorSubsystemVersion: %d\n", EC16(optional_hdr32.MinorSubsystemVersion));
+        cli_dbgmsg("SizeOfImage: 0x%x\n", EC32(optional_hdr32.SizeOfImage));
+        cli_dbgmsg("SizeOfHeaders: 0x%x\n", hdr_size);
+        cli_dbgmsg("NumberOfRvaAndSizes: %d\n", EC32(optional_hdr32.NumberOfRvaAndSizes));
+        dirs = optional_hdr32.DataDirectory;
+#if HAVE_JSON
+        cli_jsonint(pe_json, "MajorLinkerVersion", optional_hdr32.MajorLinkerVersion);
+        cli_jsonint(pe_json, "MinorLinkerVersion", optional_hdr32.MinorLinkerVersion);
+        cli_jsonint(pe_json, "SizeOfCode", EC32(optional_hdr32.SizeOfCode));
+        cli_jsonint(pe_json, "SizeOfInitializedData", EC32(optional_hdr32.SizeOfInitializedData));
+        cli_jsonint(pe_json, "SizeOfUninitializedData", EC32(optional_hdr32.SizeOfUninitializedData));
+        cli_jsonint(pe_json, "NumberOfRvaAndSizes", EC32(optional_hdr32.NumberOfRvaAndSizes));
+        cli_jsonint(pe_json, "MajorSubsystemVersion", EC16(optional_hdr32.MajorSubsystemVersion));
+        cli_jsonint(pe_json, "MinorSubsystemVersion", EC16(optional_hdr32.MinorSubsystemVersion));
+
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.BaseOfCode));
+        cli_jsonstr(pe_json, "BaseOfCode", jsonbuf);
+
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.SectionAlignment));
+        cli_jsonstr(pe_json, "SectionAlignment", jsonbuf);
 
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.FileAlignment));
-    cli_jsonstr(pe_json, "FileAlignment", jsonbuf);
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.FileAlignment));
+        cli_jsonstr(pe_json, "FileAlignment", jsonbuf);
 
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.SizeOfImage));
-    cli_jsonstr(pe_json, "SizeOfImage", jsonbuf);
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr32.SizeOfImage));
+        cli_jsonstr(pe_json, "SizeOfImage", jsonbuf);
 
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", hdr_size);
-    cli_jsonstr(pe_json, "SizeOfHeaders", jsonbuf);
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", hdr_size);
+        cli_jsonstr(pe_json, "SizeOfHeaders", jsonbuf);
 #endif
 
     } else { /* PE+ */
-        /* read the remaining part of the header */
-        if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
-	    cli_dbgmsg("Can't read optional file header\n");
-	    if(DETECT_BROKEN_PE) {
-		cli_append_virus(ctx,"Heuristics.Broken.Executable");
-		return CL_VIRUS;
-	    }
-	    return CL_CLEAN;
-	}
-	at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
-	vep = EC32(optional_hdr64.AddressOfEntryPoint);
-	hdr_size = EC32(optional_hdr64.SizeOfHeaders);
-	cli_dbgmsg("File format: PE32+\n");
-
-	cli_dbgmsg("MajorLinkerVersion: %d\n", optional_hdr64.MajorLinkerVersion);
-	cli_dbgmsg("MinorLinkerVersion: %d\n", optional_hdr64.MinorLinkerVersion);
-	cli_dbgmsg("SizeOfCode: 0x%x\n", EC32(optional_hdr64.SizeOfCode));
-	cli_dbgmsg("SizeOfInitializedData: 0x%x\n", EC32(optional_hdr64.SizeOfInitializedData));
-	cli_dbgmsg("SizeOfUninitializedData: 0x%x\n", EC32(optional_hdr64.SizeOfUninitializedData));
-	cli_dbgmsg("AddressOfEntryPoint: 0x%x\n", vep);
-	cli_dbgmsg("BaseOfCode: 0x%x\n", EC32(optional_hdr64.BaseOfCode));
-	cli_dbgmsg("SectionAlignment: 0x%x\n", EC32(optional_hdr64.SectionAlignment));
-	cli_dbgmsg("FileAlignment: 0x%x\n", EC32(optional_hdr64.FileAlignment));
-	cli_dbgmsg("MajorSubsystemVersion: %d\n", EC16(optional_hdr64.MajorSubsystemVersion));
-	cli_dbgmsg("MinorSubsystemVersion: %d\n", EC16(optional_hdr64.MinorSubsystemVersion));
-	cli_dbgmsg("SizeOfImage: 0x%x\n", EC32(optional_hdr64.SizeOfImage));
-	cli_dbgmsg("SizeOfHeaders: 0x%x\n", hdr_size);
-	cli_dbgmsg("NumberOfRvaAndSizes: %d\n", EC32(optional_hdr64.NumberOfRvaAndSizes));
-	dirs = optional_hdr64.DataDirectory;
-#if HAVE_JSON
-    cli_jsonint(pe_json, "MajorLinkerVersion", optional_hdr64.MajorLinkerVersion);
-    cli_jsonint(pe_json, "MinorLinkerVersion", optional_hdr64.MinorLinkerVersion);
-    cli_jsonint(pe_json, "SizeOfCode", EC32(optional_hdr64.SizeOfCode));
-    cli_jsonint(pe_json, "SizeOfInitializedData", EC32(optional_hdr64.SizeOfInitializedData));
-    cli_jsonint(pe_json, "SizeOfUninitializedData", EC32(optional_hdr64.SizeOfUninitializedData));
-    cli_jsonint(pe_json, "NumberOfRvaAndSizes", EC32(optional_hdr64.NumberOfRvaAndSizes));
-    cli_jsonint(pe_json, "MajorSubsystemVersion", EC16(optional_hdr64.MajorSubsystemVersion));
-    cli_jsonint(pe_json, "MinorSubsystemVersion", EC16(optional_hdr64.MinorSubsystemVersion));
-
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.BaseOfCode));
-    cli_jsonstr(pe_json, "BaseOfCode", jsonbuf);
-
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.SectionAlignment));
-    cli_jsonstr(pe_json, "SectionAlignment", jsonbuf);
+            /* read the remaining part of the header */
+            if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
+            cli_dbgmsg("Can't read optional file header\n");
+            if(DETECT_BROKEN_PE) {
+                cli_append_virus(ctx,"Heuristics.Broken.Executable");
+                return CL_VIRUS;
+            }
+
+            return CL_CLEAN;
+        }
+
+        at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
+        vep = EC32(optional_hdr64.AddressOfEntryPoint);
+        hdr_size = EC32(optional_hdr64.SizeOfHeaders);
+        cli_dbgmsg("File format: PE32+\n");
+
+        cli_dbgmsg("MajorLinkerVersion: %d\n", optional_hdr64.MajorLinkerVersion);
+        cli_dbgmsg("MinorLinkerVersion: %d\n", optional_hdr64.MinorLinkerVersion);
+        cli_dbgmsg("SizeOfCode: 0x%x\n", EC32(optional_hdr64.SizeOfCode));
+        cli_dbgmsg("SizeOfInitializedData: 0x%x\n", EC32(optional_hdr64.SizeOfInitializedData));
+        cli_dbgmsg("SizeOfUninitializedData: 0x%x\n", EC32(optional_hdr64.SizeOfUninitializedData));
+        cli_dbgmsg("AddressOfEntryPoint: 0x%x\n", vep);
+        cli_dbgmsg("BaseOfCode: 0x%x\n", EC32(optional_hdr64.BaseOfCode));
+        cli_dbgmsg("SectionAlignment: 0x%x\n", EC32(optional_hdr64.SectionAlignment));
+        cli_dbgmsg("FileAlignment: 0x%x\n", EC32(optional_hdr64.FileAlignment));
+        cli_dbgmsg("MajorSubsystemVersion: %d\n", EC16(optional_hdr64.MajorSubsystemVersion));
+        cli_dbgmsg("MinorSubsystemVersion: %d\n", EC16(optional_hdr64.MinorSubsystemVersion));
+        cli_dbgmsg("SizeOfImage: 0x%x\n", EC32(optional_hdr64.SizeOfImage));
+        cli_dbgmsg("SizeOfHeaders: 0x%x\n", hdr_size);
+        cli_dbgmsg("NumberOfRvaAndSizes: %d\n", EC32(optional_hdr64.NumberOfRvaAndSizes));
+        dirs = optional_hdr64.DataDirectory;
+#if HAVE_JSON
+        cli_jsonint(pe_json, "MajorLinkerVersion", optional_hdr64.MajorLinkerVersion);
+        cli_jsonint(pe_json, "MinorLinkerVersion", optional_hdr64.MinorLinkerVersion);
+        cli_jsonint(pe_json, "SizeOfCode", EC32(optional_hdr64.SizeOfCode));
+        cli_jsonint(pe_json, "SizeOfInitializedData", EC32(optional_hdr64.SizeOfInitializedData));
+        cli_jsonint(pe_json, "SizeOfUninitializedData", EC32(optional_hdr64.SizeOfUninitializedData));
+        cli_jsonint(pe_json, "NumberOfRvaAndSizes", EC32(optional_hdr64.NumberOfRvaAndSizes));
+        cli_jsonint(pe_json, "MajorSubsystemVersion", EC16(optional_hdr64.MajorSubsystemVersion));
+        cli_jsonint(pe_json, "MinorSubsystemVersion", EC16(optional_hdr64.MinorSubsystemVersion));
+
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.BaseOfCode));
+        cli_jsonstr(pe_json, "BaseOfCode", jsonbuf);
+
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.SectionAlignment));
+        cli_jsonstr(pe_json, "SectionAlignment", jsonbuf);
 
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.FileAlignment));
-    cli_jsonstr(pe_json, "FileAlignment", jsonbuf);
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.FileAlignment));
+        cli_jsonstr(pe_json, "FileAlignment", jsonbuf);
 
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.SizeOfImage));
-    cli_jsonstr(pe_json, "SizeOfImage", jsonbuf);
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", EC32(optional_hdr64.SizeOfImage));
+        cli_jsonstr(pe_json, "SizeOfImage", jsonbuf);
 
-    snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", hdr_size);
-    cli_jsonstr(pe_json, "SizeOfHeaders", jsonbuf);
+        snprintf(jsonbuf, sizeof(jsonbuf), "0x%x", hdr_size);
+        cli_jsonstr(pe_json, "SizeOfHeaders", jsonbuf);
 #endif
     }
 
@@ -1124,50 +1080,50 @@
 
 
     switch(pe_plus ? EC16(optional_hdr64.Subsystem) : EC16(optional_hdr32.Subsystem)) {
-	case 0:
+    case 0:
         subsystem = "Unknown";
-	    break;
-	case 1:
+        break;
+    case 1:
         subsystem = "Native (svc)";
-	    native = 1;
-	    break;
-	case 2:
+        native = 1;
+        break;
+    case 2:
         subsystem = "Win32 GUI";
-	    break;
-	case 3:
+        break;
+    case 3:
         subsystem = "Win32 console";
-	    break;
-	case 5:
+        break;
+    case 5:
         subsystem = "OS/2 console";
-	    break;
-	case 7:
+        break;
+    case 7:
         subsystem = "POSIX console";
-	    break;
-	case 8:
+        break;
+    case 8:
         subsystem = "Native Win9x driver";
-	    break;
-	case 9:
+        break;
+    case 9:
         subsystem = "WinCE GUI";
-	    break;
-	case 10:
+        break;
+    case 10:
         subsystem = "EFI application";
-	    break;
-	case 11:
+        break;
+    case 11:
         subsystem = "EFI driver";
-	    break;
-	case 12:
+        break;
+    case 12:
         subsystem = "EFI runtime driver";
-	    break;
-	case 13:
+        break;
+    case 13:
         subsystem = "EFI ROM image";
-	    break;
-	case 14:
+        break;
+    case 14:
         subsystem = "Xbox";
-	    break;
-	case 16:
+        break;
+    case 16:
         subsystem = "Boot application";
-	    break;
-	default:
+        break;
+    default:
         subsystem = "Unknown";
     }
 
@@ -1181,14 +1137,14 @@
 
     if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) {
         cli_dbgmsg("Bad virtual alignemnt\n");
-	cli_append_virus(ctx,"Heuristics.Broken.Executable");
-	return CL_VIRUS;
+        cli_append_virus(ctx,"Heuristics.Broken.Executable");
+        return CL_VIRUS;
     }
 
     if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) {
         cli_dbgmsg("Bad file alignemnt\n");
-	cli_append_virus(ctx, "Heuristics.Broken.Executable");
-	return CL_VIRUS;
+        cli_append_virus(ctx, "Heuristics.Broken.Executable");
+        return CL_VIRUS;
     }
 
     fsize = map->len;
@@ -1196,16 +1152,16 @@
     section_hdr = (struct pe_image_section_hdr *) cli_calloc(nsections, sizeof(struct pe_image_section_hdr));
 
     if(!section_hdr) {
-	cli_dbgmsg("Can't allocate memory for section headers\n");
-	return CL_EMEM;
+        cli_dbgmsg("Can't allocate memory for section headers\n");
+        return CL_EMEM;
     }
 
     exe_sections = (struct cli_exe_section *) cli_calloc(nsections, sizeof(struct cli_exe_section));
     
     if(!exe_sections) {
-	cli_dbgmsg("Can't allocate memory for section headers\n");
-	free(section_hdr);
-	return CL_EMEM;
+        cli_dbgmsg("Can't allocate memory for section headers\n");
+        free(section_hdr);
+        return CL_EMEM;
     }
 
     valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment);
@@ -1213,23 +1169,27 @@
 
     if(fmap_readn(map, section_hdr, at, sizeof(struct pe_image_section_hdr)*nsections) != (int)(nsections*sizeof(struct pe_image_section_hdr))) {
         cli_dbgmsg("Can't read section header\n");
-	cli_dbgmsg("Possibly broken PE file\n");
-	free(section_hdr);
-	free(exe_sections);
-	if(DETECT_BROKEN_PE) {
-	    cli_append_virus(ctx,"Heuristics.Broken.Executable");
-	    return CL_VIRUS;
-	}
-	return CL_CLEAN;
+        cli_dbgmsg("Possibly broken PE file\n");
+
+        free(section_hdr);
+        free(exe_sections);
+
+        if(DETECT_BROKEN_PE) {
+            cli_append_virus(ctx,"Heuristics.Broken.Executable");
+            return CL_VIRUS;
+        }
+
+        return CL_CLEAN;
     }
+
     at += sizeof(struct pe_image_section_hdr)*nsections;
 
     for(i = 0; falign!=0x200 && i<nsections; i++) {
-	/* file alignment fallback mode - blah */
-	if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) {
-	    cli_dbgmsg("Found misaligned section, using 0x200\n");
-	    falign = 0x200;
-	}
+        /* file alignment fallback mode - blah */
+        if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) {
+            cli_dbgmsg("Found misaligned section, using 0x200\n");
+            falign = 0x200;
+        }
     }
 
     hdr_size = PESALIGN(hdr_size, valign); /* Aligned headers virtual size */
@@ -1238,18 +1198,57 @@
     cli_jsonint(pe_json, "NumberOfSections", nsections);
 #endif
 
+    while (rescan==1) {
+        rescan=0;
+        for (i=0; i < nsections; i++) {
+            exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
+            exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
+            exe_sections[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign);
+            exe_sections[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign);
+            exe_sections[i].chr = EC32(section_hdr[i].Characteristics);
+            exe_sections[i].urva = EC32(section_hdr[i].VirtualAddress); /* Just in case */
+            exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize);
+            exe_sections[i].uraw = EC32(section_hdr[i].PointerToRawData);
+            exe_sections[i].ursz = EC32(section_hdr[i].SizeOfRawData);
+
+            if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
+                if (exe_sections[i].raw >= fsize || exe_sections[i].uraw > fsize) {
+                    cli_dbgmsg("Broken PE file - Section %d starts or exists beyond the end of file (Offset@ %lu, Total filesize %lu)\n", i, (unsigned long)exe_sections[i].raw, (unsigned long)fsize);
+                    if (nsections == 1) {
+                        free(section_hdr);
+                        free(exe_sections);
+
+                        if(DETECT_BROKEN_PE) {
+                            cli_append_virus(ctx, "Heuristics.Broken.Executable");
+                            return CL_VIRUS;
+                        }
+
+                        return CL_CLEAN; /* no ninjas to see here! move along! */
+                    }
+
+                    for (j=i; j < nsections-1; j++)
+                        memcpy(&exe_sections[j], &exe_sections[j+1], sizeof(struct cli_exe_section));
+
+                    for (j=i; j < nsections-1; j++)
+                        memcpy(&section_hdr[j], &section_hdr[j+1], sizeof(struct pe_image_section_hdr));
+
+                    nsections--;
+                    rescan=1;
+                    break;
+                }
+
+                if (!CLI_ISCONTAINED(0, (uint32_t) fsize, exe_sections[i].raw, exe_sections[i].rsz))
+                    exe_sections[i].rsz = fsize - exe_sections[i].raw;
+
+                if (!CLI_ISCONTAINED(0, fsize, exe_sections[i].uraw, exe_sections[i].ursz))
+                    exe_sections[i].ursz = fsize - exe_sections[i].uraw;
+            }
+        }
+    }
+
     for(i = 0; i < nsections; i++) {
-	strncpy(sname, (char *) section_hdr[i].Name, 8);
-	sname[8] = 0;
-	exe_sections[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
-	exe_sections[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
-	exe_sections[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign);
-	exe_sections[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign);
-	exe_sections[i].chr = EC32(section_hdr[i].Characteristics);
-	exe_sections[i].urva = EC32(section_hdr[i].VirtualAddress); /* Just in case */
-	exe_sections[i].uvsz = EC32(section_hdr[i].VirtualSize);
-	exe_sections[i].uraw = EC32(section_hdr[i].PointerToRawData);
-	exe_sections[i].ursz = EC32(section_hdr[i].SizeOfRawData);
+        strncpy(sname, (char *) section_hdr[i].Name, 8);
+        sname[8] = 0;
 
 #if HAVE_JSON
         add_section_info(ctx, &exe_sections[i]);
@@ -1261,127 +1260,117 @@
         }
 #endif
 
-	if (!exe_sections[i].vsz && exe_sections[i].rsz)
-	    exe_sections[i].vsz=PESALIGN(exe_sections[i].ursz, valign);
+        if (!exe_sections[i].vsz && exe_sections[i].rsz)
+            exe_sections[i].vsz=PESALIGN(exe_sections[i].ursz, valign);
+
+        cli_dbgmsg("Section %d\n", i);
+        cli_dbgmsg("Section name: %s\n", sname);
+        cli_dbgmsg("Section data (from headers - in memory)\n");
+        cli_dbgmsg("VirtualSize: 0x%x 0x%x\n", exe_sections[i].uvsz, exe_sections[i].vsz);
+        cli_dbgmsg("VirtualAddress: 0x%x 0x%x\n", exe_sections[i].urva, exe_sections[i].rva);
+        cli_dbgmsg("SizeOfRawData: 0x%x 0x%x\n", exe_sections[i].ursz, exe_sections[i].rsz);
+        cli_dbgmsg("PointerToRawData: 0x%x 0x%x\n", exe_sections[i].uraw, exe_sections[i].raw);
+
+        if(exe_sections[i].chr & 0x20) {
+            cli_dbgmsg("Section contains executable code\n");
+
+            if(exe_sections[i].vsz < exe_sections[i].rsz) {
+                cli_dbgmsg("Section contains free space\n");
+                /*
+                cli_dbgmsg("Dumping %d bytes\n", section_hdr.SizeOfRawData - section_hdr.VirtualSize);
+                ddump(desc, section_hdr.PointerToRawData + section_hdr.VirtualSize, section_hdr.SizeOfRawData - section_hdr.VirtualSize, cli_gentemp(NULL));
+                */
+            }
+        }
+
+        if(exe_sections[i].chr & 0x20000000)
+            cli_dbgmsg("Section's memory is executable\n");
 
-	if (exe_sections[i].rsz && fsize>exe_sections[i].raw && !CLI_ISCONTAINED(0, (uint32_t) fsize, exe_sections[i].raw, exe_sections[i].rsz))
-	    exe_sections[i].rsz = fsize - exe_sections[i].raw;
-	
-	cli_dbgmsg("Section %d\n", i);
-	cli_dbgmsg("Section name: %s\n", sname);
-	cli_dbgmsg("Section data (from headers - in memory)\n");
-	cli_dbgmsg("VirtualSize: 0x%x 0x%x\n", exe_sections[i].uvsz, exe_sections[i].vsz);
-	cli_dbgmsg("VirtualAddress: 0x%x 0x%x\n", exe_sections[i].urva, exe_sections[i].rva);
-	cli_dbgmsg("SizeOfRawData: 0x%x 0x%x\n", exe_sections[i].ursz, exe_sections[i].rsz);
-	cli_dbgmsg("PointerToRawData: 0x%x 0x%x\n", exe_sections[i].uraw, exe_sections[i].raw);
-
-	if(exe_sections[i].chr & 0x20) {
-	    cli_dbgmsg("Section contains executable code\n");
-
-	    if(exe_sections[i].vsz < exe_sections[i].rsz) {
-		cli_dbgmsg("Section contains free space\n");
-		/*
-		cli_dbgmsg("Dumping %d bytes\n", section_hdr.SizeOfRawData - section_hdr.VirtualSize);
-		ddump(desc, section_hdr.PointerToRawData + section_hdr.VirtualSize, section_hdr.SizeOfRawData - section_hdr.VirtualSize, cli_gentemp(NULL));
-		*/
+        if(exe_sections[i].chr & 0x80000000)
+            cli_dbgmsg("Section's memory is writeable\n");
 
-	    }
-	}
+        if (DETECT_BROKEN_PE && (!valign || (exe_sections[i].urva % valign))) { /* Bad virtual alignment */
+            cli_dbgmsg("VirtualAddress is misaligned\n");
+            cli_dbgmsg("------------------------------------\n");
+            cli_append_virus(ctx, "Heuristics.Broken.Executable");
+            free(section_hdr);
+            free(exe_sections);
+            return CL_VIRUS;
+        }
 
-	if(exe_sections[i].chr & 0x20000000)
-	    cli_dbgmsg("Section's memory is executable\n");
+        if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
+            if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !*sname && exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000 && exe_sections[i].chr == 0xe0000060) polipos = i;
 
-	if(exe_sections[i].chr & 0x80000000)
-	    cli_dbgmsg("Section's memory is writeable\n");
+            /* check hash section sigs */
+            if((DCONF & PE_CONF_MD5SECT) && ctx->engine->hm_mdb) {
+                ret = scan_pe_mdb(ctx, &exe_sections[i]);
+                if (ret != CL_CLEAN) {
+                    if (ret != CL_VIRUS)
+                        cli_errmsg("scan_pe: scan_pe_mdb failed: %s!\n", cl_strerror(ret));
+
+                    cli_dbgmsg("------------------------------------\n");
+                    free(section_hdr);
+                    free(exe_sections);
+                    return ret;
+                }
+            }
+        }
+        cli_dbgmsg("------------------------------------\n");
 
-	if (DETECT_BROKEN_PE && (!valign || (exe_sections[i].urva % valign))) { /* Bad virtual alignment */
-	    cli_dbgmsg("VirtualAddress is misaligned\n");
-	    cli_dbgmsg("------------------------------------\n");
-	    cli_append_virus(ctx, "Heuristics.Broken.Executable");
-	    free(section_hdr);
-	    free(exe_sections);
-	    return CL_VIRUS;
-	}
+        if (exe_sections[i].urva>>31 || exe_sections[i].uvsz>>31 || (exe_sections[i].rsz && exe_sections[i].uraw>>31) || exe_sections[i].ursz>>31) {
+            cli_dbgmsg("Found PE values with sign bit set\n");
 
-	if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
-	    if (exe_sections[i].raw >= fsize) { /* really broken */
-	      cli_dbgmsg("Broken PE file - Section %d starts beyond the end of file (Offset@ %lu, Total filesize %lu)\n", i, (unsigned long)exe_sections[i].raw, (unsigned long)fsize);
-	      cli_dbgmsg("------------------------------------\n");
-		free(section_hdr);
-		free(exe_sections);
-		if(DETECT_BROKEN_PE) {
-		    cli_append_virus(ctx, "Heuristics.Broken.Executable");
-		    return CL_VIRUS;
-		}
-		return CL_CLEAN; /* no ninjas to see here! move along! */
-	    }
+            free(section_hdr);
+            free(exe_sections);
+            if(DETECT_BROKEN_PE) {
+                cli_append_virus(ctx, "Heuristics.Broken.Executable");
+                return CL_VIRUS;
+            }
 
-	    if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !*sname && exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000 && exe_sections[i].chr == 0xe0000060) polipos = i;
+            return CL_CLEAN;
+        }
 
-	    /* check hash section sigs */
-	    if((DCONF & PE_CONF_MD5SECT) && ctx->engine->hm_mdb) {
-	        ret = scan_pe_mdb(ctx, &exe_sections[i]);
-	        if (ret != CL_CLEAN) {
-	            if (ret != CL_VIRUS)
-	                cli_errmsg("scan_pe: scan_pe_mdb failed: %s!\n", cl_strerror(ret));
-		    cli_dbgmsg("------------------------------------\n");
-	            free(section_hdr);
-	            free(exe_sections);
-	            return ret;
-	        }
-	    }
-	}
-	cli_dbgmsg("------------------------------------\n");
+        if(!i) {
+            if (DETECT_BROKEN_PE && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */
+                cli_dbgmsg("First section is in the wrong place\n");
+                cli_append_virus(ctx, "Heuristics.Broken.Executable");
+                free(section_hdr);
+                free(exe_sections);
+                return CL_VIRUS;
+            }
 
-	if (exe_sections[i].urva>>31 || exe_sections[i].uvsz>>31 || (exe_sections[i].rsz && exe_sections[i].uraw>>31) || exe_sections[i].ursz>>31) {
-	    cli_dbgmsg("Found PE values with sign bit set\n");
-	    free(section_hdr);
-	    free(exe_sections);
-	    if(DETECT_BROKEN_PE) {
-		cli_append_virus(ctx, "Heuristics.Broken.Executable");
-		return CL_VIRUS;
-	    }
-	    return CL_CLEAN;
-	}
+            min = exe_sections[i].rva;
+            max = exe_sections[i].rva + exe_sections[i].rsz;
+        } else {
+            if (DETECT_BROKEN_PE && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */
+                cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n");
+                cli_append_virus(ctx, "Heuristics.Broken.Executable");
+                free(section_hdr);
+                free(exe_sections);
+                return CL_VIRUS;
+            }
 
-	if(!i) {
-	    if (DETECT_BROKEN_PE && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */
-	        cli_dbgmsg("First section is in the wrong place\n");
-		cli_append_virus(ctx, "Heuristics.Broken.Executable");
-		free(section_hdr);
-		free(exe_sections);
-		return CL_VIRUS;
-	    }
-	    min = exe_sections[i].rva;
-	    max = exe_sections[i].rva + exe_sections[i].rsz;
-	} else {
-	    if (DETECT_BROKEN_PE && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */
-	        cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n");
-		cli_append_virus(ctx, "Heuristics.Broken.Executable");
-		free(section_hdr);
-		free(exe_sections);
-		return CL_VIRUS;
-	    }
-	    if(exe_sections[i].rva < min)
-	        min = exe_sections[i].rva;
+            if(exe_sections[i].rva < min)
+                min = exe_sections[i].rva;
 
-	    if(exe_sections[i].rva + exe_sections[i].rsz > max) {
-	        max = exe_sections[i].rva + exe_sections[i].rsz;
-		overlays = exe_sections[i].raw + exe_sections[i].rsz;
-	    }
-	}
+            if(exe_sections[i].rva + exe_sections[i].rsz > max) {
+                max = exe_sections[i].rva + exe_sections[i].rsz;
+                overlays = exe_sections[i].raw + exe_sections[i].rsz;
+            }
+        }
     }
 
     free(section_hdr);
 
     if(!(ep = cli_rawaddr(vep, exe_sections, nsections, &err, fsize, hdr_size)) && err) {
-	cli_dbgmsg("EntryPoint out of file\n");
-	free(exe_sections);
-	if(DETECT_BROKEN_PE) {
-	    cli_append_virus(ctx,"Heuristics.Broken.Executable");
-	    return CL_VIRUS;
-	}
-	return CL_CLEAN;
+        cli_dbgmsg("EntryPoint out of file\n");
+        free(exe_sections);
+        if(DETECT_BROKEN_PE) {
+            cli_append_virus(ctx,"Heuristics.Broken.Executable");
+            return CL_VIRUS;
+        }
+
+        return CL_CLEAN;
     }
 
 #if HAVE_JSON
@@ -1395,8 +1384,8 @@
     cli_dbgmsg("EntryPoint offset: 0x%x (%d)\n", ep, ep);
 
     if(pe_plus) { /* Do not continue for PE32+ files */
-	free(exe_sections);
-	return CL_CLEAN;
+        free(exe_sections);
+        return CL_CLEAN;
     }
 
     epsize = fmap_readn(map, epbuff, ep, 4096);
@@ -1416,14 +1405,14 @@
     /* } */
 
     if(overlays) {
-	int overlays_sz = fsize - overlays;
-	if(overlays_sz > 0) {
-	    ret = cli_scanishield(ctx, overlays, overlays_sz);
-	    if(ret != CL_CLEAN) {
-		free(exe_sections);
-		return ret;
-	    }
-	}
+        int overlays_sz = fsize - overlays;
+        if(overlays_sz > 0) {
+            ret = cli_scanishield(ctx, overlays, overlays_sz);
+            if(ret != CL_CLEAN) {
+                free(exe_sections);
+                return ret;
+            }
+        }
     }
 
     pedata.nsections = nsections;
@@ -1441,10 +1430,11 @@
     /* Bytecode BC_PE_ALL hook */
     bc_ctx = cli_bytecode_context_alloc();
     if (!bc_ctx) {
-	cli_errmsg("cli_scanpe: can't allocate memory for bc_ctx\n");
-	free(exe_sections);
-	return CL_EMEM;
+        cli_errmsg("cli_scanpe: can't allocate memory for bc_ctx\n");
+        free(exe_sections);
+        return CL_EMEM;
     }
+
     cli_bytecode_context_setpe(bc_ctx, &pedata, exe_sections);
     cli_bytecode_context_setctx(bc_ctx, ctx);
     ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_ALL, map);
@@ -1464,228 +1454,284 @@
     /* W32.Parite.B */
     if(SCAN_ALGO && (DCONF & PE_CONF_PARITE) && !dll && epsize == 4096 && ep == exe_sections[nsections - 1].raw) {
         const char *pt = cli_memstr(epbuff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
-	if(pt) {
-	    pt += 15;
-	    if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) {
-	        cli_append_virus(ctx,"Heuristics.W32.Parite.B");
-		if (!SCAN_ALL) {
-		    free(exe_sections);
-		    return CL_VIRUS;
-		}
-		viruses_found++;
-	    }
-	}
+        if(pt) {
+            pt += 15;
+            if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) {
+                cli_append_virus(ctx,"Heuristics.W32.Parite.B");
+                if (!SCAN_ALL) {
+                    free(exe_sections);
+                    return CL_VIRUS;
+                }
+
+                viruses_found++;
+            }
+        }
     }
 
     /* Kriz */
     if(SCAN_ALGO && (DCONF & PE_CONF_KRIZ) && epsize >= 200 && CLI_ISCONTAINED(exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz, ep, 0x0fd2) && epbuff[1]=='\x9c' && epbuff[2]=='\x60') {
-	enum {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSXORPRFX,KZSXOR,KZSDDELTA,KZSLOOP,KZSTOP};
-	uint8_t kzs[] = {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSTRASH,KZSXORPRFX,KZSXOR,KZSTRASH,KZSDDELTA,KZSTRASH,KZSLOOP,KZSTOP};
-	uint8_t *kzstate = kzs;
-	uint8_t *kzcode = (uint8_t *)epbuff + 3;
-	uint8_t kzdptr=0xff, kzdsize=0xff;
-	int kzlen = 197, kzinitlen=0xffff, kzxorlen=-1;
-	cli_dbgmsg("in kriz\n");
-
-	while(*kzstate!=KZSTOP) {
-	    uint8_t op;
-	    if(kzlen<=6) break;
-	    op = *kzcode++;
-	    kzlen--;
-	    switch (*kzstate) {
-	    case KZSTRASH: case KZSGETSIZE: {
-		int opsz=0;
-		switch(op) {
-		case 0x81:
-		    kzcode+=5;
-		    kzlen-=5;
-		    break;
-		case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbd: case 0xbe: case 0xbf:
-		    if(*kzstate==KZSGETSIZE && cli_readint32(kzcode)==0x0fd2) {
-			kzinitlen = kzlen-5;
-			kzdsize=op-0xb8;
-			kzstate++;
-			op=4; /* fake the register to avoid breaking out */
-			cli_dbgmsg("kriz: using #%d as size counter\n", kzdsize);
-		    }
-		    opsz=4;
-		case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4d: case 0x4e: case 0x4f:
-		    op&=7;
-		    if(op!=kzdptr && op!=kzdsize) {
-			kzcode+=opsz;
-			kzlen-=opsz;
-			break;
-		    }
-		default:
-		    kzcode--;
-		    kzlen++;
-		    kzstate++;
-		}
-		break;
-	    }
-	    case KZSCDELTA:
-		if(op==0xe8 && (uint32_t)cli_readint32(kzcode) < 0xff) {
-		    kzlen-=*kzcode+4;
-		    kzcode+=*kzcode+4;
-		    kzstate++;
-		} else *kzstate=KZSTOP;
-		break;
-	    case KZSPDELTA:
-		if((op&0xf8)==0x58 && (kzdptr=op-0x58)!=4) {
-		    kzstate++;
-		    cli_dbgmsg("kriz: using #%d as pointer\n", kzdptr);
-		} else *kzstate=KZSTOP;
-		break;
-	    case KZSXORPRFX:
-		kzstate++;
-		if(op==0x3e) break;
-	    case KZSXOR:
-		if (op==0x80 && *kzcode==kzdptr+0xb0) {
-		    kzxorlen=kzlen;
-		    kzcode+=+6;
-		    kzlen-=+6;
-		    kzstate++;
-		} else *kzstate=KZSTOP;
-		break;
-	    case KZSDDELTA:
-		if (op==kzdptr+0x48) kzstate++;
-		else *kzstate=KZSTOP;
-		break;
-	    case KZSLOOP:
-		if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
-		    cli_append_virus(ctx,"Heuristics.W32.Kriz");
-		    if (!SCAN_ALL) {
-		        free(exe_sections);
-			return CL_VIRUS;
-		    }
-		    viruses_found++;
-		}
-		cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
-		kzstate++;
-	    }
-	}
+        enum {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSXORPRFX,KZSXOR,KZSDDELTA,KZSLOOP,KZSTOP};
+        uint8_t kzs[] = {KZSTRASH,KZSCDELTA,KZSPDELTA,KZSGETSIZE,KZSTRASH,KZSXORPRFX,KZSXOR,KZSTRASH,KZSDDELTA,KZSTRASH,KZSLOOP,KZSTOP};
+        uint8_t *kzstate = kzs;
+        uint8_t *kzcode = (uint8_t *)epbuff + 3;
+        uint8_t kzdptr=0xff, kzdsize=0xff;
+        int kzlen = 197, kzinitlen=0xffff, kzxorlen=-1;
+        cli_dbgmsg("in kriz\n");
+
+        while(*kzstate!=KZSTOP) {
+            uint8_t op;
+            if(kzlen<=6)
+                break;
+
+            op = *kzcode++;
+            kzlen--;
+
+            switch (*kzstate) {
+            case KZSTRASH:
+            case KZSGETSIZE: {
+                int opsz=0;
+                switch(op) {
+                case 0x81:
+                    kzcode+=5;
+                    kzlen-=5;
+                    break;
+                case 0xb8:
+                case 0xb9:
+                case 0xba:
+                case 0xbb:
+                case 0xbd:
+                case 0xbe:
+                case 0xbf:
+                    if(*kzstate==KZSGETSIZE && cli_readint32(kzcode)==0x0fd2) {
+                        kzinitlen = kzlen-5;
+                        kzdsize=op-0xb8;
+                        kzstate++;
+                        op=4; /* fake the register to avoid breaking out */
+
+                        cli_dbgmsg("kriz: using #%d as size counter\n", kzdsize);
+                    }
+                    opsz=4;
+                case 0x48:
+                case 0x49:
+                case 0x4a:
+                case 0x4b:
+                case 0x4d:
+                case 0x4e:
+                case 0x4f:
+                    op&=7;
+                    if(op!=kzdptr && op!=kzdsize) {
+                        kzcode+=opsz;
+                        kzlen-=opsz;
+                        break;
+                    }
+                default:
+                    kzcode--;
+                    kzlen++;
+                    kzstate++;
+                }
+
+                break;
+            }
+            case KZSCDELTA:
+                if(op==0xe8 && (uint32_t)cli_readint32(kzcode) < 0xff) {
+                    kzlen-=*kzcode+4;
+                    kzcode+=*kzcode+4;
+                    kzstate++;
+                } else {
+                    *kzstate=KZSTOP;
+                }
+
+                break;
+            case KZSPDELTA:
+                if((op&0xf8)==0x58 && (kzdptr=op-0x58)!=4) {
+                    kzstate++;
+                    cli_dbgmsg("kriz: using #%d as pointer\n", kzdptr);
+                } else {
+                    *kzstate=KZSTOP;
+                }
+
+                break;
+            case KZSXORPRFX:
+                kzstate++;
+                if(op==0x3e)
+                    break;
+            case KZSXOR:
+                if (op==0x80 && *kzcode==kzdptr+0xb0) {
+                    kzxorlen=kzlen;
+                    kzcode+=+6;
+                    kzlen-=+6;
+                    kzstate++;
+                } else {
+                    *kzstate=KZSTOP;
+                }
+
+                break;
+            case KZSDDELTA:
+                if (op==kzdptr+0x48)
+                    kzstate++;
+                else
+                    *kzstate=KZSTOP;
+
+                break;
+            case KZSLOOP:
+                if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
+                    cli_append_virus(ctx,"Heuristics.W32.Kriz");
+                    if (!SCAN_ALL) {
+                        free(exe_sections);
+                        return CL_VIRUS;
+                    }
+
+                    viruses_found++;
+                }
+
+                cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
+                kzstate++;
+            }
+        }
     }
 
     /* W32.Magistr.A/B */
     if(SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (nsections>1) && (exe_sections[nsections - 1].chr & 0x80000000)) {
         uint32_t rsize, vsize, dam = 0;
 
-	vsize = exe_sections[nsections - 1].uvsz;
-	rsize = exe_sections[nsections - 1].rsz;
-	if(rsize < exe_sections[nsections - 1].ursz) {
-	    rsize = exe_sections[nsections - 1].ursz;
-	    dam = 1;
-	}
+        vsize = exe_sections[nsections - 1].uvsz;
+        rsize = exe_sections[nsections - 1].rsz;
+        if(rsize < exe_sections[nsections - 1].ursz) {
+            rsize = exe_sections[nsections - 1].ursz;
+            dam = 1;
+        }
 
-	if(vsize >= 0x612c && rsize >= 0x612c && ((vsize & 0xff) == 0xec)) {
-		int bw = rsize < 0x7000 ? rsize : 0x7000;
-		const char *tbuff;
-
-	    if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
-		if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
-		    cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A");
-		    if (!SCAN_ALL) {
-		        free(exe_sections);
-			return CL_VIRUS;
-		    }
-		    viruses_found++;
-		}
-	    }
+        if(vsize >= 0x612c && rsize >= 0x612c && ((vsize & 0xff) == 0xec)) {
+            int bw = rsize < 0x7000 ? rsize : 0x7000;
+            const char *tbuff;
+
+            if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
+                if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
+                    cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A");
+                    if (!SCAN_ALL) {
+                        free(exe_sections);
+                        return CL_VIRUS;
+                    }
 
-	} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
-		int bw = rsize < 0x8000 ? rsize : 0x8000;
-		const char *tbuff;
-
-	    if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
-		if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
-		    cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B");
-		    if (!SCAN_ALL) {
-		        free(exe_sections);
-			return CL_VIRUS;
-		    }
-		    viruses_found++;
-		} 
-	    }
-	}
+                    viruses_found++;
+                }
+            }
+        } else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
+            int bw = rsize < 0x8000 ? rsize : 0x8000;
+            const char *tbuff;
+
+            if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
+                if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
+                    cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B");
+                    if (!SCAN_ALL) {
+                        free(exe_sections);
+                        return CL_VIRUS;
+                    }
+
+                    viruses_found++;
+                } 
+            }
+        }
     }
 
     /* W32.Polipos.A */
     while(polipos && !dll && nsections > 2 && nsections < 13 && e_lfanew <= 0x800 && (EC16(optional_hdr32.Subsystem) == 2 || EC16(optional_hdr32.Subsystem) == 3) && EC16(file_hdr.Machine) == 0x14c && optional_hdr32.SizeOfStackReserve >= 0x80000) {
-	uint32_t jump, jold, *jumps = NULL;
-	const uint8_t *code;
-	unsigned int xsjs = 0;
-
-	if(exe_sections[0].rsz > CLI_MAX_ALLOCATION) break;
-
-	if(!exe_sections[0].rsz) break;
-	if(!(code=fmap_need_off_once(map, exe_sections[0].raw, exe_sections[0].rsz))) break;
-	for(i=0; i<exe_sections[0].rsz - 5; i++) {
-	    if((uint8_t)(code[i]-0xe8) > 1) continue;
-	    jump = cli_rawaddr(exe_sections[0].rva+i+5+cli_readint32(&code[i+1]), exe_sections, nsections, &err, fsize, hdr_size);
-	    if(err || !CLI_ISCONTAINED(exe_sections[polipos].raw, exe_sections[polipos].rsz, jump, 9)) continue;
-	    if(xsjs % 128 == 0) {
-		if(xsjs == 1280) break;
-		if(!(jumps=(uint32_t *)cli_realloc2(jumps, (xsjs+128)*sizeof(uint32_t)))) {
-		    free(exe_sections);
-		    return CL_EMEM;
-		}
-	    }
-	    j=0;
-	    for(; j<xsjs; j++) {
-		if(jumps[j]<jump) continue;
-		if(jumps[j]==jump) {
-		    xsjs--;
-		    break;
-		}
-		jold=jumps[j];
-		jumps[j]=jump;
-		jump=jold;
-	    }
-	    jumps[j]=jump;
-	    xsjs++;
-	}
-	if(!xsjs) break;
-	cli_dbgmsg("Polipos: Checking %d xsect jump(s)\n", xsjs);
-	for(i=0;i<xsjs;i++) {
-	    if(!(code = fmap_need_off_once(map, jumps[i], 9))) continue;
-	    if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]==0x0ec && ((jump==0x83ec8b55 && code[6]==0x60) || (jump==0x81ec8b55 && !code[7] && !code[8])))) {
-		cli_append_virus(ctx,"Heuristics.W32.Polipos.A");
-		if (!SCAN_ALL) {
-		    free(jumps);
-		    free(exe_sections);
-		    return CL_VIRUS;
-		}
-		viruses_found++;
-	    }
-	}
-	free(jumps);
-	break;
+        uint32_t jump, jold, *jumps = NULL;
+        const uint8_t *code;
+        unsigned int xsjs = 0;
+
+        if(exe_sections[0].rsz > CLI_MAX_ALLOCATION)
+            break;
+        if(!exe_sections[0].rsz)
+            break;
+        if(!(code=fmap_need_off_once(map, exe_sections[0].raw, exe_sections[0].rsz)))
+            break;
+
+        for(i=0; i<exe_sections[0].rsz - 5; i++) {
+            if((uint8_t)(code[i]-0xe8) > 1)
+                continue;
+
+            jump = cli_rawaddr(exe_sections[0].rva+i+5+cli_readint32(&code[i+1]), exe_sections, nsections, &err, fsize, hdr_size);
+            if(err || !CLI_ISCONTAINED(exe_sections[polipos].raw, exe_sections[polipos].rsz, jump, 9))
+                continue;
+
+            if(xsjs % 128 == 0) {
+                if(xsjs == 1280)
+                    break;
+
+                if(!(jumps=(uint32_t *)cli_realloc2(jumps, (xsjs+128)*sizeof(uint32_t)))) {
+                    free(exe_sections);
+                    return CL_EMEM;
+                }
+            }
+
+            j=0;
+            for(; j<xsjs; j++) {
+                if(jumps[j]<jump)
+                    continue;
+                if(jumps[j]==jump) {
+                    xsjs--;
+                    break;
+                }
+
+                jold=jumps[j];
+                jumps[j]=jump;
+                jump=jold;
+            }
+
+            jumps[j]=jump;
+            xsjs++;
+        }
+
+        if(!xsjs)
+            break;
+
+        cli_dbgmsg("Polipos: Checking %d xsect jump(s)\n", xsjs);
+        for(i=0;i<xsjs;i++) {
+            if(!(code = fmap_need_off_once(map, jumps[i], 9)))
+                continue;
+
+            if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]==0x0ec && ((jump==0x83ec8b55 && code[6]==0x60) || (jump==0x81ec8b55 && !code[7] && !code[8])))) {
+                cli_append_virus(ctx,"Heuristics.W32.Polipos.A");
+                if (!SCAN_ALL) {
+                    free(jumps);
+                    free(exe_sections);
+                    return CL_VIRUS;
+                }
+
+                viruses_found++;
+            }
+        }
+
+        free(jumps);
+        break;
     }
 
     /* Trojan.Swizzor.Gen */
     if (SCAN_ALGO && (DCONF & PE_CONF_SWIZZOR) && nsections > 1 && fsize > 64*1024 && fsize < 4*1024*1024) {
-	    if(dirs[2].Size) {
-		    struct swizz_stats *stats = cli_calloc(1, sizeof(*stats));
-		    unsigned int m = 1000;
-		    ret = CL_CLEAN;
-
-		    if (!stats)
-			    ret = CL_EMEM;
-		    else {
-			    cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
-			    if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) {
-				cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen");
-			    }
-			    free(stats);
-		    }
-		    if (ret != CL_CLEAN) {
-			if (!(ret == CL_VIRUS && SCAN_ALL)) {
-			    free(exe_sections);
-			    return ret;
-			}
-			viruses_found++;
-		    }
-	    }
+        if(dirs[2].Size) {
+            struct swizz_stats *stats = cli_calloc(1, sizeof(*stats));
+            unsigned int m = 1000;
+            ret = CL_CLEAN;
+
+            if (!stats) {
+                ret = CL_EMEM;
+            } else {
+                cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
+                if ((ret = cli_detect_swizz(stats)) == CL_VIRUS)
+                    cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen");
+
+                free(stats);
+            }
+            if (ret != CL_CLEAN) {
+                if (!(ret == CL_VIRUS && SCAN_ALL)) {
+                    free(exe_sections);
+                    return ret;
+                }
+
+                viruses_found++;
+            }
+        }
     }
 
 
@@ -1699,722 +1745,733 @@
     /* try to find the first section with physical size == 0 */
     found = 0;
     if(DCONF & (PE_CONF_UPX | PE_CONF_FSG | PE_CONF_MEW)) {
-	for(i = 0; i < (unsigned int) nsections - 1; i++) {
-	    if(!exe_sections[i].rsz && exe_sections[i].vsz && exe_sections[i + 1].rsz && exe_sections[i + 1].vsz) {
-		found = 1;
-		cli_dbgmsg("UPX/FSG/MEW: empty section found - assuming compression\n");
+        for(i = 0; i < (unsigned int) nsections - 1; i++) {
+            if(!exe_sections[i].rsz && exe_sections[i].vsz && exe_sections[i + 1].rsz && exe_sections[i + 1].vsz) {
+                found = 1;
+                cli_dbgmsg("UPX/FSG/MEW: empty section found - assuming compression\n");
 #if HAVE_JSON
-        cli_jsonbool(pe_json, "HasEmptySection", 1);
+                cli_jsonbool(pe_json, "HasEmptySection", 1);
 #endif
-		break;
-	    }
-	}
+                break;
+            }
+        }
     }
 
     /* MEW support */
     if (found && (DCONF & PE_CONF_MEW) && epsize>=16 && epbuff[0]=='\xe9') {
-	uint32_t fileoffset;
-	const char *tbuff;
-
-	fileoffset = (vep + cli_readint32(epbuff + 1) + 5);
-	while (fileoffset == 0x154 || fileoffset == 0x158) {
-	    char *src;
-	    uint32_t offdiff, uselzma;
-
-	    cli_dbgmsg ("MEW: found MEW characteristics %08X + %08X + 5 = %08X\n", 
-			cli_readint32(epbuff + 1), vep, cli_readint32(epbuff + 1) + vep + 5);
-
-	    if(!(tbuff = fmap_need_off_once(map, fileoffset, 0xb0)))
-		break;
-	    if (fileoffset == 0x154) cli_dbgmsg("MEW: Win9x compatibility was set!\n");
-	    else cli_dbgmsg("MEW: Win9x compatibility was NOT set!\n");
-
-	    if((offdiff = cli_readint32(tbuff+1) - EC32(optional_hdr32.ImageBase)) <= exe_sections[i + 1].rva || offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4) {
-	        cli_dbgmsg("MEW: ESI is not in proper section\n");
-		break;
-	    }
-	    offdiff -= exe_sections[i + 1].rva;
+        uint32_t fileoffset;
+        const char *tbuff;
 
-	    if(!exe_sections[i + 1].rsz) {
-		cli_dbgmsg("MEW: mew section is empty\n");
-		break;
-	    }
-	    ssize = exe_sections[i + 1].vsz;
-	    dsize = exe_sections[i].vsz;
+        fileoffset = (vep + cli_readint32(epbuff + 1) + 5);
+        while (fileoffset == 0x154 || fileoffset == 0x158) {
+            char *src;
+            uint32_t offdiff, uselzma;
 
-	    cli_dbgmsg("MEW: ssize %08x dsize %08x offdiff: %08x\n", ssize, dsize, offdiff);
+            cli_dbgmsg ("MEW: found MEW characteristics %08X + %08X + 5 = %08X\n", 
+                cli_readint32(epbuff + 1), vep, cli_readint32(epbuff + 1) + vep + 5);
 
-	    CLI_UNPSIZELIMITS("MEW", MAX(ssize, dsize));
-	    CLI_UNPSIZELIMITS("MEW", MAX(ssize + dsize, exe_sections[i + 1].rsz));
+            if(!(tbuff = fmap_need_off_once(map, fileoffset, 0xb0)))
+                break;
 
-	    if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize) {
-	        cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
-		break;
-	    }
+            if (fileoffset == 0x154)
+                cli_dbgmsg("MEW: Win9x compatibility was set!\n");
+            else
+                cli_dbgmsg("MEW: Win9x compatibility was NOT set!\n");
 
-	    /* allocate needed buffer */
-	    if (!(src = cli_calloc (ssize + dsize, sizeof(char)))) {
-	        free(exe_sections);
-		return CL_EMEM;
-	    }
+            if((offdiff = cli_readint32(tbuff+1) - EC32(optional_hdr32.ImageBase)) <= exe_sections[i + 1].rva || offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4) {
+                cli_dbgmsg("MEW: ESI is not in proper section\n");
+                break;
+            }
 
-	    if((bytes = fmap_readn(map, src + dsize, exe_sections[i + 1].raw, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
-		cli_dbgmsg("MEW: Can't read %d bytes [read: %lu]\n", exe_sections[i + 1].rsz, (unsigned long)bytes);
-		free(exe_sections);
-		free(src);
-		return CL_EREAD;
-	    }
-	    cli_dbgmsg("MEW: %u (%08x) bytes read\n", (unsigned int)bytes, (unsigned int)bytes);
+            offdiff -= exe_sections[i + 1].rva;
 
-	    /* count offset to lzma proc, if lzma used, 0xe8 -> call */
-	    if (tbuff[0x7b] == '\xe8') {
-	        if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(tbuff + 0x7c) + fileoffset + 0x80, 4)) {
-		    cli_dbgmsg("MEW: lzma proc out of bounds!\n");
-		    free(src);
-		    break; /* to next unpacker in chain */
-		}
-		uselzma = cli_readint32(tbuff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
-	    } else {
-	        uselzma = 0;
-	    }
+            if(!exe_sections[i + 1].rsz) {
+                cli_dbgmsg("MEW: mew section is empty\n");
+                break;
+            }
+
+            ssize = exe_sections[i + 1].vsz;
+            dsize = exe_sections[i].vsz;
+
+            cli_dbgmsg("MEW: ssize %08x dsize %08x offdiff: %08x\n", ssize, dsize, offdiff);
+
+            CLI_UNPSIZELIMITS("MEW", MAX(ssize, dsize));
+            CLI_UNPSIZELIMITS("MEW", MAX(ssize + dsize, exe_sections[i + 1].rsz));
+
+            if (exe_sections[i + 1].rsz < offdiff + 12 || exe_sections[i + 1].rsz > ssize) {
+                cli_dbgmsg("MEW: Size mismatch: %08x\n", exe_sections[i + 1].rsz);
+                break;
+            }
+
+            /* allocate needed buffer */
+            if (!(src = cli_calloc (ssize + dsize, sizeof(char)))) {
+                free(exe_sections);
+                return CL_EMEM;
+            }
+
+            if((bytes = fmap_readn(map, src + dsize, exe_sections[i + 1].raw, exe_sections[i + 1].rsz)) != exe_sections[i + 1].rsz) {
+                cli_dbgmsg("MEW: Can't read %d bytes [read: %lu]\n", exe_sections[i + 1].rsz, (unsigned long)bytes);
+                free(exe_sections);
+                free(src);
+                return CL_EREAD;
+            }
+
+            cli_dbgmsg("MEW: %u (%08x) bytes read\n", (unsigned int)bytes, (unsigned int)bytes);
+
+            /* count offset to lzma proc, if lzma used, 0xe8 -> call */
+            if (tbuff[0x7b] == '\xe8') {
+                if (!CLI_ISCONTAINED(exe_sections[1].rva, exe_sections[1].vsz, cli_readint32(tbuff + 0x7c) + fileoffset + 0x80, 4)) {
+                    cli_dbgmsg("MEW: lzma proc out of bounds!\n");
+                    free(src);
+                    break; /* to next unpacker in chain */
+                }
+
+                uselzma = cli_readint32(tbuff + 0x7c) - (exe_sections[0].rva - fileoffset - 0x80);
+            } else {
+                uselzma = 0;
+            }
 
 #if HAVE_JSON
-        cli_jsonstr(pe_json, "Packer", "MEW");
+            cli_jsonstr(pe_json, "Packer", "MEW");
 #endif
 
-	    CLI_UNPTEMP("MEW",(src,exe_sections,0));
-	    CLI_UNPRESULTS("MEW",(unmew11(src, offdiff, ssize, dsize, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, uselzma, ndesc)),1,(src,0));
-	    break;
-	}
+            CLI_UNPTEMP("MEW",(src,exe_sections,0));
+            CLI_UNPRESULTS("MEW",(unmew11(src, offdiff, ssize, dsize, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, uselzma, ndesc)),1,(src,0));
+            break;
+        }
     }
 
     if(epsize<168) {
-	free(exe_sections);
-	return CL_CLEAN;
+        free(exe_sections);
+        return CL_CLEAN;
     }
 
     if (found || upack) {
-	/* Check EP for UPX vs. FSG vs. Upack */
+        /* Check EP for UPX vs. FSG vs. Upack */
 
-	/* Upack 0.39 produces 2 types of executables
-	 * 3 sections:           | 2 sections (one empty, I don't chech found if !upack, since it's in OR above):
-	 *   mov esi, value      |   pusha
-	 *   lodsd               |   call $+0x9
-	 *   push eax            |
-	 *
-	 * Upack 1.1/1.2 Beta produces [based on 2 samples (sUx) provided by aCaB]:
-	 * 2 sections
-	 *   mov esi, value
-	 *   loads
-	 *   mov edi, eax
-	 *
-	 * Upack unknown [sample 0297729]
-	 * 3 sections
-	 *   mov esi, value
-	 *   push [esi]
-	 *   jmp
-	 * 
-	 */
-	/* upack 0.39-3s + sample 0151477*/
- 	while(((upack && nsections == 3) && /* 3 sections */
-	    ((
-	     epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
-	     epbuff[5] == '\xad' && epbuff[6] == '\x50' /* lodsd; push eax */
-	     )
-	    || 
-	    /* based on 0297729 sample from aCaB */
-	    (epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
-	     epbuff[5] == '\xff' && epbuff[6] == '\x36' /* push [esi] */
-	     )
-	   )) 
-	   ||
-	   ((!upack && nsections == 2) && /* 2 sections */
-	    (( /* upack 0.39-2s */
-	     epbuff[0] == '\x60' && epbuff[1] == '\xe8' && cli_readint32(epbuff+2) == 0x9 /* pusha; call+9 */
-	     )
-	    ||
-	    ( /* upack 1.1/1.2, based on 2 samples */
-	     epbuff[0] == '\xbe' && cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase) < min &&  /* mov esi */
-	     cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > 0 &&
-	     epbuff[5] == '\xad' && epbuff[6] == '\x8b' && epbuff[7] == '\xf8' /* loads;  mov edi, eax */
-	     )
-	   ))
-	   ) { 
-	    uint32_t vma, off;
-	    int a,b,c;
-
-	    cli_dbgmsg("Upack characteristics found.\n");
-	    a = exe_sections[0].vsz;
-	    b = exe_sections[1].vsz;
-	    if (upack) {
-	        cli_dbgmsg("Upack: var set\n");
-		c = exe_sections[2].vsz;
-		ssize = exe_sections[0].ursz + exe_sections[0].uraw;
-		off = exe_sections[0].rva;
-		vma = EC32(optional_hdr32.ImageBase) + exe_sections[0].rva;
-	    } else {
-	        cli_dbgmsg("Upack: var NOT set\n");
-		c = exe_sections[1].rva;
-		ssize = exe_sections[1].uraw;
-		off = 0;
-		vma = exe_sections[1].rva - exe_sections[1].uraw;
-	    }
+        /* Upack 0.39 produces 2 types of executables
+         * 3 sections:           | 2 sections (one empty, I don't chech found if !upack, since it's in OR above):
+         *   mov esi, value      |   pusha
+         *   lodsd               |   call $+0x9
+         *   push eax            |
+         *
+         * Upack 1.1/1.2 Beta produces [based on 2 samples (sUx) provided by aCaB]:
+         * 2 sections
+         *   mov esi, value
+         *   loads
+         *   mov edi, eax
+         *
+         * Upack unknown [sample 0297729]
+         * 3 sections
+         *   mov esi, value
+         *   push [esi]
+         *   jmp
+         * 
+         */
+        /* upack 0.39-3s + sample 0151477*/
+        while(((upack && nsections == 3) && /* 3 sections */
+            ((
+             epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
+             epbuff[5] == '\xad' && epbuff[6] == '\x50' /* lodsd; push eax */
+             )
+            || 
+            /* based on 0297729 sample from aCaB */
+            (epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > min && /* mov esi */
+             epbuff[5] == '\xff' && epbuff[6] == '\x36' /* push [esi] */
+             )
+           )) 
+           ||
+           ((!upack && nsections == 2) && /* 2 sections */
+            (( /* upack 0.39-2s */
+             epbuff[0] == '\x60' && epbuff[1] == '\xe8' && cli_readint32(epbuff+2) == 0x9 /* pusha; call+9 */
+             )
+            ||
+            ( /* upack 1.1/1.2, based on 2 samples */
+             epbuff[0] == '\xbe' && cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase) < min &&  /* mov esi */
+             cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) > 0 &&
+             epbuff[5] == '\xad' && epbuff[6] == '\x8b' && epbuff[7] == '\xf8' /* loads;  mov edi, eax */
+             )
+           ))
+           ) { 
+            uint32_t vma, off;
+            int a,b,c;
+
+            cli_dbgmsg("Upack characteristics found.\n");
+            a = exe_sections[0].vsz;
+            b = exe_sections[1].vsz;
+            if (upack) {
+                cli_dbgmsg("Upack: var set\n");
+
+                c = exe_sections[2].vsz;
+                ssize = exe_sections[0].ursz + exe_sections[0].uraw;
+                off = exe_sections[0].rva;
+                vma = EC32(optional_hdr32.ImageBase) + exe_sections[0].rva;
+            } else {
+                cli_dbgmsg("Upack: var NOT set\n");
+                c = exe_sections[1].rva;
+                ssize = exe_sections[1].uraw;
+                off = 0;
+                vma = exe_sections[1].rva - exe_sections[1].uraw;
+            }
 
-	    dsize = a+b+c;
+            dsize = a+b+c;
 
-	    CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
+            CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
 
-	    if (!CLI_ISCONTAINED(0, dsize, exe_sections[1].rva - off, exe_sections[1].ursz) || (upack && !CLI_ISCONTAINED(0, dsize, exe_sections[2].rva - exe_sections[0].rva, ssize)) || ssize > dsize) {
-	        cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
-		break;
-	    }
-			
-	    if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
-	        free(exe_sections);
-		return CL_EMEM;
-	    }
+            if (!CLI_ISCONTAINED(0, dsize, exe_sections[1].rva - off, exe_sections[1].ursz) || (upack && !CLI_ISCONTAINED(0, dsize, exe_sections[2].rva - exe_sections[0].rva, ssize)) || ssize > dsize) {
+                cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
+                break;
+            }
+                
+            if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
+                free(exe_sections);
+                return CL_EMEM;
+            }
 
-	    if((unsigned int)fmap_readn(map, dest, 0, ssize) != ssize) {
-	        cli_dbgmsg("Upack: Can't read raw data of section 0\n");
-		free(dest);
-		break;
-	    }
+            if((unsigned int)fmap_readn(map, dest, 0, ssize) != ssize) {
+                cli_dbgmsg("Upack: Can't read raw data of section 0\n");
+                free(dest);
+                break;
+            }
 
-	    if(upack) memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize);
+            if(upack)
+                memmove(dest + exe_sections[2].rva - exe_sections[0].rva, dest, ssize);
 
-	    if((unsigned int)fmap_readn(map, dest + exe_sections[1].rva - off, exe_sections[1].uraw, exe_sections[1].ursz) != exe_sections[1].ursz) {
-		cli_dbgmsg("Upack: Can't read raw data of section 1\n");
-		free(dest);
-		break;
-	    }
+            if((unsigned int)fmap_readn(map, dest + exe_sections[1].rva - off, exe_sections[1].uraw, exe_sections[1].ursz) != exe_sections[1].ursz) {
+                cli_dbgmsg("Upack: Can't read raw data of section 1\n");
+                free(dest);
+                break;
+            }
 
 #if HAVE_JSON
-        cli_jsonstr(pe_json, "Packer", "Upack");
+            cli_jsonstr(pe_json, "Packer", "Upack");
 #endif
 
-	    CLI_UNPTEMP("Upack",(dest,exe_sections,0));
-	    CLI_UNPRESULTS("Upack",(unupack(upack, dest, dsize, epbuff, vma, ep, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, ndesc)),1,(dest,0));
-	    break;
-	}
-    }
+            CLI_UNPTEMP("Upack",(dest,exe_sections,0));
+            CLI_UNPRESULTS("Upack",(unupack(upack, dest, dsize, epbuff, vma, ep, EC32(optional_hdr32.ImageBase), exe_sections[0].rva, ndesc)),1,(dest,0));
 
+            break;
+        }
+    }
     
     while(found  && (DCONF & PE_CONF_FSG) && epbuff[0] == '\x87' && epbuff[1] == '\x25') {
-	const char *dst;
+        const char *dst;
+        uint32_t newesi, newedi, newebx, newedx;
 
-	/* FSG v2.0 support - thanks to aCaB ! */
+        /* FSG v2.0 support - thanks to aCaB ! */
+        
+        ssize = exe_sections[i + 1].rsz;
+        dsize = exe_sections[i].vsz;
 
-	uint32_t newesi, newedi, newebx, newedx;
-	
-	ssize = exe_sections[i + 1].rsz;
-	dsize = exe_sections[i].vsz;
+        CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
 
-	CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
+        if(ssize <= 0x19 || dsize <= ssize) {
+            cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
+            free(exe_sections);
+            return CL_CLEAN;
+        }
+        
+        newedx = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase);
+        if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
+            cli_dbgmsg("FSG: xchg out of bounds (%x), giving up\n", newedx);
+            break;
+        }
+        
+        if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
+            cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
+            free(exe_sections);
+            return CL_ESEEK;
+        }
 
-	if(ssize <= 0x19 || dsize <= ssize) {
-	    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
-	    free(exe_sections);
-	    return CL_CLEAN;
-	}
-	
-	newedx = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase);
-	if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
-	    cli_dbgmsg("FSG: xchg out of bounds (%x), giving up\n", newedx);
-	    break;
-	}
-	
-	if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
-	    cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
-	    free(exe_sections);
-	    return CL_ESEEK;
-	}
+        dst = src + newedx - exe_sections[i + 1].rva;
+        if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dst, 4)) {
+            cli_dbgmsg("FSG: New ESP out of bounds\n");
+            break;
+        }
 
-	dst = src + newedx - exe_sections[i + 1].rva;
-	if(newedx < exe_sections[i + 1].rva || !CLI_ISCONTAINED(src, ssize, dst, 4)) {
-	    cli_dbgmsg("FSG: New ESP out of bounds\n");
-	    break;
-	}
+        newedx = cli_readint32(dst) - EC32(optional_hdr32.ImageBase);
+        if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
+            cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
+            break;
+        }
+     
+        dst = src + newedx - exe_sections[i + 1].rva;
+        if(!CLI_ISCONTAINED(src, ssize, dst, 32)) {
+            cli_dbgmsg("FSG: New stack out of bounds\n");
+            break;
+        }
 
-	newedx = cli_readint32(dst) - EC32(optional_hdr32.ImageBase);
-	if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newedx, 4)) {
-	    cli_dbgmsg("FSG: New ESP (%x) is wrong\n", newedx);
-	    break;
-	}
- 
-	dst = src + newedx - exe_sections[i + 1].rva;
-	if(!CLI_ISCONTAINED(src, ssize, dst, 32)) {
-	    cli_dbgmsg("FSG: New stack out of bounds\n");
-	    break;
-	}
+        newedi = cli_readint32(dst) - EC32(optional_hdr32.ImageBase);
+        newesi = cli_readint32(dst + 4) - EC32(optional_hdr32.ImageBase);
+        newebx = cli_readint32(dst + 16) - EC32(optional_hdr32.ImageBase);
+        newedx = cli_readint32(dst + 20);
 
-	newedi = cli_readint32(dst) - EC32(optional_hdr32.ImageBase);
-	newesi = cli_readint32(dst + 4) - EC32(optional_hdr32.ImageBase);
-	newebx = cli_readint32(dst + 16) - EC32(optional_hdr32.ImageBase);
-	newedx = cli_readint32(dst + 20);
-
-	if(newedi != exe_sections[i].rva) {
-	    cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
-	    break;
-	}
+        if(newedi != exe_sections[i].rva) {
+            cli_dbgmsg("FSG: Bad destination buffer (edi is %x should be %x)\n", newedi, exe_sections[i].rva);
+            break;
+        }
 
-	if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
-	    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
-	    break;
-	}
+        if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
+            cli_dbgmsg("FSG: Source buffer out of section bounds\n");
+            break;
+        }
 
-	if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
-	    cli_dbgmsg("FSG: Array of functions out of bounds\n");
-	    break;
-	}
+        if(!CLI_ISCONTAINED(exe_sections[i + 1].rva, exe_sections[i + 1].rsz, newebx, 16)) {
+            cli_dbgmsg("FSG: Array of functions out of bounds\n");
+            break;
+        }
 
-	newedx=cli_readint32(newebx + 12 - exe_sections[i + 1].rva + src) - EC32(optional_hdr32.ImageBase);
-	cli_dbgmsg("FSG: found old EP @%x\n",newedx);
+        newedx=cli_readint32(newebx + 12 - exe_sections[i + 1].rva + src) - EC32(optional_hdr32.ImageBase);
+        cli_dbgmsg("FSG: found old EP @%x\n",newedx);
 
-	if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
+        if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
+            free(exe_sections);
+            return CL_EMEM;
+        }
 
 #if HAVE_JSON
-    cli_jsonstr(pe_json, "Packer", "FSG");
+        cli_jsonstr(pe_json, "Packer", "FSG");
 #endif
 
-	CLI_UNPTEMP("FSG",(dest,exe_sections,0));
-	CLI_UNPRESULTSFSG2("FSG",(unfsg_200(newesi - exe_sections[i + 1].rva + src, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, newedi, EC32(optional_hdr32.ImageBase), newedx, ndesc)),1,(dest,0));
-	break;
+        CLI_UNPTEMP("FSG",(dest,exe_sections,0));
+        CLI_UNPRESULTSFSG2("FSG",(unfsg_200(newesi - exe_sections[i + 1].rva + src, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, newedi, EC32(optional_hdr32.ImageBase), newedx, ndesc)),1,(dest,0));
+        break;
     }
 
 
     while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\xbe' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) < min) {
+        int sectcnt = 0;
+        const char *support;
+        uint32_t newesi, newedi, oldep, gp, t;
+        struct cli_exe_section *sections;
 
-	/* FSG support - v. 1.33 (thx trog for the many samples) */
+        /* FSG support - v. 1.33 (thx trog for the many samples) */
 
-	int sectcnt = 0;
-	const char *support;
-	uint32_t newesi, newedi, oldep, gp, t;
-	struct cli_exe_section *sections;
-
-	ssize = exe_sections[i + 1].rsz;
-	dsize = exe_sections[i].vsz;
-
-	CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
-
-	if(ssize <= 0x19 || dsize <= ssize) {
-	    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
-	    free(exe_sections);
-	    return CL_CLEAN;
-	}
+        ssize = exe_sections[i + 1].rsz;
+        dsize = exe_sections[i].vsz;
 
-	if(!(t = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
-	    cli_dbgmsg("FSG: Support data out of padding area\n");
-	    break;
-	}
+        CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
 
-	gp = exe_sections[i + 1].raw - t;
+        if(ssize <= 0x19 || dsize <= ssize) {
+            cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
+            free(exe_sections);
+            return CL_CLEAN;
+        }
 
-	CLI_UNPSIZELIMITS("FSG", gp);
+        if(!(t = cli_rawaddr(cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size)) && err ) {
+            cli_dbgmsg("FSG: Support data out of padding area\n");
+            break;
+        }
 
-	if(!(support = fmap_need_off_once(map, t, gp))) {
-	    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
-	    free(exe_sections);
-	    return CL_EREAD;
-	}
+        gp = exe_sections[i + 1].raw - t;
 
-	/* newebx = cli_readint32(support) - EC32(optional_hdr32.ImageBase);  Unused */
-	newedi = cli_readint32(support + 4) - EC32(optional_hdr32.ImageBase); /* 1st dest */
-	newesi = cli_readint32(support + 8) - EC32(optional_hdr32.ImageBase); /* Source */
-
-	if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
-	    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
-	    break;
-	}
+        CLI_UNPSIZELIMITS("FSG", gp);
 
-	if(newedi != exe_sections[i].rva) {
-	    cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
-	    break;
-	}
+        if(!(support = fmap_need_off_once(map, t, gp))) {
+            cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
+            free(exe_sections);
+            return CL_EREAD;
+        }
 
-	/* Counting original sections */
-	for(t = 12; t < gp - 4; t += 4) {
-	    uint32_t rva = cli_readint32(support+t);
+        /* newebx = cli_readint32(support) - EC32(optional_hdr32.ImageBase);  Unused */
+        newedi = cli_readint32(support + 4) - EC32(optional_hdr32.ImageBase); /* 1st dest */
+        newesi = cli_readint32(support + 8) - EC32(optional_hdr32.ImageBase); /* Source */
 
-	    if(!rva)
-		break;
+        if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].rsz) {
+            cli_dbgmsg("FSG: Source buffer out of section bounds\n");
+            break;
+        }
 
-	    rva -= EC32(optional_hdr32.ImageBase)+1;
-	    sectcnt++;
+        if(newedi != exe_sections[i].rva) {
+            cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
+            break;
+        }
 
-	    if(rva % 0x1000) cli_dbgmsg("FSG: Original section %d is misaligned\n", sectcnt);
+        /* Counting original sections */
+        for(t = 12; t < gp - 4; t += 4) {
+            uint32_t rva = cli_readint32(support+t);
 
-	    if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
-		cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
-		break;
-	    }
-	}
+            if(!rva)
+                break;
 
-	if(t >= gp - 4 || cli_readint32(support + t)) {
-	    break;
-	}
+            rva -= EC32(optional_hdr32.ImageBase)+1;
+            sectcnt++;
 
-	if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
-        cli_errmsg("FSG: Unable to allocate memory for sections %lu\n", (sectcnt + 1) * sizeof(struct cli_exe_section));
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
+            if(rva % 0x1000)
+                cli_dbgmsg("FSG: Original section %d is misaligned\n", sectcnt);
 
-	sections[0].rva = newedi;
-	for(t = 1; t <= (uint32_t)sectcnt; t++)
-	    sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
-
-	if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
-	    cli_dbgmsg("Can't read raw data of section %d\n", i);
-	    free(exe_sections);
-	    free(sections);
-	    return CL_EREAD;
-	}
+            if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
+                cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
+                break;
+            }
+        }
 
-	if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
-	    free(exe_sections);
-	    free(sections);
-	    return CL_EMEM;
-	}
+        if(t >= gp - 4 || cli_readint32(support + t)) {
+            break;
+        }
+
+        if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
+            cli_errmsg("FSG: Unable to allocate memory for sections %lu\n", (sectcnt + 1) * sizeof(struct cli_exe_section));
+            free(exe_sections);
+            return CL_EMEM;
+        }
+
+        sections[0].rva = newedi;
+        for(t = 1; t <= (uint32_t)sectcnt; t++)
+            sections[t].rva = cli_readint32(support + 8 + t * 4) - 1 - EC32(optional_hdr32.ImageBase);
+
+        if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
+            cli_dbgmsg("Can't read raw data of section %d\n", i);
+            free(exe_sections);
+            free(sections);
+            return CL_EREAD;
+        }
+
+        if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
+            free(exe_sections);
+            free(sections);
+            return CL_EMEM;
+        }
 
-	oldep = vep + 161 + 6 + cli_readint32(epbuff+163);
-	cli_dbgmsg("FSG: found old EP @%x\n", oldep);
+        oldep = vep + 161 + 6 + cli_readint32(epbuff+163);
+        cli_dbgmsg("FSG: found old EP @%x\n", oldep);
 
 #if HAVE_JSON
-    cli_jsonstr(pe_json, "Packer", "FSG");
+        cli_jsonstr(pe_json, "Packer", "FSG");
 #endif
 
-	CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
-	CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,(dest,sections,0));
-	break; /* were done with 1.33 */
+        CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
+        CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,(dest,sections,0));
+        break; /* were done with 1.33 */
     }
 
-
     while(found && (DCONF & PE_CONF_FSG) && epbuff[0] == '\xbb' && cli_readint32(epbuff + 1) - EC32(optional_hdr32.ImageBase) < min && epbuff[5] == '\xbf' && epbuff[10] == '\xbe' && vep >= exe_sections[i + 1].rva && vep - exe_sections[i + 1].rva > exe_sections[i + 1].rva - 0xe0 ) {
+        int sectcnt = 0;
+        uint32_t gp, t = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
+        const char *support;
+        uint32_t newesi = cli_readint32(epbuff+11) - EC32(optional_hdr32.ImageBase);
+        uint32_t newedi = cli_readint32(epbuff+6) - EC32(optional_hdr32.ImageBase);
+        uint32_t oldep = vep - exe_sections[i + 1].rva;
+        struct cli_exe_section *sections;
 
-	/* FSG support - v. 1.31 */
+        /* FSG support - v. 1.31 */
 
-	int sectcnt = 0;
-	uint32_t gp, t = cli_rawaddr(cli_readint32(epbuff+1) - EC32(optional_hdr32.ImageBase), NULL, 0 , &err, fsize, hdr_size);
-	const char *support;
-	uint32_t newesi = cli_readint32(epbuff+11) - EC32(optional_hdr32.ImageBase);
-	uint32_t newedi = cli_readint32(epbuff+6) - EC32(optional_hdr32.ImageBase);
-	uint32_t oldep = vep - exe_sections[i + 1].rva;
-	struct cli_exe_section *sections;
-
-	ssize = exe_sections[i + 1].rsz;
-	dsize = exe_sections[i].vsz;
-
-	if(err) {
-	    cli_dbgmsg("FSG: Support data out of padding area\n");
-	    break;
-	}
+        ssize = exe_sections[i + 1].rsz;
+        dsize = exe_sections[i].vsz;
 
-	if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].raw) {
-	    cli_dbgmsg("FSG: Source buffer out of section bounds\n");
-	    break;
-	}
+        if(err) {
+            cli_dbgmsg("FSG: Support data out of padding area\n");
+            break;
+        }
 
-	if(newedi != exe_sections[i].rva) {
-	    cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
-	    break;
-	}
+        if(newesi < exe_sections[i + 1].rva || newesi - exe_sections[i + 1].rva >= exe_sections[i + 1].raw) {
+            cli_dbgmsg("FSG: Source buffer out of section bounds\n");
+            break;
+        }
 
-	CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
+        if(newedi != exe_sections[i].rva) {
+            cli_dbgmsg("FSG: Bad destination (is %x should be %x)\n", newedi, exe_sections[i].rva);
+            break;
+        }
 
-	if(ssize <= 0x19 || dsize <= ssize) {
-	    cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
-	    free(exe_sections);
-	    return CL_CLEAN;
-	}
+        CLI_UNPSIZELIMITS("FSG", MAX(dsize, ssize));
 
-	gp = exe_sections[i + 1].raw - t;
+        if(ssize <= 0x19 || dsize <= ssize) {
+            cli_dbgmsg("FSG: Size mismatch (ssize: %d, dsize: %d)\n", ssize, dsize);
+            free(exe_sections);
+            return CL_CLEAN;
+        }
 
-	CLI_UNPSIZELIMITS("FSG", gp)
+        gp = exe_sections[i + 1].raw - t;
 
-	if(!(support = fmap_need_off_once(map, t, gp))) {
-	    cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
-	    free(exe_sections);
-	    return CL_EREAD;
-	}
+        CLI_UNPSIZELIMITS("FSG", gp)
 
-	/* Counting original sections */
-	for(t = 0; t < gp - 2; t += 2) {
-	    uint32_t rva = support[t]|(support[t+1]<<8);
-
-	    if (rva == 2 || rva == 1)
-		break;
-
-	    rva = ((rva-2)<<12) - EC32(optional_hdr32.ImageBase);
-	    sectcnt++;
-
-	    if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
-		cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
-		break;
-	    }
-	}
+        if(!(support = fmap_need_off_once(map, t, gp))) {
+            cli_dbgmsg("Can't read %d bytes from padding area\n", gp); 
+            free(exe_sections);
+            return CL_EREAD;
+        }
 
-	if(t >= gp-10 || cli_readint32(support + t + 6) != 2) {
-	    break;
-	}
+        /* Counting original sections */
+        for(t = 0; t < gp - 2; t += 2) {
+            uint32_t rva = support[t]|(support[t+1]<<8);
 
-	if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
-        cli_errmsg("FSG: Unable to allocate memory for sections %lu\n", (sectcnt + 1) * sizeof(struct cli_exe_section));
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
+            if (rva == 2 || rva == 1)
+                break;
 
-	sections[0].rva = newedi;
-	for(t = 0; t <= (uint32_t)sectcnt - 1; t++) {
-	    sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
-	}
+            rva = ((rva-2)<<12) - EC32(optional_hdr32.ImageBase);
+            sectcnt++;
 
-	if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
-	    cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
-	    free(exe_sections);
-	    free(sections);
-	    return CL_EREAD;
-	}
+            if(rva < exe_sections[i].rva || rva - exe_sections[i].rva >= exe_sections[i].vsz) {
+                cli_dbgmsg("FSG: Original section %d is out of bounds\n", sectcnt);
+                break;
+            }
+        }
 
-	if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
-	    free(exe_sections);
-	    free(sections);
-	    return CL_EMEM;
-	}
+        if(t >= gp-10 || cli_readint32(support + t + 6) != 2)
+            break;
+
+        if((sections = (struct cli_exe_section *) cli_malloc((sectcnt + 1) * sizeof(struct cli_exe_section))) == NULL) {
+            cli_errmsg("FSG: Unable to allocate memory for sections %lu\n", (sectcnt + 1) * sizeof(struct cli_exe_section));
+            free(exe_sections);
+            return CL_EMEM;
+        }
+
+        sections[0].rva = newedi;
+        for(t = 0; t <= (uint32_t)sectcnt - 1; t++)
+            sections[t+1].rva = (((support[t*2]|(support[t*2+1]<<8))-2)<<12)-EC32(optional_hdr32.ImageBase);
+
+        if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
+            cli_dbgmsg("FSG: Can't read raw data of section %d\n", i);
+            free(exe_sections);
+            free(sections);
+            return CL_EREAD;
+        }
+
+        if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
+            free(exe_sections);
+            free(sections);
+            return CL_EMEM;
+        }
 
-	gp = 0xda + 6*(epbuff[16]=='\xe8');
-	oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
-	cli_dbgmsg("FSG: found old EP @%x\n", oldep);
+        gp = 0xda + 6*(epbuff[16]=='\xe8');
+        oldep = vep + gp + 6 + cli_readint32(src+gp+2+oldep);
+        cli_dbgmsg("FSG: found old EP @%x\n", oldep);
 
 #if HAVE_JSON
-    cli_jsonstr(pe_json, "Packer", "FSG");
+        cli_jsonstr(pe_json, "Packer", "FSG");
 #endif
 
-	CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
-	CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,(dest,sections,0));
-	break; /* were done with 1.31 */
+        CLI_UNPTEMP("FSG",(dest,sections,exe_sections,0));
+        CLI_UNPRESULTSFSG1("FSG",(unfsg_133(src + newesi - exe_sections[i + 1].rva, dest, ssize + exe_sections[i + 1].rva - newesi, dsize, sections, sectcnt, EC32(optional_hdr32.ImageBase), oldep, ndesc)),1,(dest,sections,0));
+
+        break; /* were done with 1.31 */
     }
 
 
     if(found && (DCONF & PE_CONF_UPX)) {
+        ssize = exe_sections[i + 1].rsz;
+        dsize = exe_sections[i].vsz + exe_sections[i + 1].vsz;
 
-	/* UPX support */
+        /* 
+         * UPX support
+         * we assume (i + 1) is UPX1
+         */
 
-	/* we assume (i + 1) is UPX1 */
-	ssize = exe_sections[i + 1].rsz;
-	dsize = exe_sections[i].vsz + exe_sections[i + 1].vsz;
+            /* cli_dbgmsg("UPX: ssize %u dsize %u\n", ssize, dsize); */
 
-        /* cli_dbgmsg("UPX: ssize %u dsize %u\n", ssize, dsize); */
+        CLI_UNPSIZELIMITS("UPX", MAX(dsize, ssize));
 
-	CLI_UNPSIZELIMITS("UPX", MAX(dsize, ssize));
+        if(ssize <= 0x19 || dsize <= ssize || dsize > CLI_MAX_ALLOCATION ) {
+            cli_dbgmsg("UPX: Size mismatch or dsize too big (ssize: %d, dsize: %d)\n", ssize, dsize);
+            free(exe_sections);
+            return CL_CLEAN;
+        }
 
-	if(ssize <= 0x19 || dsize <= ssize || dsize > CLI_MAX_ALLOCATION ) {
-	    cli_dbgmsg("UPX: Size mismatch or dsize too big (ssize: %d, dsize: %d)\n", ssize, dsize);
-	    free(exe_sections);
-	    return CL_CLEAN;
-	}
+        if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
+            cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
+            free(exe_sections);
+            return CL_EREAD;
+        }
 
-	if(!exe_sections[i + 1].rsz || !(src = fmap_need_off_once(map, exe_sections[i + 1].raw, ssize))) {
-	    cli_dbgmsg("UPX: Can't read raw data of section %d\n", i+1);
-	    free(exe_sections);
-	    return CL_EREAD;
-	}
+        if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
+            free(exe_sections);
+            return CL_EMEM;
+        }
 
-	if((dest = (char *) cli_calloc(dsize + 8192, sizeof(char))) == NULL) {
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
+        /* try to detect UPX code */
+        if(cli_memstr(UPX_NRV2B, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, epbuff + 0x69 + 8, 13)) {
+            cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
+            upxfn = upx_inflate2b;
+        } else if(cli_memstr(UPX_NRV2D, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2D, 24, epbuff + 0x69 + 8, 13)) {
+            cli_dbgmsg("UPX: Looks like a NRV2D decompression routine\n");
+            upxfn = upx_inflate2d;
+        } else if(cli_memstr(UPX_NRV2E, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2E, 24, epbuff + 0x69 + 8, 13)) {
+            cli_dbgmsg("UPX: Looks like a NRV2E decompression routine\n");
+            upxfn = upx_inflate2e;
+        }
 
-	/* try to detect UPX code */
-	if(cli_memstr(UPX_NRV2B, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2B, 24, epbuff + 0x69 + 8, 13)) {
-	    cli_dbgmsg("UPX: Looks like a NRV2B decompression routine\n");
-	    upxfn = upx_inflate2b;
-	} else if(cli_memstr(UPX_NRV2D, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2D, 24, epbuff + 0x69 + 8, 13)) {
-	    cli_dbgmsg("UPX: Looks like a NRV2D decompression routine\n");
-	    upxfn = upx_inflate2d;
-	} else if(cli_memstr(UPX_NRV2E, 24, epbuff + 0x69, 13) || cli_memstr(UPX_NRV2E, 24, epbuff + 0x69 + 8, 13)) {
-	    cli_dbgmsg("UPX: Looks like a NRV2E decompression routine\n");
-	    upxfn = upx_inflate2e;
-	}
+        if(upxfn) {
+            int skew = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase) - exe_sections[i + 1].rva;
 
-	if(upxfn) {
-	    int skew = cli_readint32(epbuff + 2) - EC32(optional_hdr32.ImageBase) - exe_sections[i + 1].rva;
+            if(epbuff[1] != '\xbe' || skew <= 0 || skew > 0xfff) {
+                /* FIXME: legit skews?? */
+                skew = 0; 
+            } else if ((unsigned int)skew > ssize) {
+                /* Ignore suggested skew larger than section size */
+                skew = 0;
+            } else {
+                cli_dbgmsg("UPX: UPX1 seems skewed by %d bytes\n", skew);
+            }
 
-	    if(epbuff[1] != '\xbe' || skew <= 0 || skew > 0xfff) { /* FIXME: legit skews?? */
-		skew = 0; 
-	    } else if ((unsigned int)skew > ssize) {
-		/* Ignore suggested skew larger than section size */
-		skew = 0;
-	    } else {
-		cli_dbgmsg("UPX: UPX1 seems skewed by %d bytes\n", skew);
-	    }
+            /* Try skewed first (skew may be zero) */
+            if(upxfn(src + skew, ssize - skew, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep-skew) >= 0) {
+                upx_success = 1;
+            }
+            /* If skew not successful and non-zero, try no skew */
+            else if(skew && (upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)) {
+                upx_success = 1;
+            }
 
-	    /* Try skewed first (skew may be zero) */
-	    if(upxfn(src + skew, ssize - skew, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep-skew) >= 0) {
-		upx_success = 1;
-	    }
-	    /* If skew not successful and non-zero, try no skew */
-	    else if(skew && (upxfn(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >= 0)) {
-		upx_success = 1;
-	    }
+            if(upx_success)
+                cli_dbgmsg("UPX: Successfully decompressed\n");
+            else
+                cli_dbgmsg("UPX: Preferred decompressor failed\n");
+        }
 
-	    if(upx_success)
-		cli_dbgmsg("UPX: Successfully decompressed\n");
-	    else
-		cli_dbgmsg("UPX: Preferred decompressor failed\n");
-	}
+        if(!upx_success && upxfn != upx_inflate2b) {
+            if(upx_inflate2b(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2b(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
 
-	if(!upx_success && upxfn != upx_inflate2b) {
-	    if(upx_inflate2b(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2b(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
+                cli_dbgmsg("UPX: NRV2B decompressor failed\n");
+            } else {
+                upx_success = 1;
+                cli_dbgmsg("UPX: Successfully decompressed with NRV2B\n");
+            }
+        }
 
-		cli_dbgmsg("UPX: NRV2B decompressor failed\n");
-	    } else {
-		upx_success = 1;
-		cli_dbgmsg("UPX: Successfully decompressed with NRV2B\n");
-	    }
-	}
+        if(!upx_success && upxfn != upx_inflate2d) {
+            if(upx_inflate2d(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2d(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
 
-	if(!upx_success && upxfn != upx_inflate2d) {
-	    if(upx_inflate2d(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2d(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
+                cli_dbgmsg("UPX: NRV2D decompressor failed\n");
+            } else {
+                upx_success = 1;
+                cli_dbgmsg("UPX: Successfully decompressed with NRV2D\n");
+            }
+        }
 
-		cli_dbgmsg("UPX: NRV2D decompressor failed\n");
-	    } else {
-		upx_success = 1;
-		cli_dbgmsg("UPX: Successfully decompressed with NRV2D\n");
-	    }
-	}
+        if(!upx_success && upxfn != upx_inflate2e) {
+            if(upx_inflate2e(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2e(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
+                cli_dbgmsg("UPX: NRV2E decompressor failed\n");
+            } else {
+                upx_success = 1;
+                cli_dbgmsg("UPX: Successfully decompressed with NRV2E\n");
+            }
+        }
 
-	if(!upx_success && upxfn != upx_inflate2e) {
-	    if(upx_inflate2e(src, ssize, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) == -1 && upx_inflate2e(src + 0x15, ssize - 0x15, dest, &dsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep - 0x15) == -1) {
-		cli_dbgmsg("UPX: NRV2E decompressor failed\n");
-	    } else {
-		upx_success = 1;
-		cli_dbgmsg("UPX: Successfully decompressed with NRV2E\n");
-	    }
-	}
+        if(cli_memstr(UPX_LZMA2, 20, epbuff + 0x2f, 20)) {
+            uint32_t strictdsize=cli_readint32(epbuff+0x21), skew = 0;
+            if(ssize > 0x15 && epbuff[0] == '\x60' && epbuff[1] == '\xbe') {
+                skew = cli_readint32(epbuff+2) - exe_sections[i + 1].rva - optional_hdr32.ImageBase;
+                if(skew!=0x15)
+                    skew = 0;
+            }
 
-	if(cli_memstr(UPX_LZMA2, 20, epbuff + 0x2f, 20)) {
-	    uint32_t strictdsize=cli_readint32(epbuff+0x21), skew = 0;
-	    if(ssize > 0x15 && epbuff[0] == '\x60' && epbuff[1] == '\xbe') {
-		skew = cli_readint32(epbuff+2) - exe_sections[i + 1].rva - optional_hdr32.ImageBase;
-		if(skew!=0x15) skew = 0;
-	    }
-	    if(strictdsize<=dsize)
-		upx_success = upx_inflatelzma(src+skew, ssize-skew, dest, &strictdsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >=0;
-	} else if (cli_memstr(UPX_LZMA1, 20, epbuff + 0x39, 20)) {
-	    uint32_t strictdsize=cli_readint32(epbuff+0x2b), skew = 0;
-	    if(ssize > 0x15 && epbuff[0] == '\x60' && epbuff[1] == '\xbe') {
-		skew = cli_readint32(epbuff+2) - exe_sections[i + 1].rva - optional_hdr32.ImageBase;
-		if(skew!=0x15) skew = 0;
-	    }
-	    if(strictdsize<=dsize)
-		upx_success = upx_inflatelzma(src+skew, ssize-skew, dest, &strictdsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >=0;
-	}
+            if(strictdsize<=dsize)
+                upx_success = upx_inflatelzma(src+skew, ssize-skew, dest, &strictdsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >=0;
+        } else if (cli_memstr(UPX_LZMA1, 20, epbuff + 0x39, 20)) {
+            uint32_t strictdsize=cli_readint32(epbuff+0x2b), skew = 0;
+            if(ssize > 0x15 && epbuff[0] == '\x60' && epbuff[1] == '\xbe') {
+                skew = cli_readint32(epbuff+2) - exe_sections[i + 1].rva - optional_hdr32.ImageBase;
+                if(skew!=0x15)
+                    skew = 0;
+            }
 
-	if(!upx_success) {
-	    cli_dbgmsg("UPX: All decompressors failed\n");
-	    free(dest);
-	}
+            if(strictdsize<=dsize)
+                upx_success = upx_inflatelzma(src+skew, ssize-skew, dest, &strictdsize, exe_sections[i].rva, exe_sections[i + 1].rva, vep) >=0;
+        }
+
+        if(!upx_success) {
+            cli_dbgmsg("UPX: All decompressors failed\n");
+            free(dest);
+        }
     }
 
     if(upx_success) {
-	free(exe_sections);
+        free(exe_sections);
 
-	CLI_UNPTEMP("UPX/FSG",(dest,0));
+        CLI_UNPTEMP("UPX/FSG",(dest,0));
 #if HAVE_JSON
-    cli_jsonstr(pe_json, "Packer", "UPX");
+        cli_jsonstr(pe_json, "Packer", "UPX");
 #endif
 
-	if((unsigned int) write(ndesc, dest, dsize) != dsize) {
-	    cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
-	    free(tempfile);
-	    free(dest);
-	    close(ndesc);
-	    return CL_EWRITE;
-	}
+        if((unsigned int) write(ndesc, dest, dsize) != dsize) {
+            cli_dbgmsg("UPX/FSG: Can't write %d bytes\n", dsize);
+            free(tempfile);
+            free(dest);
+            close(ndesc);
+            return CL_EWRITE;
+        }
 
-	free(dest);
-	if (lseek(ndesc, 0, SEEK_SET) == -1) {
-        cli_dbgmsg("UPX/FSG: lseek() failed\n");
-        close(ndesc);
-        CLI_TMPUNLK();
-        free(tempfile);
-        SHA_RESET;
-        return CL_ESEEK;
-    }
+        free(dest);
+        if (lseek(ndesc, 0, SEEK_SET) == -1) {
+            cli_dbgmsg("UPX/FSG: lseek() failed\n");
+            close(ndesc);
+            CLI_TMPUNLK();
+            free(tempfile);
+            SHA_RESET;
+            return CL_ESEEK;
+        }
 
-	if(ctx->engine->keeptmp)
-	    cli_dbgmsg("UPX/FSG: Decompressed data saved in %s\n", tempfile);
+        if(ctx->engine->keeptmp)
+            cli_dbgmsg("UPX/FSG: Decompressed data saved in %s\n", tempfile);
 
-	cli_dbgmsg("***** Scanning decompressed file *****\n");
-	SHA_OFF;
-	if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) {
-	    close(ndesc);
-	    CLI_TMPUNLK();
-	    free(tempfile);
-	    SHA_RESET;
-	    return CL_VIRUS;
-	}
+        cli_dbgmsg("***** Scanning decompressed file *****\n");
+        SHA_OFF;
+        if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS) {
+            close(ndesc);
+            CLI_TMPUNLK();
+            free(tempfile);
+            SHA_RESET;
+            return CL_VIRUS;
+        }
 
-	SHA_RESET;
-	close(ndesc);
-	CLI_TMPUNLK();
-	free(tempfile);
-	return ret;
+        SHA_RESET;
+        close(ndesc);
+        CLI_TMPUNLK();
+        free(tempfile);
+        return ret;
     }
 
 
     /* Petite */
 
     if(epsize<200) {
-	free(exe_sections);
-	return CL_CLEAN;
+        free(exe_sections);
+        return CL_CLEAN;
     }
 
     found = 2;
 
     if(epbuff[0] != '\xb8' || (uint32_t) cli_readint32(epbuff + 1) != exe_sections[nsections - 1].rva + EC32(optional_hdr32.ImageBase)) {
-	if(nsections < 2 || epbuff[0] != '\xb8' || (uint32_t) cli_readint32(epbuff + 1) != exe_sections[nsections - 2].rva + EC32(optional_hdr32.ImageBase))
-	    found = 0;
-	else
-	    found = 1;
+        if(nsections < 2 || epbuff[0] != '\xb8' || (uint32_t) cli_readint32(epbuff + 1) != exe_sections[nsections - 2].rva + EC32(optional_hdr32.ImageBase))
+            found = 0;
+        else
+            found = 1;
     }
 
     if(found && (DCONF & PE_CONF_PETITE)) {
-	cli_dbgmsg("Petite: v2.%d compression detected\n", found);
+        cli_dbgmsg("Petite: v2.%d compression detected\n", found);
 
-	if(cli_readint32(epbuff + 0x80) == 0x163c988d) {
-	    cli_dbgmsg("Petite: level zero compression is not supported yet\n");
-	} else {
-	    dsize = max - min;
-
-	    CLI_UNPSIZELIMITS("Petite", dsize);
-
-	    if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
-		cli_dbgmsg("Petite: Can't allocate %d bytes\n", dsize);
-		free(exe_sections);
-		return CL_EMEM;
-	    }
+        if(cli_readint32(epbuff + 0x80) == 0x163c988d) {
+            cli_dbgmsg("Petite: level zero compression is not supported yet\n");
+        } else {
+            dsize = max - min;
 
-	    for(i = 0 ; i < nsections; i++) {
-		if(exe_sections[i].raw) {
-		    if(!exe_sections[i].rsz || (unsigned int)fmap_readn(map, dest + exe_sections[i].rva - min, exe_sections[i].raw, exe_sections[i].ursz) != exe_sections[i].ursz) {
-			free(exe_sections);
-			free(dest);
-			return CL_CLEAN;
-		    }
-		}
-	    }
+            CLI_UNPSIZELIMITS("Petite", dsize);
+
+            if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
+                cli_dbgmsg("Petite: Can't allocate %d bytes\n", dsize);
+                free(exe_sections);
+                return CL_EMEM;
+            }
+
+            for(i = 0 ; i < nsections; i++) {
+                if(exe_sections[i].raw) {
+                    if(!exe_sections[i].rsz || (unsigned int)fmap_readn(map, dest + exe_sections[i].rva - min, exe_sections[i].raw, exe_sections[i].ursz) != exe_sections[i].ursz) {
+                        free(exe_sections);
+                        free(dest);
+                        return CL_CLEAN;
+                    }
+                }
+            }
 
 #if HAVE_JSON
-        cli_jsonstr(pe_json, "Packer", "Petite");
+            cli_jsonstr(pe_json, "Packer", "Petite");
 #endif
 
-	    CLI_UNPTEMP("Petite",(dest,exe_sections,0));
-	    CLI_UNPRESULTS("Petite",(petite_inflate2x_1to9(dest, min, max - min, exe_sections, nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase),vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress),EC32(optional_hdr32.DataDirectory[2].Size))),0,(dest,0));
-	}
+            CLI_UNPTEMP("Petite",(dest,exe_sections,0));
+            CLI_UNPRESULTS("Petite",(petite_inflate2x_1to9(dest, min, max - min, exe_sections, nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase),vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress),EC32(optional_hdr32.DataDirectory[2].Size))),0,(dest,0));
+        }
     }
 
     /* PESpin 1.1 */
@@ -2424,29 +2481,29 @@
        vep < exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz - 0x3217 - 4 &&
        memcmp(epbuff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0)  {
 
-	char *spinned;
+        char *spinned;
 
-	CLI_UNPSIZELIMITS("PEspin", fsize);
+        CLI_UNPSIZELIMITS("PEspin", fsize);
 
-	if((spinned = (char *) cli_malloc(fsize)) == NULL) {
-        cli_errmsg("PESping: Unable to allocate memory for spinned %lu\n", (unsigned long)fsize);
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
+        if((spinned = (char *) cli_malloc(fsize)) == NULL) {
+            cli_errmsg("PESping: Unable to allocate memory for spinned %lu\n", (unsigned long)fsize);
+            free(exe_sections);
+            return CL_EMEM;
+        }
 
-	if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
-	    cli_dbgmsg("PESpin: Can't read %lu bytes\n", (unsigned long)fsize);
-	    free(spinned);
-	    free(exe_sections);
-	    return CL_EREAD;
-	}
+        if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
+            cli_dbgmsg("PESpin: Can't read %lu bytes\n", (unsigned long)fsize);
+            free(spinned);
+            free(exe_sections);
+            return CL_EREAD;
+        }
 
 #if HAVE_JSON
-    cli_jsonstr(pe_json, "Packer", "PEspin");
+        cli_jsonstr(pe_json, "Packer", "PEspin");
 #endif
 
-	CLI_UNPTEMP("PESpin",(spinned,exe_sections,0));
-	CLI_UNPRESULTS_("PEspin",SPINCASE(),(unspin(spinned, fsize, exe_sections, nsections - 1, vep, ndesc, ctx)),0,(spinned,0));
+        CLI_UNPTEMP("PESpin",(spinned,exe_sections,0));
+        CLI_UNPRESULTS_("PEspin",SPINCASE(),(unspin(spinned, fsize, exe_sections, nsections - 1, vep, ndesc, ctx)),0,(spinned,0));
     }
 
 
@@ -2454,69 +2511,69 @@
     if((DCONF & PE_CONF_YC) && nsections > 1 &&
        (EC32(optional_hdr32.AddressOfEntryPoint) == exe_sections[nsections - 1].rva + 0x60)) {
 
-	uint32_t ecx = 0;
-	int16_t offset;
+        uint32_t ecx = 0;
+        int16_t offset;
 
-	/* yC 1.3 */
-	if (!memcmp(epbuff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED", 15) &&
-	    !memcmp(epbuff+0x26, "\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 13) &&
-	    ((uint8_t)epbuff[0x13] == 0xB9) &&
-	    ((uint16_t)(cli_readint16(epbuff+0x18)) == 0xE981) &&
-	    !memcmp(epbuff+0x1e,"\x8B\xD5\x81\xC2", 4)) {
-
-	    offset = 0;
-	    if (0x6c - cli_readint32(epbuff+0xf) + cli_readint32(epbuff+0x22) == 0xC6)
-		ecx = cli_readint32(epbuff+0x14) - cli_readint32(epbuff+0x1a);
-	}
+        /* yC 1.3 */
+        if (!memcmp(epbuff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED", 15) &&
+            !memcmp(epbuff+0x26, "\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 13) &&
+            ((uint8_t)epbuff[0x13] == 0xB9) &&
+            ((uint16_t)(cli_readint16(epbuff+0x18)) == 0xE981) &&
+            !memcmp(epbuff+0x1e,"\x8B\xD5\x81\xC2", 4)) {
+
+            offset = 0;
+            if (0x6c - cli_readint32(epbuff+0xf) + cli_readint32(epbuff+0x22) == 0xC6)
+            ecx = cli_readint32(epbuff+0x14) - cli_readint32(epbuff+0x1a);
+        }
 
-	/* yC 1.3 variant */
-	if (!ecx && !memcmp(epbuff, "\x55\x8B\xEC\x83\xEC\x40\x53\x56\x57", 9) &&
-	    !memcmp(epbuff+0x17, "\xe8\x00\x00\x00\x00\x5d\x81\xed", 8) &&
-	    ((uint8_t)epbuff[0x23] == 0xB9)) {
-
-	    offset = 0x10;
-	    if (0x6c - cli_readint32(epbuff+0x1f) + cli_readint32(epbuff+0x32) == 0xC6)
-		ecx = cli_readint32(epbuff+0x24) - cli_readint32(epbuff+0x2a);
-	}
+        /* yC 1.3 variant */
+        if (!ecx && !memcmp(epbuff, "\x55\x8B\xEC\x83\xEC\x40\x53\x56\x57", 9) &&
+            !memcmp(epbuff+0x17, "\xe8\x00\x00\x00\x00\x5d\x81\xed", 8) &&
+            ((uint8_t)epbuff[0x23] == 0xB9)) {
+
+            offset = 0x10;
+            if (0x6c - cli_readint32(epbuff+0x1f) + cli_readint32(epbuff+0x32) == 0xC6)
+            ecx = cli_readint32(epbuff+0x24) - cli_readint32(epbuff+0x2a);
+        }
 
-	/* yC 1.x/modified */
-	if (!ecx && !memcmp(epbuff, "\x60\xe8\x00\x00\x00\x00\x5d\x81\xed",9) &&
-	    ((uint8_t)epbuff[0xd] == 0xb9) &&
-	    ((uint16_t)cli_readint16(epbuff + 0x12)== 0xbd8d) &&
-	    !memcmp(epbuff+0x18, "\x8b\xf7\xac", 3)) {
-
-	    offset = -0x18;
-	    if (0x66 - cli_readint32(epbuff+0x9) + cli_readint32(epbuff+0x14) == 0xae)
-		ecx = cli_readint32(epbuff+0xe);
-	}
+        /* yC 1.x/modified */
+        if (!ecx && !memcmp(epbuff, "\x60\xe8\x00\x00\x00\x00\x5d\x81\xed",9) &&
+            ((uint8_t)epbuff[0xd] == 0xb9) &&
+            ((uint16_t)cli_readint16(epbuff + 0x12)== 0xbd8d) &&
+            !memcmp(epbuff+0x18, "\x8b\xf7\xac", 3)) {
+
+            offset = -0x18;
+            if (0x66 - cli_readint32(epbuff+0x9) + cli_readint32(epbuff+0x14) == 0xae)
+            ecx = cli_readint32(epbuff+0xe);
+        }
 
-	if (ecx > 0x800 && ecx < 0x2000 &&
-	    !memcmp(epbuff+0x63+offset, "\xaa\xe2\xcc", 3) &&
-	    (fsize >= exe_sections[nsections-1].raw + 0xC6 + ecx + offset)) {
-
-	    char *spinned;
-
-	    if((spinned = (char *) cli_malloc(fsize)) == NULL) {
-            cli_errmsg("yC: Unable to allocate memory for spinned %lu\n", (unsigned long)fsize);
-	      free(exe_sections);
-	      return CL_EMEM;
-	    }
+        if (ecx > 0x800 && ecx < 0x2000 &&
+            !memcmp(epbuff+0x63+offset, "\xaa\xe2\xcc", 3) &&
+            (fsize >= exe_sections[nsections-1].raw + 0xC6 + ecx + offset)) {
+
+            char *spinned;
+
+            if((spinned = (char *) cli_malloc(fsize)) == NULL) {
+                cli_errmsg("yC: Unable to allocate memory for spinned %lu\n", (unsigned long)fsize);
+                free(exe_sections);
+                return CL_EMEM;
+            }
 
-	    if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
-	      cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
-	      free(spinned);
-	      free(exe_sections);
-	      return CL_EREAD;
-	    }
+            if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
+                cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
+                free(spinned);
+                free(exe_sections);
+                return CL_EREAD;
+            }
 
 #if HAVE_JSON
-        cli_jsonstr(pe_json, "Packer", "yC");
+            cli_jsonstr(pe_json, "Packer", "yC");
 #endif
 
-	    cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
-	    CLI_UNPTEMP("yC",(spinned,exe_sections,0));
-	    CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
-	}
+            cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
+            CLI_UNPTEMP("yC",(spinned,exe_sections,0));
+            CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
+        }
     }
 
     /* WWPack */
@@ -2525,87 +2582,111 @@
        vep == exe_sections[nsections - 1].rva &&
        memcmp(epbuff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
        memcmp(epbuff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0)  {
-	uint32_t head = exe_sections[nsections - 1].raw;
+        uint32_t head = exe_sections[nsections - 1].raw;
         uint8_t *packer;
-	char *src;
+        char *src;
 
-	ssize = 0;
-	for(i=0 ; ; i++) {
-	    if(exe_sections[i].raw<head)
-	        head=exe_sections[i].raw;
-	    if(i+1==nsections) break;
-	    if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
-		ssize=exe_sections[i].rva+exe_sections[i].vsz;
-	}
-	if(!head || !ssize || head>ssize) break;
+        ssize = 0;
+        for(i=0 ; ; i++) {
+            if(exe_sections[i].raw<head)
+                head=exe_sections[i].raw;
+
+            if(i+1==nsections)
+                break;
 
-	CLI_UNPSIZELIMITS("WWPack", ssize);
+            if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
+                ssize=exe_sections[i].rva+exe_sections[i].vsz;
+        }
+
+        if(!head || !ssize || head>ssize)
+            break;
+
+        CLI_UNPSIZELIMITS("WWPack", ssize);
 
         if(!(src=(char *)cli_calloc(ssize, sizeof(char)))) {
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
-	if((size_t) fmap_readn(map, src, 0, head) != head) {
-	    cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", head);
-	    free(src);
-	    free(exe_sections);
-	    return CL_EREAD;
-	}
+            free(exe_sections);
+            return CL_EMEM;
+        }
+
+        if((size_t) fmap_readn(map, src, 0, head) != head) {
+            cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", head);
+            free(src);
+            free(exe_sections);
+            return CL_EREAD;
+        }
+
         for(i = 0 ; i < (unsigned int)nsections-1; i++) {
-	    if(!exe_sections[i].rsz) continue;
-            if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
-            if((unsigned int)fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
+            if(!exe_sections[i].rsz)
+                continue;
+
+            if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz))
+                break;
+
+            if((unsigned int)fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz)
+                break;
         }
+
         if(i+1!=nsections) {
             cli_dbgmsg("WWpack: Probably hacked/damaged file.\n");
             free(src);
             break;
         }
-	if((packer = (uint8_t *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
-	    free(src);
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
-	if(!exe_sections[nsections - 1].rsz || (size_t) fmap_readn(map, packer, exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
-	    cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
-	    free(src);
-	    free(packer);
-	    free(exe_sections);
-	    return CL_EREAD;
-	}
+
+        if((packer = (uint8_t *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
+            free(src);
+            free(exe_sections);
+            return CL_EMEM;
+        }
+
+        if(!exe_sections[nsections - 1].rsz || (size_t) fmap_readn(map, packer, exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
+            cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
+            free(src);
+            free(packer);
+            free(exe_sections);
+            return CL_EREAD;
+        }
 
 #if HAVE_JSON
-    cli_jsonstr(pe_json, "Packer", "WWPack");
+        cli_jsonstr(pe_json, "Packer", "WWPack");
 #endif
 
-	CLI_UNPTEMP("WWPack",(src,packer,exe_sections,0));
-	CLI_UNPRESULTS("WWPack",(wwunpack((uint8_t *)src, ssize, packer, exe_sections, nsections-1, e_lfanew, ndesc)),0,(src,packer,0));
-	break;
+        CLI_UNPTEMP("WWPack",(src,packer,exe_sections,0));
+        CLI_UNPRESULTS("WWPack",(wwunpack((uint8_t *)src, ssize, packer, exe_sections, nsections-1, e_lfanew, ndesc)),0,(src,packer,0));
+        break;
     }
 
 
     /* ASPACK support */
     while((DCONF & PE_CONF_ASPACK) && ep+58+0x70e < fsize && !memcmp(epbuff,"\x60\xe8\x03\x00\x00\x00\xe9\xeb",8)) {
-	char *src;
+        char *src;
 
-        if(epsize<0x3bf || memcmp(epbuff+0x3b9, "\x68\x00\x00\x00\x00\xc3",6)) break;
-	ssize = 0;
-	for(i=0 ; i< nsections ; i++)
-	    if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
-		ssize=exe_sections[i].rva+exe_sections[i].vsz;
-	if(!ssize) break;
+        if(epsize<0x3bf || memcmp(epbuff+0x3b9, "\x68\x00\x00\x00\x00\xc3",6))
+            break;
+        ssize = 0;
+        for(i=0 ; i< nsections ; i++)
+            if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
+                ssize=exe_sections[i].rva+exe_sections[i].vsz;
+
+        if(!ssize)
+            break;
 
-	CLI_UNPSIZELIMITS("Aspack", ssize);
+        CLI_UNPSIZELIMITS("Aspack", ssize);
 
         if(!(src=(char *)cli_calloc(ssize, sizeof(char)))) {
-	    free(exe_sections);
-	    return CL_EMEM;
-	}
+            free(exe_sections);
+            return CL_EMEM;
+        }
         for(i = 0 ; i < (unsigned int)nsections; i++) {
-	    if(!exe_sections[i].rsz) continue;
-            if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
-            if((unsigned int)fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
+            if(!exe_sections[i].rsz)
+                continue;
+
+            if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz))
+                break;
+
+            if((unsigned int)fmap_readn(map, src+exe_sections[i].rva, exe_sections[i].raw, exe_sections[i].rsz)!=exe_sections[i].rsz)
+                break;
         }
+
         if(i!=nsections) {
             cli_dbgmsg("Aspack: Probably hacked/damaged Aspack file.\n");
             free(src);
@@ -2616,212 +2697,230 @@
         cli_jsonstr(pe_json, "Packer", "Aspack");
 #endif
 
-	CLI_UNPTEMP("Aspack",(src,exe_sections,0));
-	CLI_UNPRESULTS("Aspack",(unaspack212((uint8_t *)src, ssize, exe_sections, nsections, vep-1, EC32(optional_hdr32.ImageBase), ndesc)),1,(src,0));
-	break;
+        CLI_UNPTEMP("Aspack",(src,exe_sections,0));
+        CLI_UNPRESULTS("Aspack",(unaspack212((uint8_t *)src, ssize, exe_sections, nsections, vep-1, EC32(optional_hdr32.ImageBase), ndesc)),1,(src,0));
+        break;
     }
 
     /* NsPack */
 
     while (DCONF & PE_CONF_NSPACK) {
-	uint32_t eprva = vep;
-	uint32_t start_of_stuff, rep = ep;
-	unsigned int nowinldr;
-	const char *nbuff;
-
-	src=epbuff;
-	if (*epbuff=='\xe9') { /* bitched headers */
-	    eprva = cli_readint32(epbuff+1)+vep+5;
-	    if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) break;
-	    if (!(nbuff = fmap_need_off_once(map, rep, 24))) break;
-	    src = nbuff;
-	}
+        uint32_t eprva = vep;
+        uint32_t start_of_stuff, rep = ep;
+        unsigned int nowinldr;
+        const char *nbuff;
+
+        src=epbuff;
+        if (*epbuff=='\xe9') { /* bitched headers */
+            eprva = cli_readint32(epbuff+1)+vep+5;
+            if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err)
+                break;
 
-	if (memcmp(src, "\x9c\x60\xe8\x00\x00\x00\x00\x5d\xb8\x07\x00\x00\x00", 13)) break;
+            if (!(nbuff = fmap_need_off_once(map, rep, 24)))
+                break;
 
-	nowinldr = 0x54-cli_readint32(src+17);
-	cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
+            src = nbuff;
+        }
 
-	if(!(nbuff = fmap_need_off_once(map, rep-nowinldr, 4))) break;
-	start_of_stuff=rep+cli_readint32(nbuff);
-	if(!(nbuff = fmap_need_off_once(map, start_of_stuff, 20))) break;
-	src = nbuff;
-	if (!cli_readint32(nbuff)) {
-	    start_of_stuff+=4; /* FIXME: more to do */
-	    src+=4;
-	}
+        if (memcmp(src, "\x9c\x60\xe8\x00\x00\x00\x00\x5d\xb8\x07\x00\x00\x00", 13))
+            break;
 
-	ssize = cli_readint32(src+5)|0xff;
-	dsize = cli_readint32(src+9);
+        nowinldr = 0x54-cli_readint32(src+17);
+        cli_dbgmsg("NsPack: Found *start_of_stuff @delta-%x\n", nowinldr);
 
-	CLI_UNPSIZELIMITS("NsPack", MAX(ssize,dsize));
+        if(!(nbuff = fmap_need_off_once(map, rep-nowinldr, 4)))
+            break;
 
-	if (!ssize || !dsize || dsize != exe_sections[0].vsz) break;
-	if (!(dest=cli_malloc(dsize))) {
-        cli_errmsg("NsPack: Unable to allocate memory for dest %u\n", dsize);
-        break;
-    }
-	/* memset(dest, 0xfc, dsize); */
+        start_of_stuff=rep+cli_readint32(nbuff);
+        if(!(nbuff = fmap_need_off_once(map, start_of_stuff, 20)))
+            break;
 
-	if(!(src = fmap_need_off(map, start_of_stuff, ssize))) {
-	    free(dest);
-	    break;
-	}
-	/* memset(src, 0x00, ssize); */
+        src = nbuff;
+        if (!cli_readint32(nbuff)) {
+            start_of_stuff+=4; /* FIXME: more to do */
+            src+=4;
+        }
 
-	eprva+=0x27a;
-	if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) {
-	  free(dest);
-	  break;
-	}
-	if(!(nbuff = fmap_need_off_once(map, rep, 5))) {
-	  free(dest);
-	  break;
-	}
-	fmap_unneed_off(map, start_of_stuff, ssize);
-	eprva=eprva+5+cli_readint32(nbuff+1);
-	cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
+        ssize = cli_readint32(src+5)|0xff;
+        dsize = cli_readint32(src+9);
+
+        CLI_UNPSIZELIMITS("NsPack", MAX(ssize,dsize));
+
+        if (!ssize || !dsize || dsize != exe_sections[0].vsz)
+            break;
+
+        if (!(dest=cli_malloc(dsize))) {
+            cli_errmsg("NsPack: Unable to allocate memory for dest %u\n", dsize);
+            break;
+        }
+        /* memset(dest, 0xfc, dsize); */
+
+        if(!(src = fmap_need_off(map, start_of_stuff, ssize))) {
+            free(dest);
+            break;
+        }
+        /* memset(src, 0x00, ssize); */
+
+        eprva+=0x27a;
+        if (!(rep = cli_rawaddr(eprva, exe_sections, nsections, &err, fsize, hdr_size)) && err) {
+          free(dest);
+          break;
+        }
+
+        if(!(nbuff = fmap_need_off_once(map, rep, 5))) {
+          free(dest);
+          break;
+        }
+
+        fmap_unneed_off(map, start_of_stuff, ssize);
+        eprva=eprva+5+cli_readint32(nbuff+1);
+        cli_dbgmsg("NsPack: OEP = %08x\n", eprva);
 
 #if HAVE_JSON
-    cli_jsonstr(pe_json, "Packer", "NsPack");
+        cli_jsonstr(pe_json, "Packer", "NsPack");
 #endif
 
-	CLI_UNPTEMP("NsPack",(dest,exe_sections,0));
-	CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,(dest,0));
-	break;
+        CLI_UNPTEMP("NsPack",(dest,exe_sections,0));
+        CLI_UNPRESULTS("NsPack",(unspack(src, dest, ctx, exe_sections[0].rva, EC32(optional_hdr32.ImageBase), eprva, ndesc)),0,(dest,0));
+        break;
     }
 
     /* to be continued ... */
 
-
-
-
     /* !!!!!!!!!!!!!!    PACKERS END HERE    !!!!!!!!!!!!!! */
     ctx->corrupted_input = corrupted_cur;
 
     /* Bytecode BC_PE_UNPACKER hook */
     bc_ctx = cli_bytecode_context_alloc();
     if (!bc_ctx) {
-	cli_errmsg("cli_scanpe: can't allocate memory for bc_ctx\n");
-	return CL_EMEM;
+        cli_errmsg("cli_scanpe: can't allocate memory for bc_ctx\n");
+        return CL_EMEM;
     }
+
     cli_bytecode_context_setpe(bc_ctx, &pedata, exe_sections);
     cli_bytecode_context_setctx(bc_ctx, ctx);
+
     ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_UNPACKER, map);
     switch (ret) {
-	case CL_VIRUS:
-	    free(exe_sections);
-	    cli_bytecode_context_destroy(bc_ctx);
-	    return CL_VIRUS;
-	case CL_SUCCESS:
-	    ndesc = cli_bytecode_context_getresult_file(bc_ctx, &tempfile);
-	    cli_bytecode_context_destroy(bc_ctx);
-	    if (ndesc != -1 && tempfile) {
-		CLI_UNPRESULTS("bytecode PE hook", 1, 1, (0));
-	    }
-	    break;
-	default:
-	    cli_bytecode_context_destroy(bc_ctx);
+    case CL_VIRUS:
+        free(exe_sections);
+        cli_bytecode_context_destroy(bc_ctx);
+        return CL_VIRUS;
+    case CL_SUCCESS:
+        ndesc = cli_bytecode_context_getresult_file(bc_ctx, &tempfile);
+        cli_bytecode_context_destroy(bc_ctx);
+        if (ndesc != -1 && tempfile) {
+            CLI_UNPRESULTS("bytecode PE hook", 1, 1, (0));
+        }
+
+        break;
+    default:
+        cli_bytecode_context_destroy(bc_ctx);
     }
 
     free(exe_sections);
+
 #if HAVE_JSON
-    if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS) {
+    if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS)
         return CL_ETIMEOUT;
-    }
 #endif
+
     if (SCAN_ALL && viruses_found)
-	return CL_VIRUS;
+        return CL_VIRUS;
+
     return CL_CLEAN;
 }
 
 int cli_peheader(fmap_t *map, struct cli_exe_info *peinfo)
 {
-	uint16_t e_magic; /* DOS signature ("MZ") */
-	uint32_t e_lfanew; /* address of new exe header */
-	/* Obsolete - see below
-	  uint32_t min = 0, max = 0;
-	*/
-	struct pe_image_file_hdr file_hdr;
-	union {
-	    struct pe_image_optional_hdr64 opt64;
-	    struct pe_image_optional_hdr32 opt32;
-	} pe_opt;
-	struct pe_image_section_hdr *section_hdr;
-	unsigned int i;
-	unsigned int err, pe_plus = 0;
-	uint32_t valign, falign, hdr_size;
-	size_t fsize;
-	ssize_t at;
-	struct pe_image_data_dir *dirs;
+    uint16_t e_magic; /* DOS signature ("MZ") */
+    uint32_t e_lfanew; /* address of new exe header */
+    /* Obsolete - see below
+      uint32_t min = 0, max = 0;
+    */
+    struct pe_image_file_hdr file_hdr;
+    union {
+        struct pe_image_optional_hdr64 opt64;
+        struct pe_image_optional_hdr32 opt32;
+    } pe_opt;
+    struct pe_image_section_hdr *section_hdr;
+    unsigned int i;
+    unsigned int err, pe_plus = 0;
+    uint32_t valign, falign, hdr_size;
+    size_t fsize;
+    ssize_t at;
+    struct pe_image_data_dir *dirs;
 
     cli_dbgmsg("in cli_peheader\n");
 
     fsize = map->len - peinfo->offset;
     if(fmap_readn(map, &e_magic, peinfo->offset, sizeof(e_magic)) != sizeof(e_magic)) {
-	cli_dbgmsg("Can't read DOS signature\n");
-	return -1;
+        cli_dbgmsg("Can't read DOS signature\n");
+        return -1;
     }
 
     if(EC16(e_magic) != PE_IMAGE_DOS_SIGNATURE && EC16(e_magic) != PE_IMAGE_DOS_SIGNATURE_OLD) {
-	cli_dbgmsg("Invalid DOS signature\n");
-	return -1;
+        cli_dbgmsg("Invalid DOS signature\n");
+        return -1;
     }
 
     if(fmap_readn(map, &e_lfanew, peinfo->offset + 58 + sizeof(e_magic), sizeof(e_lfanew)) != sizeof(e_lfanew)) {
-	/* truncated header? */
-	return -1;
+        /* truncated header? */
+        return -1;
     }
 
     e_lfanew = EC32(e_lfanew);
     if(!e_lfanew) {
-	cli_dbgmsg("Not a PE file\n");
-	return -1;
+        cli_dbgmsg("Not a PE file\n");
+        return -1;
     }
 
     if(fmap_readn(map, &file_hdr, peinfo->offset + e_lfanew, sizeof(struct pe_image_file_hdr)) != sizeof(struct pe_image_file_hdr)) {
-	/* bad information in e_lfanew - probably not a PE file */
-	cli_dbgmsg("Can't read file header\n");
-	return -1;
+        /* bad information in e_lfanew - probably not a PE file */
+        cli_dbgmsg("Can't read file header\n");
+        return -1;
     }
 
     if(EC32(file_hdr.Magic) != PE_IMAGE_NT_SIGNATURE) {
-	cli_dbgmsg("Invalid PE signature (probably NE file)\n");
-	return -1;
+        cli_dbgmsg("Invalid PE signature (probably NE file)\n");
+        return -1;
     }
 
     if ( (peinfo->nsections = EC16(file_hdr.NumberOfSections)) < 1 || peinfo->nsections > 96 ) return -1;
 
     if (EC16(file_hdr.SizeOfOptionalHeader) < sizeof(struct pe_image_optional_hdr32)) {
         cli_dbgmsg("SizeOfOptionalHeader too small\n");
-	return -1;
+        return -1;
     }
 
     at = peinfo->offset + e_lfanew + sizeof(struct pe_image_file_hdr);
     if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
         cli_dbgmsg("Can't read optional file header\n");
-	return -1;
+        return -1;
     }
     at += sizeof(struct pe_image_optional_hdr32);
 
     if(EC16(optional_hdr64.Magic)==PE32P_SIGNATURE) { /* PE+ */
         if(EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr64)) {
-	    cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
-	    return -1;
-	}
-	if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
-	    cli_dbgmsg("Can't read optional file header\n");
-	    return -1;
-	}
-	at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
-	hdr_size = EC32(optional_hdr64.SizeOfHeaders);
-	pe_plus=1;
+            cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
+            return -1;
+        }
+
+        if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
+            cli_dbgmsg("Can't read optional file header\n");
+            return -1;
+        }
+
+        at += sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32);
+        hdr_size = EC32(optional_hdr64.SizeOfHeaders);
+        pe_plus=1;
     } else { /* PE */
-	if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
-	    /* Seek to the end of the long header */
-	    at += EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32);
-	}
-	hdr_size = EC32(optional_hdr32.SizeOfHeaders);
+        if (EC16(file_hdr.SizeOfOptionalHeader)!=sizeof(struct pe_image_optional_hdr32)) {
+            /* Seek to the end of the long header */
+            at += EC16(file_hdr.SizeOfOptionalHeader)-sizeof(struct pe_image_optional_hdr32);
+        }
+
+        hdr_size = EC32(optional_hdr32.SizeOfHeaders);
     }
 
     valign = (pe_plus)?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment);
@@ -2832,249 +2931,253 @@
     peinfo->section = (struct cli_exe_section *) cli_calloc(peinfo->nsections, sizeof(struct cli_exe_section));
 
     if(!peinfo->section) {
-	cli_dbgmsg("Can't allocate memory for section headers\n");
-	return -1;
+        cli_dbgmsg("Can't allocate memory for section headers\n");
+        return -1;
     }
 
     section_hdr = (struct pe_image_section_hdr *) cli_calloc(peinfo->nsections, sizeof(struct pe_image_section_hdr));
 
     if(!section_hdr) {
-	cli_dbgmsg("Can't allocate memory for section headers\n");
-	free(peinfo->section);
-	peinfo->section = NULL;
-	return -1;
+        cli_dbgmsg("Can't allocate memory for section headers\n");
+        free(peinfo->section);
+        peinfo->section = NULL;
+        return -1;
     }
 
     if(fmap_readn(map, section_hdr, at, peinfo->nsections * sizeof(struct pe_image_section_hdr)) != peinfo->nsections * sizeof(struct pe_image_section_hdr)) {
         cli_dbgmsg("Can't read section header\n");
-	cli_dbgmsg("Possibly broken PE file\n");
-	free(section_hdr);
-	free(peinfo->section);
-	peinfo->section = NULL;
-	return -1;
+        cli_dbgmsg("Possibly broken PE file\n");
+        free(section_hdr);
+        free(peinfo->section);
+        peinfo->section = NULL;
+        return -1;
     }
     at += sizeof(struct pe_image_section_hdr)*peinfo->nsections;
 
     for(i = 0; falign!=0x200 && i<peinfo->nsections; i++) {
-	/* file alignment fallback mode - blah */
-	if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) {
-	    falign = 0x200;
-	}
+        /* file alignment fallback mode - blah */
+        if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) {
+            falign = 0x200;
+        }
     }
 
     for(i = 0; i < peinfo->nsections; i++) {
         peinfo->section[i].rva = PEALIGN(EC32(section_hdr[i].VirtualAddress), valign);
-	peinfo->section[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
-	peinfo->section[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign);
-	peinfo->section[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign);
+        peinfo->section[i].vsz = PESALIGN(EC32(section_hdr[i].VirtualSize), valign);
+        peinfo->section[i].raw = PEALIGN(EC32(section_hdr[i].PointerToRawData), falign);
+        peinfo->section[i].rsz = PESALIGN(EC32(section_hdr[i].SizeOfRawData), falign);
 
-	if (!peinfo->section[i].vsz && peinfo->section[i].rsz)
-	    peinfo->section[i].vsz=PESALIGN(EC32(section_hdr[i].SizeOfRawData), valign);
+        if (!peinfo->section[i].vsz && peinfo->section[i].rsz)
+            peinfo->section[i].vsz=PESALIGN(EC32(section_hdr[i].SizeOfRawData), valign);
 
-	if (peinfo->section[i].rsz && !CLI_ISCONTAINED(0, (uint32_t) fsize, peinfo->section[i].raw, peinfo->section[i].rsz))
-	    peinfo->section[i].rsz = (fsize - peinfo->section[i].raw)*(fsize>peinfo->section[i].raw);
+        if (peinfo->section[i].rsz && !CLI_ISCONTAINED(0, (uint32_t) fsize, peinfo->section[i].raw, peinfo->section[i].rsz))
+            peinfo->section[i].rsz = (fsize - peinfo->section[i].raw)*(fsize>peinfo->section[i].raw);
     }
 
     if(pe_plus) {
-	peinfo->ep = EC32(optional_hdr64.AddressOfEntryPoint);
-	dirs = optional_hdr64.DataDirectory;
+        peinfo->ep = EC32(optional_hdr64.AddressOfEntryPoint);
+        dirs = optional_hdr64.DataDirectory;
     } else {
-	peinfo->ep = EC32(optional_hdr32.AddressOfEntryPoint);
-	dirs = optional_hdr32.DataDirectory;
+        peinfo->ep = EC32(optional_hdr32.AddressOfEntryPoint);
+        dirs = optional_hdr32.DataDirectory;
     }
 
     if(!(peinfo->ep = cli_rawaddr(peinfo->ep, peinfo->section, peinfo->nsections, &err, fsize, hdr_size)) && err) {
-	cli_dbgmsg("Broken PE file\n");
-	free(section_hdr);
-	free(peinfo->section);
-	peinfo->section = NULL;
-	return -1;
+        cli_dbgmsg("Broken PE file\n");
+        free(section_hdr);
+        free(peinfo->section);
+        peinfo->section = NULL;
+        return -1;
     }
 
     if(EC16(file_hdr.Characteristics) & 0x2000 || !dirs[2].Size)
-	peinfo->res_addr = 0;
+        peinfo->res_addr = 0;
     else
-	peinfo->res_addr = EC32(dirs[2].VirtualAddress);
+        peinfo->res_addr = EC32(dirs[2].VirtualAddress);
 
     while(dirs[2].Size) {
-	struct vinfo_list vlist;
-	const uint8_t *vptr, *baseptr;
-    	uint32_t rva, res_sz;
-
-	memset(&vlist, 0, sizeof(vlist));
-    	findres(0x10, 0xffffffff, EC32(dirs[2].VirtualAddress), map, peinfo->section, peinfo->nsections, hdr_size, versioninfo_cb, &vlist);
-	if(!vlist.count) break; /* No version_information */
-	if(cli_hashset_init(&peinfo->vinfo, 32, 80)) {
-	    cli_errmsg("cli_peheader: Unable to init vinfo hashset\n");
-	    free(section_hdr);
-	    free(peinfo->section);
-	    peinfo->section = NULL;
-	    return -1;
-	}
-
-	err = 0;
-	for(i=0; i<vlist.count; i++) { /* enum all version_information res - RESUMABLE */
-	    cli_dbgmsg("cli_peheader: parsing version info @ rva %x (%u/%u)\n", vlist.rvas[i], i+1, vlist.count);
-	    rva = cli_rawaddr(vlist.rvas[i], peinfo->section, peinfo->nsections, &err, fsize, hdr_size);
-	    if(err)
-		continue;
-
-	    if(!(vptr = fmap_need_off_once(map, rva, 16)))
-		continue;
-
-	    baseptr = vptr - rva;
-	    /* parse resource */
-	    rva = cli_readint32(vptr); /* ptr to version_info */
-	    res_sz = cli_readint32(vptr+4); /* sizeof(resource) */
-	    rva = cli_rawaddr(rva, peinfo->section, peinfo->nsections, &err, fsize, hdr_size);
-	    if(err)
-		continue;
-	    if(!(vptr = fmap_need_off_once(map, rva, res_sz)))
-		continue;
-	    
-	    while(res_sz>4) { /* look for version_info - NOT RESUMABLE (expecting exactly one versioninfo) */
-		uint32_t vinfo_sz, vinfo_val_sz, got_varfileinfo = 0;
-
-		vinfo_sz = vinfo_val_sz = cli_readint32(vptr);
-		vinfo_sz &= 0xffff;
-		if(vinfo_sz > res_sz)
-		    break; /* the content is larger than the container */
-
-		vinfo_val_sz >>= 16;
-		if(vinfo_sz <= 6 + 0x20 + 2 + 0x34 ||
-		   vinfo_val_sz != 0x34 || 
-		   memcmp(vptr+6, "V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0\0\0", 0x20) ||
-		   (unsigned int)cli_readint32(vptr + 0x28) != 0xfeef04bd) {
-		    /* - there should be enough room for the header(6), the key "VS_VERSION_INFO"(20), the padding(2) and the value(34)
-		     * - the value should be sizeof(fixedfileinfo)
-		     * - the key should match
-		     * - there should be some proper magic for fixedfileinfo */
-		    break; /* there's no point in looking further */
-		}
-
-		/* move to the end of fixedfileinfo where the child elements are located */
-		vptr += 6 + 0x20 + 2 + 0x34;
-		vinfo_sz -= 6 + 0x20 + 2 + 0x34;
-
-		while(vinfo_sz > 6) { /* look for stringfileinfo - NOT RESUMABLE (expecting at most one stringfileinfo) */
-		    uint32_t sfi_sz = cli_readint32(vptr) & 0xffff;
-
-		    if(sfi_sz > vinfo_sz)
-			break; /* the content is larger than the container */
-
-		    if(!got_varfileinfo && sfi_sz > 6 + 0x18 && !memcmp(vptr+6, "V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0", 0x18)) {
-			/* skip varfileinfo as it sometimes appear before stringtableinfo */
-			vptr += sfi_sz;
-			vinfo_sz -= sfi_sz;
-			got_varfileinfo = 1;
-			continue;
-		    }
+        struct vinfo_list vlist;
+        const uint8_t *vptr, *baseptr;
+        uint32_t rva, res_sz;
+
+        memset(&vlist, 0, sizeof(vlist));
+        findres(0x10, 0xffffffff, EC32(dirs[2].VirtualAddress), map, peinfo->section, peinfo->nsections, hdr_size, versioninfo_cb, &vlist);
+        if(!vlist.count)
+            break; /* No version_information */
 
-		    if(sfi_sz <= 6 + 0x1e || memcmp(vptr+6, "S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0", 0x1e)) {
-			/* - there should be enough room for the header(6) and the key "StringFileInfo"(1e)
-			 * - the key should match */
-			break; /* this is an implicit hard fail: parent is not resumable */
-		    }
-
-		    /* move to the end of stringfileinfo where the child elements are located */
-		    vptr += 6 + 0x1e;
-		    sfi_sz -= 6 + 0x1e;
-
-		    while(sfi_sz > 6) { /* enum all stringtables - RESUMABLE */
-			uint32_t st_sz = cli_readint32(vptr) & 0xffff;
-			const uint8_t *next_vptr = vptr + st_sz;
-			uint32_t next_sfi_sz = sfi_sz - st_sz;
-
-			if(st_sz > sfi_sz || st_sz <= 24) {
-			    /* - the content is larger than the container
-			       - there's no room for a stringtables (headers(6) + key(16) + padding(2)) */
-			    break; /* this is an implicit hard fail: parent is not resumable */
-			}
-
-			/* move to the end of stringtable where the child elements are located */
-			vptr += 24;
-			st_sz -= 24;
-
-			while(st_sz > 6) {  /* enum all strings - RESUMABLE */
-			    uint32_t s_sz, s_key_sz, s_val_sz;
-
-			    s_sz = (cli_readint32(vptr) & 0xffff) + 3;
-			    s_sz &= ~3;
-			    if(s_sz > st_sz || s_sz <= 6 + 2 + 8) {
-				/* - the content is larger than the container
-				 * - there's no room for a minimal string
-				 * - there's no room for the value */
-				st_sz = 0;
-				sfi_sz = 0;
-				break; /* force a hard fail */
-			    }
-
-			    /* ~wcstrlen(key) */
-			    for(s_key_sz = 6; s_key_sz+1 < s_sz; s_key_sz += 2) {
-				if(vptr[s_key_sz] || vptr[s_key_sz+1]) continue;
-				s_key_sz += 2;
-				break;
-			    }
-
-			    s_key_sz += 3;
-			    s_key_sz &= ~3;
+        if(cli_hashset_init(&peinfo->vinfo, 32, 80)) {
+            cli_errmsg("cli_peheader: Unable to init vinfo hashset\n");
+            free(section_hdr);
+            free(peinfo->section);
+            peinfo->section = NULL;
+            return -1;
+        }
 
-			    if(s_key_sz >= s_sz) {
-				/* key overflow */
-				vptr += s_sz;
-				st_sz -= s_sz;
-				continue;
-			    }
-
-			    s_val_sz = s_sz - s_key_sz;
-			    s_key_sz -= 6;
-
-			    if(s_val_sz <= 2) {
-				/* skip unset value */
-				vptr += s_sz;
-				st_sz -= s_sz;
-				continue;
-			    }
-
-			    if(cli_hashset_addkey(&peinfo->vinfo, (uint32_t)(vptr - baseptr + 6))) {
-				cli_errmsg("cli_peheader: Unable to add rva to vinfo hashset\n");
-				cli_hashset_destroy(&peinfo->vinfo);
-				free(section_hdr);
-				free(peinfo->section);
-				peinfo->section = NULL;
-				return -1;
-			    }
-
-			    if(cli_debug_flag) {
-				char *k, *v, *s;
-
-				/* FIXME: skip too long strings */
-				k = cli_utf16toascii((const char*)vptr + 6, s_key_sz);
-				if(k) {
-				    v = cli_utf16toascii((const char*)vptr + s_key_sz + 6, s_val_sz);
-				    if(v) {
-					s = cli_str2hex((const char*)vptr + 6, s_key_sz + s_val_sz - 6);
-					if(s) {
-					    cli_dbgmsg("VersionInfo (%x): '%s'='%s' - VI:%s\n", (uint32_t)(vptr - baseptr + 6), k, v, s);
-					    free(s);
-					}
-					free(v);
-				    }
-				    free(k);
-				}
-			    }
-			    vptr += s_sz;
-			    st_sz -= s_sz;
-			} /* enum all strings - RESUMABLE */
-			vptr = next_vptr;
-			sfi_sz = next_sfi_sz * (sfi_sz != 0);
-		    } /* enum all stringtables - RESUMABLE */
-		    break;
-		} /* look for stringfileinfo - NOT RESUMABLE */
-		break;
-	    } /* look for version_info - NOT RESUMABLE */
-	} /* enum all version_information res - RESUMABLE */
-	break;
+        err = 0;
+        for(i=0; i<vlist.count; i++) { /* enum all version_information res - RESUMABLE */
+            cli_dbgmsg("cli_peheader: parsing version info @ rva %x (%u/%u)\n", vlist.rvas[i], i+1, vlist.count);
+            rva = cli_rawaddr(vlist.rvas[i], peinfo->section, peinfo->nsections, &err, fsize, hdr_size);
+            if(err)
+                continue;
+
+            if(!(vptr = fmap_need_off_once(map, rva, 16)))
+                continue;
+
+            baseptr = vptr - rva;
+            /* parse resource */
+            rva = cli_readint32(vptr); /* ptr to version_info */
+            res_sz = cli_readint32(vptr+4); /* sizeof(resource) */
+            rva = cli_rawaddr(rva, peinfo->section, peinfo->nsections, &err, fsize, hdr_size);
+            if(err)
+                continue;
+            if(!(vptr = fmap_need_off_once(map, rva, res_sz)))
+                continue;
+            
+            while(res_sz>4) { /* look for version_info - NOT RESUMABLE (expecting exactly one versioninfo) */
+                uint32_t vinfo_sz, vinfo_val_sz, got_varfileinfo = 0;
+
+                vinfo_sz = vinfo_val_sz = cli_readint32(vptr);
+                vinfo_sz &= 0xffff;
+                if(vinfo_sz > res_sz)
+                    break; /* the content is larger than the container */
+
+                vinfo_val_sz >>= 16;
+                if(vinfo_sz <= 6 + 0x20 + 2 + 0x34 ||
+                   vinfo_val_sz != 0x34 || 
+                   memcmp(vptr+6, "V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0\0\0", 0x20) ||
+                   (unsigned int)cli_readint32(vptr + 0x28) != 0xfeef04bd) {
+                    /* - there should be enough room for the header(6), the key "VS_VERSION_INFO"(20), the padding(2) and the value(34)
+                     * - the value should be sizeof(fixedfileinfo)
+                     * - the key should match
+                     * - there should be some proper magic for fixedfileinfo */
+                    break; /* there's no point in looking further */
+                }
+
+                /* move to the end of fixedfileinfo where the child elements are located */
+                vptr += 6 + 0x20 + 2 + 0x34;
+                vinfo_sz -= 6 + 0x20 + 2 + 0x34;
+
+                while(vinfo_sz > 6) { /* look for stringfileinfo - NOT RESUMABLE (expecting at most one stringfileinfo) */
+                    uint32_t sfi_sz = cli_readint32(vptr) & 0xffff;
+
+                    if(sfi_sz > vinfo_sz)
+                        break; /* the content is larger than the container */
+
+                    if(!got_varfileinfo && sfi_sz > 6 + 0x18 && !memcmp(vptr+6, "V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0", 0x18)) {
+                        /* skip varfileinfo as it sometimes appear before stringtableinfo */
+                        vptr += sfi_sz;
+                        vinfo_sz -= sfi_sz;
+                        got_varfileinfo = 1;
+                        continue;
+                    }
+
+                    if(sfi_sz <= 6 + 0x1e || memcmp(vptr+6, "S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0", 0x1e)) {
+                        /* - there should be enough room for the header(6) and the key "StringFileInfo"(1e)
+                         * - the key should match */
+                        break; /* this is an implicit hard fail: parent is not resumable */
+                    }
+
+                    /* move to the end of stringfileinfo where the child elements are located */
+                    vptr += 6 + 0x1e;
+                    sfi_sz -= 6 + 0x1e;
+
+                    while(sfi_sz > 6) { /* enum all stringtables - RESUMABLE */
+                        uint32_t st_sz = cli_readint32(vptr) & 0xffff;
+                        const uint8_t *next_vptr = vptr + st_sz;
+                        uint32_t next_sfi_sz = sfi_sz - st_sz;
+
+                        if(st_sz > sfi_sz || st_sz <= 24) {
+                            /* - the content is larger than the container
+                               - there's no room for a stringtables (headers(6) + key(16) + padding(2)) */
+                            break; /* this is an implicit hard fail: parent is not resumable */
+                        }
+
+                        /* move to the end of stringtable where the child elements are located */
+                        vptr += 24;
+                        st_sz -= 24;
+
+                        while(st_sz > 6) {  /* enum all strings - RESUMABLE */
+                            uint32_t s_sz, s_key_sz, s_val_sz;
+
+                            s_sz = (cli_readint32(vptr) & 0xffff) + 3;
+                            s_sz &= ~3;
+                            if(s_sz > st_sz || s_sz <= 6 + 2 + 8) {
+                                /* - the content is larger than the container
+                                 * - there's no room for a minimal string
+                                 * - there's no room for the value */
+                                st_sz = 0;
+                                sfi_sz = 0;
+                                break; /* force a hard fail */
+                            }
+
+                            /* ~wcstrlen(key) */
+                            for(s_key_sz = 6; s_key_sz+1 < s_sz; s_key_sz += 2) {
+                                if(vptr[s_key_sz] || vptr[s_key_sz+1])
+                                    continue;
+
+                                s_key_sz += 2;
+                                break;
+                            }
+
+                            s_key_sz += 3;
+                            s_key_sz &= ~3;
+
+                            if(s_key_sz >= s_sz) {
+                                /* key overflow */
+                                vptr += s_sz;
+                                st_sz -= s_sz;
+                                continue;
+                            }
+
+                            s_val_sz = s_sz - s_key_sz;
+                            s_key_sz -= 6;
+
+                            if(s_val_sz <= 2) {
+                                /* skip unset value */
+                                vptr += s_sz;
+                                st_sz -= s_sz;
+                                continue;
+                            }
+
+                            if(cli_hashset_addkey(&peinfo->vinfo, (uint32_t)(vptr - baseptr + 6))) {
+                                cli_errmsg("cli_peheader: Unable to add rva to vinfo hashset\n");
+                                cli_hashset_destroy(&peinfo->vinfo);
+                                free(section_hdr);
+                                free(peinfo->section);
+                                peinfo->section = NULL;
+                                return -1;
+                            }
+
+                            if(cli_debug_flag) {
+                                char *k, *v, *s;
+
+                                /* FIXME: skip too long strings */
+                                k = cli_utf16toascii((const char*)vptr + 6, s_key_sz);
+                                if(k) {
+                                    v = cli_utf16toascii((const char*)vptr + s_key_sz + 6, s_val_sz);
+                                    if(v) {
+                                        s = cli_str2hex((const char*)vptr + 6, s_key_sz + s_val_sz - 6);
+                                        if(s) {
+                                            cli_dbgmsg("VersionInfo (%x): '%s'='%s' - VI:%s\n", (uint32_t)(vptr - baseptr + 6), k, v, s);
+                                            free(s);
+                                        }
+                                        free(v);
+                                    }
+                                    free(k);
+                                }
+                            }
+                            vptr += s_sz;
+                            st_sz -= s_sz;
+                        } /* enum all strings - RESUMABLE */
+                        vptr = next_vptr;
+                        sfi_sz = next_sfi_sz * (sfi_sz != 0);
+                    } /* enum all stringtables - RESUMABLE */
+                    break;
+                } /* look for stringfileinfo - NOT RESUMABLE */
+                break;
+            } /* look for version_info - NOT RESUMABLE */
+        } /* enum all version_information res - RESUMABLE */
+        break;
     } /* while(dirs[2].Size) */
 
     free(section_hdr);
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/scanners.c clamav-0.98.5+dfsg/libclamav/scanners.c
--- clamav-0.98.5~rc1+dfsg/libclamav/scanners.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/scanners.c	2014-11-13 17:30:43.000000000 -0500
@@ -2596,6 +2596,7 @@
             if (type == CL_TYPE_PDF ||   /* file types we collect properties about */
                 type == CL_TYPE_MSOLE2 ||
                 type == CL_TYPE_MSEXE ||
+                //type == CL_TYPE_ZIP ||
                 type == CL_TYPE_OOXML_WORD ||
                 type == CL_TYPE_OOXML_PPT ||
                 type == CL_TYPE_OOXML_XL) { 
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/swf.c clamav-0.98.5+dfsg/libclamav/swf.c
--- clamav-0.98.5~rc1+dfsg/libclamav/swf.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/swf.c	2014-11-13 17:30:43.000000000 -0500
@@ -124,7 +124,7 @@
 	z_stream stream;
 	char inbuff[FILEBUFF], outbuff[FILEBUFF];
 	fmap_t *map = *ctx->fmap;
-	int offset = 8, ret, zret, outsize = 8, count;
+	int offset = 8, ret, zret, outsize = 8, count, zend;
 	char *tmpname;
 	int fd;
 
@@ -174,9 +174,11 @@
 		close(fd);
 		if(cli_unlink(tmpname)) {
 		    free(tmpname);
+            inflateEnd(&stream);
 		    return CL_EUNLINK;
 		}
 		free(tmpname);
+        inflateEnd(&stream);
 		return CL_EUNPACK;
 	    }
 	    if(!ret)
@@ -205,7 +207,9 @@
 	stream.avail_out = FILEBUFF;
     } while(zret == Z_OK);
 
-    if((zret != Z_STREAM_END && zret != Z_OK) || (zret = inflateEnd(&stream)) != Z_OK) {
+    zend = inflateEnd(&stream);
+
+    if((zret != Z_STREAM_END && zret != Z_OK) || zend != Z_OK) {
         /*
          * outsize is initialized to 8, it being 8 here means that we couldn't even read a single byte.
          * If outsize > 8, then we have data. Let's scan what we have.
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/tomsfastmath/misc/fp_ident.c clamav-0.98.5+dfsg/libclamav/tomsfastmath/misc/fp_ident.c
--- clamav-0.98.5~rc1+dfsg/libclamav/tomsfastmath/misc/fp_ident.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/tomsfastmath/misc/fp_ident.c	2014-11-13 17:30:43.000000000 -0500
@@ -74,7 +74,7 @@
 
    if (sizeof(fp_digit) == sizeof(fp_word)) {
       strncat(buf, "WARNING: sizeof(fp_digit) == sizeof(fp_word), this build is likely to not work properly.\n", 
-              sizeof(buf)-1);
+              sizeof(buf)-strlen(buf)-1);
    }
    return buf;
 }
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/unzip.c clamav-0.98.5+dfsg/libclamav/unzip.c
--- clamav-0.98.5~rc1+dfsg/libclamav/unzip.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/unzip.c	2014-11-13 17:30:43.000000000 -0500
@@ -53,14 +53,6 @@
 #define UNZIP_PRIVATE
 #include "unzip.h"
 
-typedef struct zip_request {
-    const char *name;
-    size_t namelen;
-    uint32_t loff;
-
-    int found;
-} zip_request_t;
-
 static int wrap_inflateinit2(void *a, int b) {
   return inflateInit2(a, b);
 }
@@ -427,7 +419,7 @@
   return zip-lh;
 }
 
-static unsigned int chdr(fmap_t *map, uint32_t coff, uint32_t zsize, unsigned int *fu, unsigned int fc, int *ret, cli_ctx *ctx, char *tmpd, zip_request_t *request) {
+static unsigned int chdr(fmap_t *map, uint32_t coff, uint32_t zsize, unsigned int *fu, unsigned int fc, int *ret, cli_ctx *ctx, char *tmpd, struct zip_requests *requests) {
   char name[256];
   int last = 0;
   const uint8_t *ch;
@@ -447,7 +439,7 @@
   }
 
   name[0]='\0';
-  if((cli_debug_flag && !last) || request) {
+  if((cli_debug_flag && !last) || requests) {
       unsigned int size = (CH_flen>=sizeof(name))?sizeof(name)-1:CH_flen;
       const char *src = fmap_need_off_once(map, coff, size);
       if(src) {
@@ -470,16 +462,26 @@
   }
   coff+=CH_clen;
 
-  if (!request) {
+  if (!requests) {
       if(CH_off<zsize-SIZEOF_LH) {
           lhdr(map, CH_off, zsize-CH_off, fu, fc, ch, ret, ctx, tmpd, 1, zip_scan_cb);
       } else cli_dbgmsg("cli_unzip: ch - local hdr out of file\n");
   }
   else {
-      size_t len = MIN(sizeof(name)-1, request->namelen);
-      if (!last && !strncmp(request->name, name, len)) {
-          request->found = 1;
-          request->loff = CH_off;
+      int i;
+      size_t len;
+
+      if (!last) {
+          for (i = 0; i < requests->namecnt; ++i) {
+              cli_dbgmsg("checking for %i: %s\n", i, requests->names[i]);
+
+              len = MIN(sizeof(name)-1, requests->namelens[i]);      
+              if (!strncmp(requests->names[i], name, len)) {
+                  requests->match = 1;
+                  requests->found = i;
+                  requests->loff = CH_off;
+              }
+          }
       }
   }
 
@@ -603,27 +605,46 @@
     return unzip_single_internal(ctx, lhoffl, zip_scan_cb);
 }
 
-int unzip_search(cli_ctx *ctx, const char *name, size_t nlen, uint32_t *loff)
+int unzip_search_add(struct zip_requests *requests, const char *name, size_t nlen)
+{
+    cli_dbgmsg("in unzip_search_add\n");
+
+    if (requests->namecnt >= MAX_ZIP_REQUESTS) {
+        cli_dbgmsg("DEBUGGING MESSAGE GOES HERE!\n");
+        return CL_BREAK;
+    }
+
+    cli_dbgmsg("unzip_search_add: adding %s (len %llu)\n", name, (long long unsigned)nlen);
+
+    requests->names[requests->namecnt] = name;
+    requests->namelens[requests->namecnt] = nlen;
+    requests->namecnt++;
+
+    return CL_SUCCESS;
+}
+
+int unzip_search(cli_ctx *ctx, fmap_t *map, struct zip_requests *requests)
 {
     unsigned int fc = 0;
-    fmap_t *map;
+    fmap_t *zmap = map;
     size_t fsize;
     uint32_t coff = 0;
     const char *ptr;
-    zip_request_t request; 
     int ret = CL_CLEAN;
 #if HAVE_JSON
     uint32_t toval = 0;
 #endif
-
     cli_dbgmsg("in unzip_search\n");
-    if (!ctx) {
+
+    if ((!ctx && !map) || !requests) {
         return CL_ENULLARG;
     }
 
-    map = *ctx->fmap;
-    fsize = map->len;
-    if(sizeof(off_t)!=sizeof(uint32_t) && fsize!=map->len) {
+    /* get priority to given map over *ctx->fmap */
+    if (ctx && !map)
+        zmap = *ctx->fmap;
+    fsize = zmap->len;
+    if(sizeof(off_t)!=sizeof(uint32_t) && fsize!=zmap->len) {
         cli_dbgmsg("unzip_search: file too big\n");
         return CL_CLEAN;
     }
@@ -633,7 +654,7 @@
     }
 
     for(coff=fsize-22 ; coff>0 ; coff--) { /* sizeof(EOC)==22 */
-        if(!(ptr = fmap_need_off_once(map, coff, 20)))
+        if(!(ptr = fmap_need_off_once(zmap, coff, 20)))
             continue;
         if(cli_readint32(ptr)==0x06054b50) {
             uint32_t chptr = cli_readint32(&ptr[16]);
@@ -643,25 +664,20 @@
         }
     }
 
-    request.name = name;
-    request.namelen = nlen;
-    request.found = 0;
-
     if(coff) {
         cli_dbgmsg("unzip_search: central @%x\n", coff);
-        while(ret==CL_CLEAN && (coff=chdr(map, coff, fsize, NULL, fc+1, &ret, ctx, NULL, &request))) {
-            if (request.found) {
-                *loff = request.loff;
+        while(ret==CL_CLEAN && (coff=chdr(zmap, coff, fsize, NULL, fc+1, &ret, ctx, NULL, requests))) {
+            if (requests->match) {
                 return CL_VIRUS;
             }
 
             fc++;
-            if (ctx->engine->maxfiles && fc >= ctx->engine->maxfiles) {
+            if (ctx && ctx->engine->maxfiles && fc >= ctx->engine->maxfiles) {
                 cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->engine->maxfiles);
                 ret=CL_EMAXFILES;
             }
 #if HAVE_JSON
-            if (cli_json_timeout_cycle_check(ctx, (int *)(&toval)) != CL_SUCCESS) {
+            if (ctx && cli_json_timeout_cycle_check(ctx, (int *)(&toval)) != CL_SUCCESS) {
                 return CL_ETIMEOUT;
             }
 #endif
@@ -671,5 +687,28 @@
     }
 
     return ret;
+}
+
+int unzip_search_single(cli_ctx *ctx, const char *name, size_t nlen, uint32_t *loff)
+{
+    struct zip_requests requests;
+    int ret;
+
+    cli_dbgmsg("in unzip_search_single\n");
+    if (!ctx) {
+        return CL_ENULLARG;
+    }
+
+    memset(&requests, 0, sizeof(struct zip_requests));
+
+    if ((ret = unzip_search_add(&requests, name, nlen)) != CL_SUCCESS) {
+        return ret;
+    }
+
+    if ((ret = unzip_search(ctx, NULL, &requests)) == CL_VIRUS) {
+        *loff = requests.loff;
+    }
+
+    return ret;
 }
 
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/unzip.h clamav-0.98.5+dfsg/libclamav/unzip.h
--- clamav-0.98.5~rc1+dfsg/libclamav/unzip.h	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/unzip.h	2014-11-13 17:30:43.000000000 -0500
@@ -25,15 +25,30 @@
 #include "clamav-config.h"
 #endif
 
+#include "others.h"
+
 typedef int (*zip_cb)(int fd, cli_ctx *ctx);
 #define zip_scan_cb cli_magic_scandesc
 
-#include "others.h"
+#define MAX_ZIP_REQUESTS 10
+struct zip_requests {
+    const char *names[MAX_ZIP_REQUESTS];
+    size_t namelens[MAX_ZIP_REQUESTS];
+    int namecnt;
+
+    uint32_t loff;
+    int found, match;
+};
+
 int cli_unzip(cli_ctx *);
 int cli_unzip_single_internal(cli_ctx *, off_t, zip_cb);
-int unzip_single_internal(cli_ctx *ctx, off_t lhoffl, zip_cb zcb);
+int unzip_single_internal(cli_ctx *, off_t, zip_cb);
 int cli_unzip_single(cli_ctx *, off_t);
-int unzip_search(cli_ctx *, const char *, size_t, uint32_t *);
+
+int unzip_search_add(struct zip_requests *, const char *, size_t);
+int unzip_search(cli_ctx *, fmap_t *, struct zip_requests *);
+int unzip_search_single(cli_ctx *, const char *, size_t, uint32_t *);
+
 
 #ifdef UNZIP_PRIVATE
 #define F_ENCR  (1<<0)
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/vba_extract.c clamav-0.98.5+dfsg/libclamav/vba_extract.c
--- clamav-0.98.5~rc1+dfsg/libclamav/vba_extract.c	2014-09-03 17:26:54.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/vba_extract.c	2014-11-13 17:30:43.000000000 -0500
@@ -128,7 +128,10 @@
 				*ret++ = '_';
 				*ret++ = (char)(name[i] + '0');
 			} else {
-				const uint16_t x = (uint16_t)((name[i] << 8) | name[i + 1]);
+				uint16_t x;
+				if ((i + 1) >= size)
+					break;
+				x = (uint16_t)((name[i] << 8) | name[i + 1]);
 
 				*ret++ = '_';
 				*ret++ = (char)('a'+((x&0xF)));
@@ -510,6 +513,7 @@
 	if(b == NULL)
 		return NULL;
 
+	memset(buffer, 0, sizeof(buffer));
 	lseek(fd, offset+3, SEEK_SET); /* 1byte ?? , 2byte length ?? */
 	clean = TRUE;
 	pos = 0;
diff -Nru clamav-0.98.5~rc1+dfsg/libclamav/version.h clamav-0.98.5+dfsg/libclamav/version.h
--- clamav-0.98.5~rc1+dfsg/libclamav/version.h	2014-10-10 13:00:40.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamav/version.h	2014-11-13 18:14:39.000000000 -0500
@@ -1 +1 @@
-#define REPO_VERSION "devel-clamav-0.98.5-rc1"
+#define REPO_VERSION "devel-clamav-0.98.5"
diff -Nru clamav-0.98.5~rc1+dfsg/libclamunrar_iface/unrar_iface.c clamav-0.98.5+dfsg/libclamunrar_iface/unrar_iface.c
--- clamav-0.98.5~rc1+dfsg/libclamunrar_iface/unrar_iface.c	2014-09-09 11:45:50.000000000 -0400
+++ clamav-0.98.5+dfsg/libclamunrar_iface/unrar_iface.c	2014-11-13 17:30:43.000000000 -0500
@@ -172,6 +172,7 @@
 	unrar_dbgmsg("UNRAR: Head Size: %.4x\n", file_header->head_size);
 	if(lseek(fd, file_header->next_offset, SEEK_SET) != file_header->next_offset) {
 	    unrar_dbgmsg("seek: %ld\n", file_header->next_offset);
+            free(file_header);
 	    return NULL;
 	}
 
diff -Nru clamav-0.98.5~rc1+dfsg/NEWS clamav-0.98.5+dfsg/NEWS
--- clamav-0.98.5~rc1+dfsg/NEWS	2014-09-03 17:26:52.000000000 -0400
+++ clamav-0.98.5+dfsg/NEWS	2014-11-13 17:30:35.000000000 -0500
@@ -3,20 +3,20 @@
 
 Welcome to ClamAV 0.98.5! ClamAV 0.98.5 includes important new features
 for collecting and analyzing file properties. Software developers and
-analysts may collect file properties using the ClamAV API and then
-analyze them with ClamAV bytecode programs. Using the new features will
-require that libjson-c is installed, but otherwise libjson-c will be
-optional.
+analysts may collect file property meta data using the ClamAV API for
+subsequent analysis by ClamAV bytecode programs. Using these features
+will require that libjson-c is installed, but otherwise libjson-c is not
+needed.
 
 Look for our upcoming series of blog posts to learn more about using the
 ClamAV API and bytecode facilities for collecting and analyzing file
 properties.
 
-ClamAV 0.98.5 also includes these new features:
+ClamAV 0.98.5 also includes these new features and bug fixes:
 
     - Support for the XDP file format and extracting, decoding, and
       scanning PDF files within XDP files.
-    - Addition of shared library support for LLVM verions 3.1 - 3.4
+    - Addition of shared library support for LLVM versions 3.1 - 3.5
       for the purpose of just-in-time(JIT) compilation of ClamAV
       bytecode signatures. Andreas Cadhalpun submitted the patch
       implementing this support.
@@ -24,6 +24,15 @@
       ClamAV bytecode signature authors by providing introspection
       into compiled bytecode programs.
     - Resolution of many of the warning messages from ClamAV compilation.
+    - Improved detection of malicious PE files.
+    - Security fix for ClamAV crash when using 'clamscan -a'. This issue
+      was identified by Kurt Siefried of Red Hat.
+    - Security fix for ClamAV crash when scanning maliciously crafted
+      yoda's crypter files. This issue, as well as several other bugs
+      fixed in this release, were identified by Damien Millescamp of
+      Oppida.
+    - ClamAV 0.98.5 now works with OpenSSL in FIPS compliant mode.
+      Thanks to Reinhard Max for supplying the patch.
     - Bug fixes and other feature enhancements. See Changelog or
       git log for details.
 
@@ -32,6 +41,9 @@
 
 Andreas Cadhalpun
 Sebastian Andrzej Siewior
+Damien Millescamp
+Reinhard Max
+Kurt Seifried
 
 --
 The ClamAV team (http://www.clamav.net/about.html#credits)
diff -Nru clamav-0.98.5~rc1+dfsg/README clamav-0.98.5+dfsg/README
--- clamav-0.98.5~rc1+dfsg/README	2014-09-03 17:26:52.000000000 -0400
+++ clamav-0.98.5+dfsg/README	2014-11-13 17:30:35.000000000 -0500
@@ -7,20 +7,20 @@
 
 Welcome to ClamAV 0.98.5! ClamAV 0.98.5 includes important new features
 for collecting and analyzing file properties. Software developers and
-analysts may collect file properties using the ClamAV API and then
-analyze them with ClamAV bytecode programs. Using the new features will
-require that libjson-c is installed, but otherwise libjson-c will be
-optional.
+analysts may collect file property meta data using the ClamAV API for
+subsequent analysis by ClamAV bytecode programs. Using these features
+will require that libjson-c is installed, but otherwise libjson-c is not
+needed.
 
 Look for our upcoming series of blog posts to learn more about using the
 ClamAV API and bytecode facilities for collecting and analyzing file
 properties.
 
-ClamAV 0.98.5 also includes these new features:
+ClamAV 0.98.5 also includes these new features and bug fixes:
 
     - Support for the XDP file format and extracting, decoding, and
       scanning PDF files within XDP files.
-    - Addition of shared library support for LLVM verions 3.1 - 3.4
+    - Addition of shared library support for LLVM versions 3.1 - 3.5
       for the purpose of just-in-time(JIT) compilation of ClamAV
       bytecode signatures. Andreas Cadhalpun submitted the patch
       implementing this support.
@@ -28,6 +28,15 @@
       ClamAV bytecode signature authors by providing introspection
       into compiled bytecode programs.
     - Resolution of many of the warning messages from ClamAV compilation.
+    - Improved detection of malicious PE files.
+    - Security fix for ClamAV crash when using 'clamscan -a'. This issue
+      was identified by Kurt Siefried of Red Hat.
+    - Security fix for ClamAV crash when scanning maliciously crafted
+      yoda's crypter files. This issue, as well as several other bugs
+      fixed in this release, were identified by Damien Millescamp of
+      Oppida.
+    - ClamAV 0.98.5 now works with OpenSSL in FIPS compliant mode.
+      Thanks to Reinhard Max for supplying the patch.
     - Bug fixes and other feature enhancements. See Changelog or
       git log for details.
 
@@ -36,6 +45,9 @@
 
 Andreas Cadhalpun
 Sebastian Andrzej Siewior
+Damien Millescamp
+Reinhard Max
+Kurt Seifried
 
 0.98.4
 ------

Reply to: