Browse code

Resolve merge conflicts matcher-ac.c clamconf.c readdb.c

Steven Morgan authored on 2015/02/04 09:37:12
Showing 77 changed files
... ...
@@ -1,3 +1,44 @@
1
+
2
+Tue Dec 16 16:21:40 2014 EDT (swebb)
3
+-------------------------------------
4
+bb#11215 - Change a variable to be an unsigned int to compensate for
5
+	compiler optimization issue with crafted petite file. Fix
6
+	suggested by Sebastian Andrzej Siewior.
7
+
8
+Fri Dec 12 14:33:41 2014 EDT (klin)
9
+-----------------------------------
10
+Added missing break statements(FireAmp #12710) to correct handling of
11
+	prescan callback return code.
12
+
13
+Fri Dec 5 15:26:06 2014 EDT (smorgan)
14
+-------------------------------------
15
+bb#11216 - add boundary checks for fuzzed upack file. This issue
16
+	was reported by Sebastian Andrzej Siewior. CVE-2014-9328.
17
+
18
+Thu Dec 4 18:29:17 2014 EDT (klin)
19
+-----------------------------------
20
+bb#11212 - fixed section boundary mismatch in MEW unpacker. This issue
21
+	was identified by Felix Groebert of the Google Security Team.
22
+
23
+Thu Dec 4 08:43:43 2014 EDT (swebb)
24
+-------------------------------------
25
+bb#11213 - Enforce bounds checking before integer overflow in upx files.
26
+	This issue was reported by Kevin Szkudlapski of Quarkslab.
27
+
28
+Tue Dec 2 15:15:55 2014 EDT (swebb)
29
+-------------------------------------
30
+bb#11210: Apply a basic fix for y0da crafted file. This issue was
31
+	identified by Felix Groebert of the Google Security Team.
32
+
33
+Fri, 21 Nov 2014 15:55:12 EDT (swebb)
34
+-------------------------------------
35
+bb#11194: Include OpenSSL's headers after the local headers
36
+
37
+Thu, 20 Nov 2014 12:39:00 EDT (swebb)
38
+-------------------------------------
39
+bb#10907: Add trailing newline to the end of the pidfile
40
+	  (patch submitted by Sebastian Andrzej Siewior)
41
+
1 42
 Wed, 12 Nov 2014 14:30:39 EDT (swebb)
2 43
 -------------------------------------
3 44
 * bb11176 - Instruct OpenSSL to allow MD5 when in FIPS-compliant mode.
... ...
@@ -1,49 +1,36 @@
1
-0.98.5
1
+0.98.6
2 2
 ------
3 3
 
4
-Welcome to ClamAV 0.98.5! ClamAV 0.98.5 includes important new features
5
-for collecting and analyzing file properties. Software developers and
6
-analysts may collect file property meta data using the ClamAV API for
7
-subsequent analysis by ClamAV bytecode programs. Using these features
8
-will require that libjson-c is installed, but otherwise libjson-c is not
9
-needed.
10
-
11
-Look for our upcoming series of blog posts to learn more about using the
12
-ClamAV API and bytecode facilities for collecting and analyzing file
13
-properties.
14
-
15
-ClamAV 0.98.5 also includes these new features and bug fixes:
16
-
17
-    - Support for the XDP file format and extracting, decoding, and
18
-      scanning PDF files within XDP files.
19
-    - Addition of shared library support for LLVM versions 3.1 - 3.5
20
-      for the purpose of just-in-time(JIT) compilation of ClamAV
21
-      bytecode signatures. Andreas Cadhalpun submitted the patch
22
-      implementing this support.
23
-    - Enhancements to the clambc command line utility to assist
24
-      ClamAV bytecode signature authors by providing introspection
25
-      into compiled bytecode programs.
26
-    - Resolution of many of the warning messages from ClamAV compilation.
27
-    - Improved detection of malicious PE files.
28
-    - Security fix for ClamAV crash when using 'clamscan -a'. This issue
29
-      was identified by Kurt Siefried of Red Hat.
30
-    - Security fix for ClamAV crash when scanning maliciously crafted
31
-      yoda's crypter files. This issue, as well as several other bugs
32
-      fixed in this release, were identified by Damien Millescamp of
33
-      Oppida.
34
-    - ClamAV 0.98.5 now works with OpenSSL in FIPS compliant mode.
35
-      Thanks to Reinhard Max for supplying the patch.
36
-    - Bug fixes and other feature enhancements. See Changelog or
37
-      git log for details.
4
+ClamAV 0.98.6 is a bug fix release correcting the following:
38 5
 
6
+    - library shared object revisions.
7
+    - installation issues on some Mac OS X and FreeBSD platforms.
8
+    - includes a patch from Sebastian Andrzej Siewior making
9
+      ClamAV pid files compatible with systemd.
10
+    - Fix a heap out of bounds condition with crafted Yoda's
11
+      crypter files. This issue was discovered by Felix Groebert
12
+      of the Google Security Team.
13
+    - Fix a heap out of bounds condition with crafted mew packer
14
+      files. This issue was discovered by Felix Groebert of the
15
+      Google Security Team.
16
+    - Fix a heap out of bounds condition with crafted upx packer
17
+      files. This issue was discovered by Kevin Szkudlapski of
18
+      Quarkslab.
19
+    - Fix a heap out of bounds condition with crafted upack packer
20
+      files. This issue was discovered by Sebastian Andrzej Siewior.
21
+      CVE-2014-9328.
22
+    - Compensate a crash due to incorrect compiler optimization when
23
+      handling crafted petite packer files. This issue was discovered
24
+      by Sebastian Andrzej Siewior.
25
+      
39 26
 Thanks to the following ClamAV community members for code submissions
40
-and bug reporting included in ClamAV 0.98.5:
27
+and bug reporting included in ClamAV 0.98.6:
41 28
 
42
-Andreas Cadhalpun
43 29
 Sebastian Andrzej Siewior
44
-Damien Millescamp
45
-Reinhard Max
46
-Kurt Seifried
30
+Felix Groebert
31
+Kevin Szkudlapski
32
+Mark Pizzolato
33
+Daniel J. Luke
47 34
 
48 35
 --
49 36
 The ClamAV team (http://www.clamav.net/about.html#credits)
... ...
@@ -2,6 +2,40 @@ Note: This README/NEWS file refers to the source tarball. Some things described
2 2
 here may not be available in binary packages.
3 3
 --
4 4
 
5
+0.98.6
6
+------
7
+
8
+ClamAV 0.98.6 is a bug fix release correcting the following:
9
+
10
+    - library shared object revisions.
11
+    - installation issues on some Mac OS X and FreeBSD platforms.
12
+    - includes a patch from Sebastian Andrzej Siewior making
13
+      ClamAV pid files compatible with systemd.
14
+    - Fix a heap out of bounds condition with crafted Yoda's
15
+      crypter files. This issue was discovered by Felix Groebert
16
+      of the Google Security Team.
17
+    - Fix a heap out of bounds condition with crafted mew packer
18
+      files. This issue was discovered by Felix Groebert of the
19
+      Google Security Team.
20
+    - Fix a heap out of bounds condition with crafted upx packer
21
+      files. This issue was discovered by Kevin Szkudlapski of
22
+      Quarkslab.
23
+    - Fix a heap out of bounds condition with crafted upack packer
24
+      files. This issue was discovered by Sebastian Andrzej Siewior.
25
+      CVE-2014-9328.
26
+    - Compensate a crash due to incorrect compiler optimization when
27
+      handling crafted petite packer files. This issue was discovered
28
+      by Sebastian Andrzej Siewior.
29
+      
30
+Thanks to the following ClamAV community members for code submissions
31
+and bug reporting included in ClamAV 0.98.6:
32
+
33
+Sebastian Andrzej Siewior
34
+Felix Groebert
35
+Kevin Szkudlapski
36
+Mark Pizzolato
37
+Daniel J. Luke
38
+
5 39
 0.98.5
6 40
 ------
7 41
 
... ...
@@ -464,6 +464,9 @@ int main(int argc, char **argv)
464 464
 #ifdef HAVE_PCRE
465 465
 	printf("PCRE ");
466 466
 #endif
467
+#ifdef HAVE_ICONV
468
+	printf("ICONV ");
469
+#endif
467 470
 #ifdef HAVE_JSON
468 471
 	printf("JSON ");
469 472
 #endif
... ...
@@ -112,8 +112,11 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
112 112
             serv[0] = '\0';
113 113
         }
114 114
 #else
115
-        strncpy(host, ipaddr, sizeof(host));
116
-        host[sizeof(host)-1] = '\0';
115
+		if (ipaddr) {
116
+			strncpy(host, ipaddr, sizeof(host));
117
+			host[sizeof(host)-1] = '\0';
118
+		} else
119
+			host[0] = '\0';
117 120
         snprintf(serv, sizeof(serv), "%u", (unsigned int)(optget(opts, "TCPSocket")->numarg));
118 121
 #endif
119 122
         if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
... ...
@@ -99,10 +99,9 @@ int dconnect() {
99 99
         memset(&hints, 0x00, sizeof(struct addrinfo));
100 100
         hints.ai_family = AF_UNSPEC;
101 101
         hints.ai_socktype = SOCK_STREAM;
102
-        hints.ai_flags = AI_PASSIVE;
103 102
 
104 103
         if ((res = getaddrinfo(ipaddr, port, &hints, &info))) {
105
-            logg("!Could not lookup %s: %s\n", opt->strarg, gai_strerror(res));
104
+            logg("!Could not lookup %s: %s\n", ipaddr ? ipaddr : "", gai_strerror(res));
106 105
             opt = opt->nextarg;
107 106
             continue;
108 107
         }
... ...
@@ -1569,37 +1569,39 @@ Optional Features:
1569 1569
                           optimize for fast installation [default=yes]
1570 1570
   --disable-libtool-lock  avoid locking (might break parallel builds)
1571 1571
   --enable-ltdl-install   install libltdl
1572
-  --disable-gcc-vcheck	  do not check for buggy gcc version
1573
-  --enable-experimental	enable experimental code
1574
-  --disable-mempool       disable memory pools
1575
-  --enable-check           Enable 'check' unit tests (default=auto)
1572
+  --disable-gcc-vcheck    do not check for buggy gcc version
1573
+  --enable-experimental   enable experimental code
1574
+  --disable-mempool       do not use memory pools
1575
+  --enable-check          enable check unit tests [default=auto]
1576 1576
   --disable-rpath         do not hardcode runtime library paths
1577 1577
   --enable-coverage       turn on test coverage [default=no]
1578
-  --disable-xml	  disable DMG and XAR support
1579
-  --enable-maintainer-mode enable make rules and dependencies not useful
1580
-                          (and sometimes confusing) to the casual installer
1581
-  --disable-zlib-vcheck	  do not check for buggy zlib version
1582
-  --disable-bzip2	  disable bzip2 support
1583
-  --disable-unrar	  don't build libclamunrar and libclamunrar_iface
1584
-  --disable-getaddrinfo          disable support for getaddrinfo
1585
-  --disable-ipv6          disable IPv6 support
1586
-  --disable-dns           disable support for database verification through
1587
-                          DNS
1588
-  --disable-fanotify	  disable fanotify support (Linux only)
1589
-  --enable-milter	  build clamav-milter
1590
-  --disable-pthreads      disable POSIX threads support
1591
-  --disable-cr		  don't link with C reentrant library (BSD)
1592
-  --enable-id-check	  use id utility instead of /etc/passwd parsing
1593
-  --enable-yp-check	  use ypmatch utility instead of /etc/passwd parsing
1594
-  --enable-no-cache	  use "Cache-Control: no-cache" in freshclam
1595
-  --enable-dns-fix	  enable workaround for broken DNS servers (as in SpeedTouch 510)
1596
-  --enable-bigstack	  increase thread stack size
1597
-  --enable-readdir_r		    enable support for readdir_r
1598
-  --disable-fdpassing        don't build file descriptor passing support
1599
-  --enable-clamdtop       Enable 'clamdtop' tool [default=auto]
1578
+  --disable-xml           do not include DMG and XAR support
1579
+  --enable-maintainer-mode
1580
+                          make rules and dependencies not useful (and
1581
+                          sometimes confusing) to the casual installer
1582
+  --disable-zlib-vcheck   do not check for buggy zlib version
1583
+  --disable-bzip2         do not include bzip2 support
1584
+  --disable-unrar         do not build libclamunrar and libclamunrar_iface
1585
+  --disable-getaddrinfo   do not include support for getaddrinfo
1586
+  --disable-ipv6          do not include IPv6 support
1587
+  --disable-dns           do not include support for database verification
1588
+                          through DNS
1589
+  --disable-fanotify      do not add fanotify support (Linux only)
1590
+  --enable-milter         build clamav-milter
1591
+  --disable-pthreads      do not include POSIX threads support
1592
+  --disable-cr            do not link with C reentrant library (BSD)
1593
+  --enable-id-check       use id utility instead of /etc/passwd parsing
1594
+  --enable-yp-check       use ypmatch utility instead of /etc/passwd parsing
1595
+  --enable-no-cache       use "Cache-Control: no-cache" in freshclam
1596
+  --enable-dns-fix        enable workaround for broken DNS servers (as in
1597
+                          SpeedTouch 510)
1598
+  --enable-bigstack       increase thread stack size
1599
+  --enable-readdir_r      enable support for readdir_r
1600
+  --disable-fdpassing     do not build file descriptor passing support
1601
+  --enable-clamdtop       build clamdtop tool [default=auto]
1600 1602
   --enable-distcheck-werror
1601 1603
                           enable warnings as error for distcheck [default=no]
1602
-  --enable-llvm           Enable 'llvm' JIT/verifier support [default=auto]
1604
+  --enable-llvm           enable 'llvm' JIT/verifier support [default=auto]
1603 1605
 
1604 1606
 
1605 1607
 Optional Packages:
... ...
@@ -1608,40 +1610,47 @@ Optional Packages:
1608 1608
   --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
1609 1609
                           both]
1610 1610
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
1611
-  --with-sysroot=DIR Search for dependent libraries within DIR
1612
-                        (or the compiler's sysroot if not specified).
1611
+  --with-sysroot[=DIR]    search for dependent libraries within DIR (or the
1612
+                          compiler's sysroot if not specified).
1613 1613
   --with-included-ltdl    use the GNU ltdl sources included here
1614
-  --with-ltdl-include=DIR use the ltdl headers installed in DIR
1615
-  --with-ltdl-lib=DIR     use the libltdl.la installed in DIR
1616
-  --with-gnu-ld           assume the C compiler uses GNU ld default=no
1614
+  --with-ltdl-include[=DIR]
1615
+                          use the ltdl headers installed in DIR
1616
+  --with-ltdl-lib[=DIR]   use the libltdl.la installed in DIR
1617
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
1617 1618
   --with-libcheck-prefix[=DIR]  search for libcheck in DIR/include and DIR/lib
1618 1619
   --without-libcheck-prefix     don't search for libcheck in includedir and libdir
1619
-  --with-xml=DIR	  path to directory containing libxml2 library (default=
1620
-			  /usr/local or /usr if not found in /usr/local)
1621
-  --with-openssl=DIR   path to directory containing openssl (default=
1622
-    /usr/local or /usr if not found in /usr/local)
1623
-  --with-libjson=DIR   path to directory containing libjson (default=
1624
-    /usr/local or /usr if not found in /usr/local)
1625
-  --with-pcre=DIR        path to directory containing libpcre library (default=
1626
-                          /usr/local or /usr if not found in /usr/local)
1627
-  --with-zlib=DIR	  path to directory containing zlib library (default=
1628
-			  /usr/local or /usr if not found in /usr/local)
1620
+  --with-xml[=DIR]        path to directory containing libxml2 library
1621
+                          [default=/usr/local or /usr if not found in
1622
+                          /usr/local]
1623
+  --with-openssl[=DIR]    path to directory containing openssl
1624
+                          [default=/usr/local or /usr if not found in
1625
+                          /usr/local]
1626
+  --with-libjson[=DIR]    path to directory containing libjson
1627
+                          [default=/usr/local or /usr if not found in
1628
+                          /usr/local]
1629
+  --with-pcre[=DIR]       path to directory containing libpcre library
1630
+                          [default=/usr/local or /usr if not found in
1631
+                          /usr/local]
1632
+  --with-zlib[=DIR]       path to directory containing zlib library
1633
+                          [default=/usr/local or /usr if not found in
1634
+                          /usr/local]
1629 1635
   --with-libbz2-prefix[=DIR]  search for libbz2 in DIR/include and DIR/lib
1630 1636
   --without-libbz2-prefix     don't search for libbz2 in includedir and libdir
1631
-  --with-iconv supports iconv() (default=auto)
1632
-  --with-user=uid	  name of the clamav user (default=clamav)
1633
-  --with-group=gid	  name of the clamav group (default=clamav)
1634
-  --with-version=STR    use custom version string (dev only)
1635
-  --with-dbdir=path	  path to virus database directory
1637
+  --with-iconv            supports iconv() [default=auto]
1638
+  --with-user[=uid]       name of the clamav user [default=clamav]
1639
+  --with-group[=gid]      name of the clamav group [default=clamav]
1640
+  --with-version[=STR]    use custom version string (dev only)
1641
+  --with-dbdir[=path]     path to virus database directory
1636 1642
   --with-libncurses-prefix[=DIR]  search for libncurses in DIR/include and DIR/lib
1637 1643
   --without-libncurses-prefix     don't search for libncurses in includedir and libdir
1638 1644
   --with-libpdcurses-prefix[=DIR]  search for libpdcurses in DIR/include and DIR/lib
1639 1645
   --without-libpdcurses-prefix     don't search for libpdcurses in includedir and libdir
1640
-  --with-system-llvm      Use system llvm instead of built-in, uses full path
1641
-                          to llvm-config (default= /usr/local or /usr if not
1642
-                          found in /usr/local)
1643
-  --with-libcurl=DIR   path to directory containing libcurl (default=
1644
-    /usr/local or /usr if not found in /usr/local)
1646
+  --with-system-llvm      use system llvm instead of built-in, uses full path
1647
+                          to llvm-config [default=/usr/local or /usr if not
1648
+                          found in /usr/local]
1649
+  --with-libcurl[=DIR]    path to directory containing libcurl
1650
+                          [default=/usr/local or /usr if not found in
1651
+                          /usr/local]
1645 1652
 
1646 1653
 Some influential environment variables:
1647 1654
   CC          C compiler command
... ...
@@ -61,7 +61,7 @@ m4_include([m4/reorganization/compiler_checks.m4])
61 61
 m4_include([m4/reorganization/linker_checks.m4])
62 62
 
63 63
 AC_ARG_ENABLE([experimental],
64
-[  --enable-experimental	enable experimental code],
64
+[AS_HELP_STRING([--enable-experimental], [enable experimental code])],
65 65
 enable_experimental=$enableval, enable_experimental="no")
66 66
 
67 67
 if test "$enable_experimental" = "yes"; then
... ...
@@ -186,7 +186,7 @@ cat <<EOF
186 186
               pthreads    : $have_pthreads ($THREAD_LIBS)
187 187
 EOF
188 188
 
189
-AC_MSG_NOTICE([Summary of miscellaneous  features])
189
+AC_MSG_NOTICE([Summary of miscellaneous features])
190 190
 if test "x$CHECK_LIBS" = "x"; then
191 191
     check_libs="no"
192 192
 else
... ...
@@ -206,7 +206,7 @@ CL_MSG_STATUS([clamdtop    ],[$CURSES_LIBS],[$enable_clamdtop])
206 206
 CL_MSG_STATUS([milter      ],[yes],[$have_milter])
207 207
 CL_MSG_STATUS([clamsubmit  ],[$have_curl],[$curl_msg])
208 208
 
209
-AC_MSG_NOTICE([Summary of engine performance features)])
209
+AC_MSG_NOTICE([Summary of engine performance features])
210 210
 if test "x$enable_debug" = "xyes"; then
211 211
     CL_MSG_STATUS([release mode],[no],[debug build])
212 212
 else
... ...
@@ -319,7 +319,7 @@ Possible values:
319 319
 .br
320 320
 \fBForceJIT\fR \- always choose JIT, fail if not possible
321 321
 .br
322
-\fBForceIntepreter\fR \- always choose interpreter
322
+\fBForceInterpreter\fR \- always choose interpreter
323 323
 .br
324 324
 \fBTest\fR \- run with both JIT and interpreter and compare results. Make all failures fatal.
325 325
 .RE
... ...
@@ -1,4 +1,4 @@
1
-.TH "Config tool" "1" "March 20, 2014" "ClamAV @VERSION@" "Clam AntiVirus"
1
+.TH "File submission tool" "1" "March 20, 2014" "ClamAV @VERSION@" "Clam AntiVirus"
2 2
 .SH "NAME"
3 3
 .LP 
4 4
 clamsubmit \- File submission utility for ClamAV
... ...
@@ -26,8 +26,6 @@ Required option for setting the name of the sender for the submission.
26 26
 .TP
27 27
 \fB-p FILE\fR
28 28
 Submit a file that reports as a false positive (ClamAV flags the file as virus). FILE can be \- to specify stdin. Mutually exclusive with \-n.
29
-.SH "CREDITS"
30
-The idea of this tool is based on Postfix's postconf. clamconf was created under pressure from Tomasz Papszun ;-)
31 29
 .SH "AUTHOR"
32 30
 .LP 
33 31
 Shawn Webb <swebb@sourcefire.com>
... ...
@@ -92,7 +92,8 @@ libclamav_internal_utils_la_SOURCES=str.c\
92 92
 				    regex/cname.h \
93 93
 				    regex/regex.h \
94 94
 				    regex/regex2.h \
95
-				    regex/utils.h
95
+				    regex/utils.h \
96
+					strlcat.c
96 97
 
97 98
 libclamav_internal_utils_la_LDFLAGS=-static @SSL_LDFLAGS@ @JSON_LDFLAGS@
98 99
 libclamav_internal_utils_la_CFLAGS=$(AM_CFLAGS)  -fPIC -DPIC @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
... ...
@@ -118,7 +119,8 @@ libclamav_internal_utils_nothreads_la_SOURCES=str.c\
118 118
 				    regex/cname.h \
119 119
 				    regex/regex.h \
120 120
 				    regex/regex2.h \
121
-				    regex/utils.h
121
+				    regex/utils.h \
122
+					strlcat.c
122 123
 
123 124
 libclamav_internal_utils_nothreads_la_LDFLAGS=-static @SSL_LDFLAGS@ @JSON_LDFLAGS@
124 125
 libclamav_internal_utils_nothreads_la_CFLAGS=$(AM_CFLAGS) -DCL_NOTHREADS @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
... ...
@@ -358,7 +358,8 @@ am_libclamav_internal_utils_la_OBJECTS =  \
358 358
 	libclamav_internal_utils_la-regcomp.lo \
359 359
 	libclamav_internal_utils_la-regerror.lo \
360 360
 	libclamav_internal_utils_la-regexec.lo \
361
-	libclamav_internal_utils_la-regfree.lo
361
+	libclamav_internal_utils_la-regfree.lo \
362
+	libclamav_internal_utils_la-strlcat.lo
362 363
 libclamav_internal_utils_la_OBJECTS =  \
363 364
 	$(am_libclamav_internal_utils_la_OBJECTS)
364 365
 libclamav_internal_utils_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
... ...
@@ -377,7 +378,8 @@ am_libclamav_internal_utils_nothreads_la_OBJECTS =  \
377 377
 	libclamav_internal_utils_nothreads_la-regcomp.lo \
378 378
 	libclamav_internal_utils_nothreads_la-regerror.lo \
379 379
 	libclamav_internal_utils_nothreads_la-regexec.lo \
380
-	libclamav_internal_utils_nothreads_la-regfree.lo
380
+	libclamav_internal_utils_nothreads_la-regfree.lo \
381
+	libclamav_internal_utils_nothreads_la-strlcat.lo
381 382
 libclamav_internal_utils_nothreads_la_OBJECTS =  \
382 383
 	$(am_libclamav_internal_utils_nothreads_la_OBJECTS)
383 384
 libclamav_internal_utils_nothreads_la_LINK = $(LIBTOOL) $(AM_V_lt) \
... ...
@@ -817,7 +819,8 @@ libclamav_internal_utils_la_SOURCES = str.c\
817 817
 				    regex/cname.h \
818 818
 				    regex/regex.h \
819 819
 				    regex/regex2.h \
820
-				    regex/utils.h
820
+				    regex/utils.h \
821
+					strlcat.c
821 822
 
822 823
 libclamav_internal_utils_la_LDFLAGS = -static @SSL_LDFLAGS@ @JSON_LDFLAGS@
823 824
 libclamav_internal_utils_la_CFLAGS = $(AM_CFLAGS)  -fPIC -DPIC @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
... ...
@@ -842,7 +845,8 @@ libclamav_internal_utils_nothreads_la_SOURCES = str.c\
842 842
 				    regex/cname.h \
843 843
 				    regex/regex.h \
844 844
 				    regex/regex2.h \
845
-				    regex/utils.h
845
+				    regex/utils.h \
846
+					strlcat.c
846 847
 
847 848
 libclamav_internal_utils_nothreads_la_LDFLAGS = -static @SSL_LDFLAGS@ @JSON_LDFLAGS@
848 849
 libclamav_internal_utils_nothreads_la_CFLAGS = $(AM_CFLAGS) -DCL_NOTHREADS @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
... ...
@@ -1105,6 +1109,7 @@ distclean-compile:
1105 1105
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_la-regexec.Plo@am__quote@
1106 1106
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_la-regfree.Plo@am__quote@
1107 1107
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_la-str.Plo@am__quote@
1108
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_la-strlcat.Plo@am__quote@
1108 1109
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_la-strlcpy.Plo@am__quote@
1109 1110
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-conv.Plo@am__quote@
1110 1111
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-crypto.Plo@am__quote@
... ...
@@ -1116,6 +1121,7 @@ distclean-compile:
1116 1116
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-regexec.Plo@am__quote@
1117 1117
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-regfree.Plo@am__quote@
1118 1118
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-str.Plo@am__quote@
1119
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-strlcat.Plo@am__quote@
1119 1120
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_internal_utils_nothreads_la-strlcpy.Plo@am__quote@
1120 1121
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zAlloc.Plo@am__quote@
1121 1122
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-7zBuf.Plo@am__quote@
... ...
@@ -3018,6 +3024,13 @@ libclamav_internal_utils_la-regfree.lo: regex/regfree.c
3018 3018
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3019 3019
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_la_CFLAGS) $(CFLAGS) -c -o libclamav_internal_utils_la-regfree.lo `test -f 'regex/regfree.c' || echo '$(srcdir)/'`regex/regfree.c
3020 3020
 
3021
+libclamav_internal_utils_la-strlcat.lo: strlcat.c
3022
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_la_CFLAGS) $(CFLAGS) -MT libclamav_internal_utils_la-strlcat.lo -MD -MP -MF $(DEPDIR)/libclamav_internal_utils_la-strlcat.Tpo -c -o libclamav_internal_utils_la-strlcat.lo `test -f 'strlcat.c' || echo '$(srcdir)/'`strlcat.c
3023
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_internal_utils_la-strlcat.Tpo $(DEPDIR)/libclamav_internal_utils_la-strlcat.Plo
3024
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='strlcat.c' object='libclamav_internal_utils_la-strlcat.lo' libtool=yes @AMDEPBACKSLASH@
3025
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3026
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_la_CFLAGS) $(CFLAGS) -c -o libclamav_internal_utils_la-strlcat.lo `test -f 'strlcat.c' || echo '$(srcdir)/'`strlcat.c
3027
+
3021 3028
 libclamav_internal_utils_nothreads_la-str.lo: str.c
3022 3029
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_nothreads_la_CFLAGS) $(CFLAGS) -MT libclamav_internal_utils_nothreads_la-str.lo -MD -MP -MF $(DEPDIR)/libclamav_internal_utils_nothreads_la-str.Tpo -c -o libclamav_internal_utils_nothreads_la-str.lo `test -f 'str.c' || echo '$(srcdir)/'`str.c
3023 3030
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_internal_utils_nothreads_la-str.Tpo $(DEPDIR)/libclamav_internal_utils_nothreads_la-str.Plo
... ...
@@ -3095,6 +3108,13 @@ libclamav_internal_utils_nothreads_la-regfree.lo: regex/regfree.c
3095 3095
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3096 3096
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_nothreads_la_CFLAGS) $(CFLAGS) -c -o libclamav_internal_utils_nothreads_la-regfree.lo `test -f 'regex/regfree.c' || echo '$(srcdir)/'`regex/regfree.c
3097 3097
 
3098
+libclamav_internal_utils_nothreads_la-strlcat.lo: strlcat.c
3099
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_nothreads_la_CFLAGS) $(CFLAGS) -MT libclamav_internal_utils_nothreads_la-strlcat.lo -MD -MP -MF $(DEPDIR)/libclamav_internal_utils_nothreads_la-strlcat.Tpo -c -o libclamav_internal_utils_nothreads_la-strlcat.lo `test -f 'strlcat.c' || echo '$(srcdir)/'`strlcat.c
3100
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_internal_utils_nothreads_la-strlcat.Tpo $(DEPDIR)/libclamav_internal_utils_nothreads_la-strlcat.Plo
3101
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='strlcat.c' object='libclamav_internal_utils_nothreads_la-strlcat.lo' libtool=yes @AMDEPBACKSLASH@
3102
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3103
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_nothreads_la_CFLAGS) $(CFLAGS) -c -o libclamav_internal_utils_nothreads_la-strlcat.lo `test -f 'strlcat.c' || echo '$(srcdir)/'`strlcat.c
3104
+
3098 3105
 libclamav_nocxx_la-bytecode_nojit.lo: bytecode_nojit.c
3099 3106
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_nocxx_la_CFLAGS) $(CFLAGS) -MT libclamav_nocxx_la-bytecode_nojit.lo -MD -MP -MF $(DEPDIR)/libclamav_nocxx_la-bytecode_nojit.Tpo -c -o libclamav_nocxx_la-bytecode_nojit.lo `test -f 'bytecode_nojit.c' || echo '$(srcdir)/'`bytecode_nojit.c
3100 3107
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_nocxx_la-bytecode_nojit.Tpo $(DEPDIR)/libclamav_nocxx_la-bytecode_nojit.Plo
... ...
@@ -589,24 +589,9 @@ static void gpt_printName(uint16_t name[], const char* msg)
589 589
 
590 590
 static void gpt_printGUID(uint8_t GUID[], const char* msg)
591 591
 {
592
-    unsigned i;
593
-    char hexstr[64], tmpstr[64];
594
-
595
-    hexstr[0] = '\0';
596
-    tmpstr[0] = '\0';
597
-    for (i = 0; i < 16; ++i) {
598
-        gpt_printmsg("%x\n", GUID[i]);
599
-        if (i == 3 || i == 5 || i == 7 || i == 9) {
600
-            snprintf(hexstr, 64, "%s%02x-", tmpstr, GUID[i]);
601
-            gpt_printmsg("%s\n", hexstr);
602
-        }
603
-        else {
604
-            snprintf(hexstr, 64, "%s%02x", tmpstr, GUID[i]);
605
-            gpt_printmsg("%s\n", hexstr);
606
-        }
607
-        strncpy(tmpstr, hexstr, 64);
608
-    }
609
-    cli_dbgmsg("%s: %s\n", msg, hexstr);
592
+    cli_dbgmsg("%s: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
593
+               msg, GUID[0], GUID[1], GUID[2], GUID[3], GUID[4], GUID[5], GUID[6], GUID[7],
594
+               GUID[8], GUID[9], GUID[10], GUID[11], GUID[12], GUID[13], GUID[14], GUID[15]);
610 595
 }
611 596
 
612 597
 static int gpt_prtn_intxn(cli_ctx *ctx, struct gpt_header hdr, size_t sectorsize)
... ...
@@ -525,7 +525,8 @@ static int replace_token_range(struct tokens *dst, size_t start, size_t end, con
525 525
 {
526 526
 	const size_t len = with ? with->cnt : 0;
527 527
 	size_t i;
528
-	cli_dbgmsg(MODULE "Replacing tokens %lu - %lu with %lu tokens\n",start, end, len);
528
+	cli_dbgmsg(MODULE "Replacing tokens %lu - %lu with %lu tokens\n", (unsigned long)start,
529
+                   (unsigned long)end, (unsigned long)len);
529 530
 	if(start >= dst->cnt || end > dst->cnt)
530 531
 		return -1;
531 532
 	for(i=start;i<end;i++) {
... ...
@@ -547,7 +548,7 @@ static int append_tokens(struct tokens *dst, const struct tokens *src)
547 547
 		return CL_ENULLARG;
548 548
 	if(tokens_ensure_capacity(dst, dst->cnt + src->cnt))
549 549
 		return CL_EMEM;
550
-	cli_dbgmsg(MODULE "Appending %lu tokens\n", src->cnt);
550
+	cli_dbgmsg(MODULE "Appending %lu tokens\n", (unsigned long)(src->cnt));
551 551
 	memcpy(&dst->data[dst->cnt], src->data, src->cnt * sizeof(dst->data[0]));
552 552
 	dst->cnt += src->cnt;
553 553
 	return CL_SUCCESS;
... ...
@@ -1110,7 +1111,7 @@ void cli_js_process_buffer(struct parser_state *state, const char *buf, size_t n
1110 1110
 				TOKEN_SET(&val, scope, state->current);
1111 1111
 				break;
1112 1112
 			case TOK_StringLiteral:
1113
-				if(state->tokens.cnt > 0 && state->tokens.data[state->tokens.cnt-1].type == TOK_PLUS) {
1113
+				if(state->tokens.cnt > 1 && state->tokens.data[state->tokens.cnt-1].type == TOK_PLUS) {
1114 1114
 					/* see if can fold */
1115 1115
 					yystype *prev_string = &state->tokens.data[state->tokens.cnt-2];
1116 1116
 					if(prev_string->type == TOK_StringLiteral) {
... ...
@@ -69,6 +69,8 @@ CLAMAV_PRIVATE {
69 69
     cli_gettmpdir;
70 70
     cli_strtok;
71 71
     cli_strtokenize;
72
+    cli_strlcat;
73
+    cli_strlcpy;
72 74
     cli_cvdunpack;
73 75
     cli_regcomp;
74 76
     cli_regexec;
... ...
@@ -1653,203 +1653,191 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1653 1653
     }
1654 1654
 
1655 1655
     if(strchr(hexsig, '(')) {
1656
-        char *hexnew, *start, *h, *c;
1657
-
1658
-        if(hex) {
1659
-            hexcpy = hex;
1660
-        } else if(!(hexcpy = cli_strdup(hexsig))) {
1661
-            mpool_free(root->mempool, new);
1662
-            return CL_EMEM;
1663
-        }
1664
-
1665
-        if(!(hexnew = (char *) cli_calloc(strlen(hexsig) + 1, 1))) {
1666
-            free(new);
1667
-            free(hexcpy);
1668
-            return CL_EMEM;
1669
-        }
1670
-
1671
-        start = pt = hexcpy;
1672
-        while((pt = strchr(start, '('))) {
1673
-            *pt++ = 0;
1674
-
1675
-            if(!start) {
1676
-                error = CL_EMALFDB;
1677
-                break;
1678
-            }
1679
-
1680
-            newspecial = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
1681
-            if(!newspecial) {
1682
-                cli_errmsg("cli_ac_addsig: Can't allocate newspecial\n");
1683
-                error = CL_EMEM;
1684
-                break;
1685
-            }
1686
-
1687
-            if(pt >= hexcpy + 2) {
1688
-                if(pt[-2] == '!') {
1689
-                    newspecial->negative = 1;
1690
-                    pt[-2] = 0;
1691
-                }
1692
-            }
1693
-
1694
-            strcat(hexnew, start);
1695
-
1696
-            if(!(start = strchr(pt, ')'))) {
1697
-                mpool_free(root->mempool, newspecial);
1698
-                error = CL_EMALFDB;
1699
-                break;
1700
-            }
1701
-
1702
-            *start++ = 0;
1703
-            if(!strlen(pt)) {
1704
-                cli_errmsg("cli_ac_addsig: Empty block\n");
1705
-                error = CL_EMALFDB;
1706
-                break;
1707
-            }
1708
-
1709
-            if(!strcmp(pt, "B")) {
1710
-                if(!*start) {
1711
-                    new->boundary |= AC_BOUNDARY_RIGHT;
1712
-                    if(newspecial->negative)
1713
-                        new->boundary |= AC_BOUNDARY_RIGHT_NEGATIVE;
1714
-
1715
-                    mpool_free(root->mempool, newspecial);
1716
-                    continue;
1717
-                } else if(pt - 1 == hexcpy) {
1718
-                    new->boundary |= AC_BOUNDARY_LEFT;
1719
-                    if(newspecial->negative)
1720
-                        new->boundary |= AC_BOUNDARY_LEFT_NEGATIVE;
1721
-
1722
-                    mpool_free(root->mempool, newspecial);
1723
-                    continue;
1724
-                }
1725
-            } else if(!strcmp(pt, "L")) {
1726
-                if(!*start) {
1727
-                    new->boundary |= AC_LINE_MARKER_RIGHT;
1728
-                    if(newspecial->negative)
1729
-                        new->boundary |= AC_LINE_MARKER_RIGHT_NEGATIVE;
1730
-
1731
-                    mpool_free(root->mempool, newspecial);
1732
-                    continue;
1733
-                } else if(pt - 1 == hexcpy) {
1734
-                    new->boundary |= AC_LINE_MARKER_LEFT;
1735
-                    if(newspecial->negative)
1736
-                        new->boundary |= AC_LINE_MARKER_LEFT_NEGATIVE;
1737
-
1738
-                    mpool_free(root->mempool, newspecial);
1739
-                    continue;
1740
-                }
1741
-            }
1742
-
1743
-            strcat(hexnew, "()");
1744
-            new->special++;
1745
-            newtable = (struct cli_ac_special **) mpool_realloc(root->mempool, new->special_table, new->special * sizeof(struct cli_ac_special *));
1746
-            if(!newtable) {
1747
-                new->special--;
1748
-                mpool_free(root->mempool, newspecial);
1749
-                cli_errmsg("cli_ac_addsig: Can't realloc new->special_table\n");
1750
-                error = CL_EMEM;
1751
-                break;
1752
-            }
1753
-
1754
-            newtable[new->special - 1] = newspecial;
1755
-            new->special_table = newtable;
1756
-
1757
-            if(!strcmp(pt, "B")) {
1758
-                newspecial->type = AC_SPECIAL_BOUNDARY;
1759
-            } else if(!strcmp(pt, "L")) {
1760
-                newspecial->type = AC_SPECIAL_LINE_MARKER;
1761
-#if 0
1762
-            } else if(strcmp(pt, "W")) {
1763
-                newspecial->type = AC_SPECIAL_WHITE;
1764
-#endif
1765
-            } else {
1766
-                newspecial->num = 1;
1767
-                for(i = 0; i < strlen(pt); i++)
1768
-                    if(pt[i] == '|')
1769
-                        newspecial->num++;
1770
-
1771
-                if(3 * newspecial->num - 1 == (uint16_t) strlen(pt)) {
1772
-                    newspecial->type = AC_SPECIAL_ALT_CHAR;
1773
-                    newspecial->str = (unsigned char *) mpool_malloc(root->mempool, newspecial->num);
1774
-                    if(!newspecial->str) {
1775
-                        cli_errmsg("cli_ac_addsig: Can't allocate newspecial->str\n");
1776
-                        error = CL_EMEM;
1777
-                        break;
1778
-                    }
1779
-                } else {
1780
-                    newspecial->type = AC_SPECIAL_ALT_STR;
1781
-                }
1782
-
1783
-                for(i = 0; i < newspecial->num; i++) {
1784
-                    unsigned int clen;
1785
-
1786
-                    if(newspecial->num == 1) {
1787
-                        c = (char *) cli_mpool_hex2str(root->mempool, pt);
1788
-                        clen = strlen(pt) / 2;
1789
-                    } else {
1790
-                        if(!(h = cli_strtok(pt, i, "|"))) {
1791
-                            error = CL_EMEM;
1792
-                            break;
1793
-                        }
1794
-
1795
-                        c = (char *) cli_mpool_hex2str(root->mempool, h);
1796
-                        clen = strlen(h) / 2;
1797
-                        free(h);
1798
-                    }
1799
-
1800
-                    if(!c) {
1801
-                        error = CL_EMALFDB;
1802
-                        break;
1803
-                    }
1804
-
1805
-                    if(newspecial->type == AC_SPECIAL_ALT_CHAR) {
1806
-                        newspecial->str[i] = *c;
1807
-                        mpool_free(root->mempool, c);
1808
-                    } else {
1809
-                        if(i) {
1810
-                            specialpt = newspecial;
1811
-                            while(specialpt->next)
1812
-                                specialpt = specialpt->next;
1813
-
1814
-                            specialpt->next = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
1815
-                            if(!specialpt->next) {
1816
-                                cli_errmsg("cli_ac_addsig: Can't allocate specialpt->next\n");
1817
-                                error = CL_EMEM;
1818
-                                free(c);
1819
-                                break;
1820
-                            }
1821
-
1822
-                            specialpt->next->str = (unsigned char *) c;
1823
-                            specialpt->next->len = clen;
1824
-                        } else {
1825
-                            newspecial->str = (unsigned char *) c;
1826
-                            newspecial->len = clen;
1827
-                        }
1828
-                    }
1829
-                }
1830
-
1831
-                if(newspecial->num > 1 && newspecial->type == AC_SPECIAL_ALT_CHAR)
1832
-                    cli_qsort(newspecial->str, newspecial->num, sizeof(unsigned char), qcompare);
1833
-
1834
-                if(error)
1835
-                    break;
1836
-            }
1837
-        }
1838
-
1839
-        if(start)
1840
-            strcat(hexnew, start);
1841
-
1842
-        hex = hexnew;
1843
-        free(hexcpy);
1844
-
1845
-        if(error) {
1846
-            free(hex);
1847
-            if(new->special)
1848
-                mpool_ac_free_special(root->mempool, new);
1849
-
1850
-            mpool_free(root->mempool, new);
1851
-            return error;
1852
-        }
1656
+	    char *hexnew, *start, *h, *c;
1657
+        size_t hexnewsz;
1658
+
1659
+	if(hex) {
1660
+	    hexcpy = hex;
1661
+	} else if(!(hexcpy = cli_strdup(hexsig))) {
1662
+	    mpool_free(root->mempool, new);
1663
+	    return CL_EMEM;
1664
+	}
1665
+
1666
+    hexnewsz = strlen(hexsig) + 1;
1667
+	if(!(hexnew = (char *) cli_calloc(1, hexnewsz))) {
1668
+	    free(new);
1669
+	    free(hexcpy);
1670
+	    return CL_EMEM;
1671
+	}
1672
+
1673
+	start = pt = hexcpy;
1674
+	while((pt = strchr(start, '('))) {
1675
+	    *pt++ = 0;
1676
+
1677
+	    if(!start) {
1678
+		error = CL_EMALFDB;
1679
+		break;
1680
+	    }
1681
+	    newspecial = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
1682
+	    if(!newspecial) {
1683
+		cli_errmsg("cli_ac_addsig: Can't allocate newspecial\n");
1684
+		error = CL_EMEM;
1685
+		break;
1686
+	    }
1687
+	    if(pt >= hexcpy + 2) {
1688
+		if(pt[-2] == '!') {
1689
+		    newspecial->negative = 1;
1690
+		    pt[-2] = 0;
1691
+		}
1692
+	    }
1693
+	    cli_strlcat(hexnew, start, hexnewsz);
1694
+
1695
+	    if(!(start = strchr(pt, ')'))) {
1696
+		mpool_free(root->mempool, newspecial);
1697
+		error = CL_EMALFDB;
1698
+		break;
1699
+	    }
1700
+	    *start++ = 0;
1701
+	    if(!strlen(pt)) {
1702
+		cli_errmsg("cli_ac_addsig: Empty block\n");
1703
+		error = CL_EMALFDB;
1704
+		break;
1705
+	    }
1706
+
1707
+	    if(!strcmp(pt, "B")) {
1708
+		if(!*start) {
1709
+		    new->boundary |= AC_BOUNDARY_RIGHT;
1710
+		    if(newspecial->negative)
1711
+			new->boundary |= AC_BOUNDARY_RIGHT_NEGATIVE;
1712
+		    mpool_free(root->mempool, newspecial);
1713
+		    continue;
1714
+		} else if(pt - 1 == hexcpy) {
1715
+		    new->boundary |= AC_BOUNDARY_LEFT;
1716
+		    if(newspecial->negative)
1717
+			new->boundary |= AC_BOUNDARY_LEFT_NEGATIVE;
1718
+		    mpool_free(root->mempool, newspecial);
1719
+		    continue;
1720
+		}
1721
+	    } else if(!strcmp(pt, "L")) {
1722
+		if(!*start) {
1723
+		    new->boundary |= AC_LINE_MARKER_RIGHT;
1724
+		    if(newspecial->negative)
1725
+			new->boundary |= AC_LINE_MARKER_RIGHT_NEGATIVE;
1726
+		    mpool_free(root->mempool, newspecial);
1727
+		    continue;
1728
+		} else if(pt - 1 == hexcpy) {
1729
+		    new->boundary |= AC_LINE_MARKER_LEFT;
1730
+		    if(newspecial->negative)
1731
+			new->boundary |= AC_LINE_MARKER_LEFT_NEGATIVE;
1732
+		    mpool_free(root->mempool, newspecial);
1733
+		    continue;
1734
+		}
1735
+	    }
1736
+	    cli_strlcat(hexnew, "()", hexnewsz);
1737
+	    new->special++;
1738
+	    newtable = (struct cli_ac_special **) mpool_realloc(root->mempool, new->special_table, new->special * sizeof(struct cli_ac_special *));
1739
+	    if(!newtable) {
1740
+		new->special--;
1741
+		mpool_free(root->mempool, newspecial);
1742
+		cli_errmsg("cli_ac_addsig: Can't realloc new->special_table\n");
1743
+		error = CL_EMEM;
1744
+		break;
1745
+	    }
1746
+	    newtable[new->special - 1] = newspecial;
1747
+	    new->special_table = newtable;
1748
+
1749
+	    if(!strcmp(pt, "B")) {
1750
+		newspecial->type = AC_SPECIAL_BOUNDARY;
1751
+	    } else if(!strcmp(pt, "L")) {
1752
+		newspecial->type = AC_SPECIAL_LINE_MARKER;
1753
+	    /*
1754
+	    } else if(strcmp(pt, "W")) {
1755
+		newspecial->type = AC_SPECIAL_WHITE;
1756
+	    */
1757
+	    } else {
1758
+		newspecial->num = 1;
1759
+		for(i = 0; i < strlen(pt); i++)
1760
+		    if(pt[i] == '|')
1761
+			newspecial->num++;
1762
+
1763
+		if(3 * newspecial->num - 1 == (uint16_t) strlen(pt)) {
1764
+		    newspecial->type = AC_SPECIAL_ALT_CHAR;
1765
+		    newspecial->str = (unsigned char *) mpool_malloc(root->mempool, newspecial->num);
1766
+		    if(!newspecial->str) {
1767
+			cli_errmsg("cli_ac_addsig: Can't allocate newspecial->str\n");
1768
+			error = CL_EMEM;
1769
+			break;
1770
+		    }
1771
+		} else {
1772
+		    newspecial->type = AC_SPECIAL_ALT_STR;
1773
+		}
1774
+
1775
+		for(i = 0; i < newspecial->num; i++) {
1776
+			unsigned int clen;
1777
+
1778
+		    if(newspecial->num == 1) {
1779
+			c = (char *) cli_mpool_hex2str(root->mempool, pt);
1780
+			clen = strlen(pt) / 2;
1781
+		    } else {
1782
+			if(!(h = cli_strtok(pt, i, "|"))) {
1783
+			    error = CL_EMEM;
1784
+			    break;
1785
+			}
1786
+			c = (char *) cli_mpool_hex2str(root->mempool, h);
1787
+			clen = strlen(h) / 2;
1788
+			free(h);
1789
+		    }
1790
+		    if(!c) {
1791
+			error = CL_EMALFDB;
1792
+			break;
1793
+		    }
1794
+
1795
+		    if(newspecial->type == AC_SPECIAL_ALT_CHAR) {
1796
+			newspecial->str[i] = *c;
1797
+			mpool_free(root->mempool, c);
1798
+		    } else {
1799
+			if(i) {
1800
+			    specialpt = newspecial;
1801
+			    while(specialpt->next)
1802
+				specialpt = specialpt->next;
1803
+
1804
+			    specialpt->next = (struct cli_ac_special *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_special));
1805
+			    if(!specialpt->next) {
1806
+				cli_errmsg("cli_ac_addsig: Can't allocate specialpt->next\n");
1807
+				error = CL_EMEM;
1808
+				free(c);
1809
+				break;
1810
+			    }
1811
+			    specialpt->next->str = (unsigned char *) c;
1812
+			    specialpt->next->len = clen;
1813
+			} else {
1814
+			    newspecial->str = (unsigned char *) c;
1815
+			    newspecial->len = clen;
1816
+			}
1817
+		    }
1818
+		}
1819
+		if(newspecial->num > 1 && newspecial->type == AC_SPECIAL_ALT_CHAR)
1820
+		    cli_qsort(newspecial->str, newspecial->num, sizeof(unsigned char), qcompare);
1821
+
1822
+		if(error)
1823
+		    break;
1824
+	    }
1825
+	}
1826
+
1827
+	if(start)
1828
+	    cli_strlcat(hexnew, start, hexnewsz);
1829
+
1830
+	hex = hexnew;
1831
+	free(hexcpy);
1832
+
1833
+	if(error) {
1834
+	    free(hex);
1835
+	    if(new->special) {
1836
+		mpool_ac_free_special(root->mempool, new);
1837
+	    }
1838
+	    mpool_free(root->mempool, new);
1839
+	    return error;
1840
+	}
1853 1841
     }
1854 1842
 
1855 1843
     new->pattern = cli_mpool_hex2ui(root->mempool, hex ? hex : hexsig);
... ...
@@ -697,12 +697,12 @@ parseEmailFile(fmap_t *map, size_t *at, const table_t *rfc821, const char *first
697 697
 						break;
698 698
 					}
699 699
 				} else if(line != NULL) {
700
-					fulllinelength += strlen(line);
700
+					fulllinelength += strlen(line) + 1;
701 701
 					ptr = cli_realloc(fullline, fulllinelength);
702 702
 					if(ptr == NULL)
703 703
 						continue;
704 704
 					fullline = ptr;
705
-					strcat(fullline, line);
705
+					cli_strlcat(fullline, line, fulllinelength);
706 706
 				}
707 707
 
708 708
 				assert(fullline != NULL);
... ...
@@ -902,12 +902,12 @@ parseEmailHeaders(message *m, const table_t *rfc821)
902 902
 					fullline = cli_strdup(line);
903 903
 					fulllinelength = strlen(line) + 1;
904 904
 				} else if(line) {
905
-					fulllinelength += strlen(line);
905
+					fulllinelength += strlen(line) + 1;
906 906
 					ptr = cli_realloc(fullline, fulllinelength);
907 907
 					if(ptr == NULL)
908 908
 						continue;
909 909
 					fullline = ptr;
910
-					strcat(fullline, line);
910
+					cli_strlcat(fullline, line, fulllinelength);
911 911
 				}
912 912
 				assert(fullline != NULL);
913 913
 
... ...
@@ -1456,6 +1456,7 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re
1456 1456
 						 */
1457 1457
 						while(t_line && next_is_folded_header(t_line)) {
1458 1458
 							const char *data;
1459
+                            size_t datasz;
1459 1460
 
1460 1461
 							t_line = t_line->t_next;
1461 1462
 
... ...
@@ -1474,14 +1475,14 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re
1474 1474
 								break;
1475 1475
 							}
1476 1476
 
1477
-							ptr = cli_realloc(fullline,
1478
-								strlen(fullline) + strlen(data) + 1);
1477
+                            datasz = strlen(fullline) + strlen(data) + 1;
1478
+							ptr = cli_realloc(fullline, datasz);
1479 1479
 
1480 1480
 							if(ptr == NULL)
1481 1481
 								break;
1482 1482
 
1483 1483
 							fullline = ptr;
1484
-							strcat(fullline, data);
1484
+							cli_strlcat(fullline, data, datasz);
1485 1485
 
1486 1486
 							/*quotes = count_quotes(data);*/
1487 1487
 						}
... ...
@@ -480,6 +480,7 @@ messageAddArguments(message *m, const char *s)
480 480
 	while(*string) {
481 481
 		const char *key, *cptr;
482 482
 		char *data, *field;
483
+        size_t datasz=0;
483 484
 
484 485
 		if(isspace(*string & 0xff) || (*string == ';')) {
485 486
 			string++;
... ...
@@ -592,12 +593,14 @@ messageAddArguments(message *m, const char *s)
592 592
 
593 593
 			*ptr = '\0';
594 594
 
595
+            datasz = strlen(kcopy) + strlen(data) + 2;
595 596
 			field = cli_realloc(kcopy, strlen(kcopy) + strlen(data) + 2);
596 597
 			if(field) {
597
-				strcat(field, "=");
598
-				strcat(field, data);
599
-			} else
598
+                cli_strlcat(field, "=", datasz);
599
+                cli_strlcat(field, data, datasz);
600
+			} else {
600 601
 				free(kcopy);
602
+            }
601 603
 			free(data);
602 604
 		} else {
603 605
 			size_t len;
... ...
@@ -827,7 +827,9 @@ int unmew11(char *src, int off, int ssize, int dsize, uint32_t base, uint32_t va
827 827
 
828 828
 		if (!uselzma)
829 829
 		{
830
-			uint32_t val = PESALIGN(f2 - src, 0x1000);
830
+			/* bb#11212 - DO NOT PEALIGN sections to cli_rebuildpe() *
831
+			 * data processed in src buffer is stored NOT pe-aligned */
832
+			uint32_t val = f2 - src;
831 833
 			void *newsect;
832 834
 
833 835
 			if (i && val < section[i].raw) {
... ...
@@ -889,7 +891,7 @@ int unmew11(char *src, int off, int ssize, int dsize, uint32_t base, uint32_t va
889 889
 		section[0].raw = 0; section[0].rva = vadd;
890 890
 		section[0].rsz = section[0].vsz = dsize;
891 891
 	}
892
-	if (!cli_rebuildpe(src, section, i, base, entry_point - base, 0, 0, filedesc))
892
+	if (!cli_rebuildpe_align(src, section, i, base, entry_point - base, 0, 0, filedesc, 0x1000))
893 893
 	{
894 894
 		cli_dbgmsg("MEW: Rebuilding failed\n");
895 895
 		free(section);
... ...
@@ -358,22 +358,21 @@ print_ole2_header(ole2_header_t * hdr)
358 358
     if (!hdr || !cli_debug_flag) {
359 359
         return;
360 360
     }
361
-    cli_dbgmsg("\nMagic:\t\t\t0x");
362
-    for (i = 0; i < 8; i++) {
363
-        cli_dbgmsg("%x", hdr->magic[i]);
364
-    }
365 361
     cli_dbgmsg("\n");
362
+    cli_dbgmsg("Magic:\t\t\t0x%x%x%x%x%x%x%x%x\n",
363
+               hdr->magic[0], hdr->magic[1], hdr->magic[2], hdr->magic[3],
364
+               hdr->magic[4], hdr->magic[5], hdr->magic[6], hdr->magic[7]);
366 365
 
367
-    cli_dbgmsg("CLSID:\t\t\t{");
368
-    for (i = 0; i < 16; i++) {
369
-        cli_dbgmsg("%x ", hdr->clsid[i]);
370
-    }
371
-    cli_dbgmsg("}\n");
366
+    cli_dbgmsg("CLSID:\t\t\t{%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x}\n",
367
+               hdr->clsid[0],  hdr->clsid[1],  hdr->clsid[2],  hdr->clsid[3],
368
+               hdr->clsid[4],  hdr->clsid[5],  hdr->clsid[6],  hdr->clsid[7],
369
+               hdr->clsid[8],  hdr->clsid[9],  hdr->clsid[10], hdr->clsid[11],
370
+               hdr->clsid[12], hdr->clsid[13], hdr->clsid[14], hdr->clsid[15]);
372 371
 
373 372
     cli_dbgmsg("Minor version:\t\t0x%x\n", hdr->minor_version);
374 373
     cli_dbgmsg("DLL version:\t\t0x%x\n", hdr->dll_version);
375 374
     cli_dbgmsg("Byte Order:\t\t%d\n", hdr->byte_order);
376
-    cli_dbgmsg("Big Block Size:\t\t%i\n", hdr->log2_big_block_size);
375
+    cli_dbgmsg("Big Block Size:\t%i\n", hdr->log2_big_block_size);
377 376
     cli_dbgmsg("Small Block Size:\t%i\n", hdr->log2_small_block_size);
378 377
     cli_dbgmsg("BAT count:\t\t%d\n", hdr->bat_count);
379 378
     cli_dbgmsg("Prop start:\t\t%d\n", hdr->prop_start);
... ...
@@ -381,7 +380,8 @@ print_ole2_header(ole2_header_t * hdr)
381 381
     cli_dbgmsg("SBat start:\t\t%d\n", hdr->sbat_start);
382 382
     cli_dbgmsg("SBat block count:\t%d\n", hdr->sbat_block_count);
383 383
     cli_dbgmsg("XBat start:\t\t%d\n", hdr->xbat_start);
384
-    cli_dbgmsg("XBat block count:\t%d\n\n", hdr->xbat_count);
384
+    cli_dbgmsg("XBat block count:\t%d\n", hdr->xbat_count);
385
+    cli_dbgmsg("\n");
385 386
     return;
386 387
 }
387 388
 
... ...
@@ -1240,7 +1240,8 @@ int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj, uint32_t flags)
1240 1240
         }
1241 1241
     } while (0);
1242 1242
 
1243
-    cli_dbgmsg("cli_pdf: extracted %ld bytes %u %u obj to %s\n", sum, obj->id>>8, obj->id&0xff, fullname);
1243
+    cli_dbgmsg("cli_pdf: extracted %ld bytes %u %u obj\n", sum, obj->id>>8, obj->id&0xff);
1244
+    cli_dbgmsg("         ... to %s\n", fullname);
1244 1245
 
1245 1246
     if (flags & PDF_EXTRACT_OBJ_SCAN && sum) {
1246 1247
         int rc2;
... ...
@@ -76,7 +76,7 @@ char *pdf_convert_utf(char *begin, size_t sz)
76 76
     char *res=NULL;
77 77
 #if HAVE_ICONV
78 78
     char *buf, *outbuf, *p1, *p2;
79
-    size_t inlen, outlen, i;
79
+    size_t sz2, inlen, outlen, i;
80 80
     char *encodings[] = {
81 81
         "UTF-16",
82 82
         NULL
... ...
@@ -87,10 +87,63 @@ char *pdf_convert_utf(char *begin, size_t sz)
87 87
     if (!(buf))
88 88
         return NULL;
89 89
 
90
-    memcpy(buf, begin, sz);
90
+    /* convert PDF specific escape sequences, like octal sequences */
91
+    sz2 = 0;
92
+    for (i = 0; i < sz; ++i) {
93
+        if ((i+1 < sz) && begin[i] == '\\') {
94
+            if ((i+3 < sz) &&
95
+                (isdigit(begin[i+1]) && isdigit(begin[i+2]) && isdigit(begin[i+3]))) {
96
+                /* octal sequence */
97
+                char octal[4], *check;
98
+                unsigned long value;
99
+
100
+                memcpy(octal, &begin[i+1], 3);
101
+                octal[3] = '\0';
102
+
103
+                value = (char)strtoul(octal, &check, 8);
104
+                /* check if all characters were converted */
105
+                if (check == &octal[3])
106
+                    buf[sz2++] = value;
107
+                i += 3;
108
+            } else {
109
+                /* other sequences */
110
+                switch(begin[i+1]) {
111
+                case 'n':
112
+                    buf[sz2++] = 0x0a;
113
+                    break;
114
+                case 'r':
115
+                    buf[sz2++] = 0x0d;
116
+                    break;
117
+                case 't':
118
+                    buf[sz2++] = 0x09;
119
+                    break;
120
+                case 'b':
121
+                    buf[sz2++] = 0x08;
122
+                    break;
123
+                case 'f':
124
+                    buf[sz2++] = 0x0c;
125
+                    break;
126
+                case '(':
127
+                    buf[sz2++] = 0x28;
128
+                    break;
129
+                case ')':
130
+                    buf[sz2++] = 0x29;
131
+                    break;
132
+                case '\\':
133
+                    buf[sz2++] = 0x5c;
134
+                    break;
135
+                default:
136
+                    /* IGNORE THE REVERSE SOLIDUS - PDF3000-2008 */
137
+                    break;
138
+                }
139
+            }
140
+        } else
141
+            buf[sz2++] = begin[i]; 
142
+    }
143
+    //memcpy(buf, begin, sz);
91 144
     p1 = buf;
92 145
 
93
-    p2 = outbuf = cli_calloc(1, sz+1);
146
+    p2 = outbuf = cli_calloc(1, sz2+1);
94 147
     if (!(outbuf)) {
95 148
         free(buf);
96 149
         return NULL;
... ...
@@ -99,7 +152,7 @@ char *pdf_convert_utf(char *begin, size_t sz)
99 99
     for (i=0; encodings[i] != NULL; i++) {
100 100
         p1 = buf;
101 101
         p2 = outbuf;
102
-        inlen = outlen = sz;
102
+        inlen = outlen = sz2;
103 103
 
104 104
         cd = iconv_open("UTF-8", encodings[i]);
105 105
         if (cd == (iconv_t)(-1)) {
... ...
@@ -109,13 +162,13 @@ char *pdf_convert_utf(char *begin, size_t sz)
109 109
 
110 110
         iconv(cd, (char **)(&p1), &inlen, &p2, &outlen);
111 111
 
112
-        if (outlen == sz) {
112
+        if (outlen == sz2) {
113 113
             /* Decoding unsuccessful right from the start */
114 114
             iconv_close(cd);
115 115
             continue;
116 116
         }
117 117
 
118
-        outbuf[sz - outlen] = '\0';
118
+        outbuf[sz2 - outlen] = '\0';
119 119
 
120 120
         res = strdup(outbuf);
121 121
         iconv_close(cd);
... ...
@@ -277,10 +330,11 @@ char *pdf_parse_string(struct pdf_struct *pdf, struct pdf_obj *obj, const char *
277 277
     p2 = (char *)(q + objsize);
278 278
     if (is_object_reference(p1, &p2, &objid)) {
279 279
         struct pdf_obj *newobj;
280
-        char *begin;
280
+        char *begin, *p3;
281 281
         STATBUF sb;
282 282
         uint32_t objflags;
283 283
         int fd;
284
+        size_t objsize2;
284 285
 
285 286
         newobj = find_obj(pdf, obj, objid);
286 287
         if (!(newobj))
... ...
@@ -343,25 +397,32 @@ char *pdf_parse_string(struct pdf_struct *pdf, struct pdf_obj *obj, const char *
343 343
                 return NULL;
344 344
             }
345 345
 
346
-            switch (begin[0]) {
346
+            p3 = begin;
347
+            objsize2 = sb.st_size;
348
+            while ((size_t)(p3 - begin) < objsize2 && isspace(p3[0])) {
349
+                p3++;
350
+                objsize2--;
351
+            }
352
+
353
+            switch (*p3) {
347 354
                 case '(':
348 355
                 case '<':
349
-                    res = pdf_parse_string(pdf, obj, begin, sb.st_size, NULL, NULL);
356
+                    res = pdf_parse_string(pdf, obj, p3, objsize2, NULL, NULL);
350 357
                     free(begin);
351 358
                     break;
352 359
                 default:
353
-                    for (i=0; i < sb.st_size; i++) {
354
-                        if (begin[i] >= 0x7f) {
360
+                    for (i=0; i < objsize2; i++) {
361
+                        if (p3[i] >= 0x7f) {
355 362
                             likelyutf=1;
356 363
                             break;
357 364
                         }
358 365
                     }
359 366
 
360
-                    res = likelyutf ? pdf_convert_utf(begin, sb.st_size) : NULL;
367
+                    res = likelyutf ? pdf_convert_utf(p3, objsize2) : NULL;
361 368
 
362 369
                     if (!(res)) {
363 370
                         res = begin;
364
-                        res[sb.st_size] = '\0';
371
+                        res[objsize2] = '\0';
365 372
                     } else {
366 373
                         free(begin);
367 374
                     }
... ...
@@ -2570,9 +2570,26 @@ int cli_scanpe(cli_ctx *ctx)
2570 2570
             cli_jsonstr(pe_json, "Packer", "yC");
2571 2571
 #endif
2572 2572
 
2573
-            cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
2574
-            CLI_UNPTEMP("yC",(spinned,exe_sections,0));
2575
-            CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
2573
+            do {
2574
+                unsigned int yc_unp_num_viruses = ctx->num_viruses;
2575
+                const char *yc_unp_virname = NULL;
2576
+
2577
+                if (ctx->virname)
2578
+                    yc_unp_virname = ctx->virname[0];
2579
+
2580
+                cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
2581
+                CLI_UNPTEMP("yC",(spinned,exe_sections,0));
2582
+                CLI_UNPRESULTS("yC",(yc_decrypt(ctx, spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
2583
+
2584
+                if (SCAN_ALL && yc_unp_num_viruses != ctx->num_viruses) {
2585
+                    free(exe_sections);
2586
+                    return CL_VIRUS;
2587
+                }
2588
+                else if (ctx->virname && yc_unp_virname != ctx->virname[0]) {
2589
+                    free(exe_sections);
2590
+                    return CL_VIRUS;
2591
+                }
2592
+            } while(0);
2576 2593
         }
2577 2594
     }
2578 2595
 
... ...
@@ -108,7 +108,8 @@ int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli
108 108
   while (1) {
109 109
     char *ssrc, *ddst;
110 110
     uint32_t size, srva;
111
-    int backbytes, oldback, backsize, addsize;
111
+    int backbytes, oldback, addsize;
112
+    unsigned int backsize;
112 113
     
113 114
     if ( ! CLI_ISCONTAINED(buf, bufsz, packed, 4)) {
114 115
       if (usects)
... ...
@@ -124,6 +124,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
124 124
     int ret, asterisk = 0, range;
125 125
     unsigned int i, j, hexlen, parts = 0;
126 126
     int mindist = 0, maxdist = 0, error = 0;
127
+    size_t hexcpysz;
127 128
 
128 129
     hexlen = strlen(hexsig);
129 130
     if (hexsig[0] == '$') {
... ...
@@ -121,6 +121,11 @@ struct IMAGE_PE_HEADER {
121 121
 
122 122
 int cli_rebuildpe(char *buffer, struct cli_exe_section *sections, int sects, uint32_t base, uint32_t ep, uint32_t ResRva, uint32_t ResSize, int file)
123 123
 {
124
+  return cli_rebuildpe_align(buffer, sections, sects, base, ep, ResRva, ResSize, file, 0);
125
+}
126
+
127
+int cli_rebuildpe_align(char *buffer, struct cli_exe_section *sections, int sects, uint32_t base, uint32_t ep, uint32_t ResRva, uint32_t ResSize, int file, uint32_t align)
128
+{
124 129
   uint32_t datasize=0, rawbase=PESALIGN(0x148+0x80+0x28*sects, 0x200);
125 130
   char *pefile=NULL, *curpe;
126 131
   struct IMAGE_PE_HEADER *fakepe;
... ...
@@ -131,8 +136,12 @@ int cli_rebuildpe(char *buffer, struct cli_exe_section *sections, int sects, uin
131 131
   if(sects+gotghost > 96)
132 132
     return 0;
133 133
 
134
-  for (i=0; i < sects; i++)
135
-    datasize+=PESALIGN(sections[i].rsz, 0x200);
134
+  if (!align)
135
+    for (i=0; i < sects; i++)
136
+      datasize+=PESALIGN(sections[i].rsz, 0x200);
137
+  else
138
+    for (i=0; i < sects; i++)
139
+      datasize+=PESALIGN(PESALIGN(sections[i].rsz, align), 0x200);
136 140
 
137 141
   if(datasize > CLI_MAX_ALLOCATION)
138 142
     return 0;
... ...
@@ -163,10 +172,17 @@ int cli_rebuildpe(char *buffer, struct cli_exe_section *sections, int sects, uin
163 163
 
164 164
     for (i=0; i < sects; i++) {
165 165
       snprintf(curpe, 8, ".clam%.2d", i+1);
166
-      cli_writeint32(curpe+8, sections[i].vsz);
167
-      cli_writeint32(curpe+12, sections[i].rva);
168
-      cli_writeint32(curpe+16, sections[i].rsz);
169
-      cli_writeint32(curpe+20, rawbase);
166
+      if (!align) {
167
+        cli_writeint32(curpe+8, sections[i].vsz);
168
+        cli_writeint32(curpe+12, sections[i].rva);
169
+        cli_writeint32(curpe+16, sections[i].rsz);
170
+        cli_writeint32(curpe+20, rawbase);
171
+      } else {
172
+        cli_writeint32(curpe+8, PESALIGN(sections[i].vsz, align));
173
+        cli_writeint32(curpe+12, PESALIGN(sections[i].rva, align));
174
+        cli_writeint32(curpe+16, PESALIGN(sections[i].rsz, align));
175
+        cli_writeint32(curpe+20, rawbase);
176
+      }
170 177
       /* already zeroed
171 178
       cli_writeint32(curpe+24, 0);
172 179
       cli_writeint32(curpe+28, 0);
... ...
@@ -174,9 +190,14 @@ int cli_rebuildpe(char *buffer, struct cli_exe_section *sections, int sects, uin
174 174
       */
175 175
       cli_writeint32(curpe+0x24, 0xffffffff);
176 176
       memcpy(pefile+rawbase, buffer+sections[i].raw, sections[i].rsz);
177
-      rawbase+=PESALIGN(sections[i].rsz, 0x200);
178 177
       curpe+=40;
179
-      datasize+=PESALIGN(sections[i].vsz, 0x1000);
178
+      if (!align) {
179
+        rawbase+=PESALIGN(sections[i].rsz, 0x200);
180
+        datasize+=PESALIGN(sections[i].vsz, 0x1000);
181
+      } else {
182
+        rawbase+=PESALIGN(PESALIGN(sections[i].rsz, align), 0x200);
183
+        datasize+=PESALIGN(PESALIGN(sections[i].vsz, align), 0x1000);
184
+      }
180 185
     }
181 186
     fakepe->SizeOfImage = EC32(datasize);
182 187
   } else {
... ...
@@ -25,5 +25,6 @@
25 25
 #include "execs.h"
26 26
 
27 27
 int cli_rebuildpe(char *, struct cli_exe_section *, int, uint32_t, uint32_t, uint32_t, uint32_t, int);
28
+int cli_rebuildpe_align(char *, struct cli_exe_section *, int, uint32_t, uint32_t, uint32_t, uint32_t, int, uint32_t);
28 29
 
29 30
 #endif
... ...
@@ -16,6 +16,10 @@
16 16
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 17
  */
18 18
 
19
+#if HAVE_CONFIG_H
20
+#include "clamav-config.h"
21
+#endif
22
+
19 23
 #include <sys/types.h>
20 24
 #include <string.h>
21 25
 
... ...
@@ -28,6 +32,9 @@
28 28
 size_t
29 29
 cli_strlcpy(char *dst, const char *src, size_t siz)
30 30
 {
31
+#if HAVE_STRLCPY
32
+    return strlcpy(dst, src, siz);
33
+#else
31 34
 	char *d = dst;
32 35
 	const char *s = src;
33 36
 	size_t n = siz;
... ...
@@ -49,4 +56,5 @@ cli_strlcpy(char *dst, const char *src, size_t siz)
49 49
 	}
50 50
 
51 51
 	return(s - src - 1);	/* count does not include NUL */
52
+#endif
52 53
 }
... ...
@@ -2514,7 +2514,9 @@ static int dispatch_prescan(clcb_pre_scan cb, cli_ctx *ctx, const char *filetype
2514 2514
             cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n");
2515 2515
             perf_stop(ctx, PERFT_PRECB);
2516 2516
             ctx->hook_lsig_matches = old_hook_lsig_matches;
2517
+            /* returns CL_CLEAN */
2517 2518
             *run_cleanup = 1;
2519
+            break;
2518 2520
         case CL_VIRUS:
2519 2521
             cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n");
2520 2522
             cli_append_virus(ctx, "Detected.By.Callback");
... ...
@@ -2522,6 +2524,7 @@ static int dispatch_prescan(clcb_pre_scan cb, cli_ctx *ctx, const char *filetype
2522 2522
             ctx->hook_lsig_matches = old_hook_lsig_matches;
2523 2523
             *run_cleanup = 1;
2524 2524
             res = CL_VIRUS;
2525
+            break;
2525 2526
         case CL_CLEAN:
2526 2527
             break;
2527 2528
         default:
... ...
@@ -3073,7 +3076,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
3073 3073
 		    cli_dbgmsg("Descriptor[%d]: cli_scanraw error %s\n", fmap_fd(*ctx->fmap), cl_strerror(res));
3074 3074
 		    cli_bitset_free(ctx->hook_lsig_matches);
3075 3075
 		    ctx->hook_lsig_matches = old_hook_lsig_matches;
3076
-            return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
3076
+            return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, res, parent_property);
3077 3077
 		/* CL_VIRUS = malware found, check FP and report */
3078 3078
 		case CL_VIRUS:
3079 3079
 		    ret = cli_checkfp(hash, hashed_size, ctx);
... ...
@@ -3463,8 +3466,8 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned
3463 3463
         else {
3464 3464
             int ret = CL_SUCCESS;
3465 3465
             cli_dbgmsg("%s\n", jstring);
3466
- 
3467
-           /* Scan the json string unless a virus was detected */ 
3466
+
3467
+           /* Scan the json string unless a virus was detected */
3468 3468
             if (rc != CL_VIRUS) {
3469 3469
                 ctx.options &= ~CL_SCAN_FILE_PROPERTIES;
3470 3470
                 rc = cli_mem_scandesc(jstring, strlen(jstring), &ctx);
... ...
@@ -58,4 +58,5 @@ typedef enum {
58 58
 } utf16_type;
59 59
 char *cli_utf16_to_utf8(const char *utf16, size_t length, utf16_type type);
60 60
 
61
+size_t cli_strlcat(char *dst, const char *src, size_t sz); /* libclamav/strlcat.c */
61 62
 #endif
62 63
new file mode 100644
... ...
@@ -0,0 +1,67 @@
0
+/*	$OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $	*/
1
+
2
+/*
3
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+
18
+/*
19
+ * Taken from HardenedBSD's strlcat.c, which was taken from OpenBSD.
20
+ */
21
+
22
+#if HAVE_CONFIG_H
23
+#include "clamav-config.h"
24
+#endif
25
+
26
+#include <sys/types.h>
27
+#include <string.h>
28
+
29
+/*
30
+ * Appends src to string dst of size siz (unlike strncat, siz is the
31
+ * full size of dst, not space left).  At most siz-1 characters
32
+ * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
33
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
34
+ * If retval >= siz, truncation occurred.
35
+ */
36
+size_t
37
+cli_strlcat(char *dst, const char *src, size_t siz)
38
+{
39
+#if HAVE_STRLCAT
40
+    return strlcat(dst, src, siz);
41
+#else
42
+	char *d = dst;
43
+	const char *s = src;
44
+	size_t n = siz;
45
+	size_t dlen;
46
+
47
+	/* Find the end of dst and adjust bytes left but don't go past end */
48
+	while (n-- != 0 && *d != '\0')
49
+		d++;
50
+	dlen = d - dst;
51
+	n = siz - dlen;
52
+
53
+	if (n == 0)
54
+		return(dlen + strlen(s));
55
+	while (*s != '\0') {
56
+		if (n != 1) {
57
+			*d++ = *s;
58
+			n--;
59
+		}
60
+		s++;
61
+	}
62
+	*d = '\0';
63
+
64
+	return(dlen + (s - src));	/* count does not include NUL */
65
+#endif
66
+}
... ...
@@ -213,12 +213,17 @@ int unupack(int upack, char *dest, uint32_t dsize, char *buff, uint32_t vma, uin
213 213
 			loc_edi = dest+vma-base; /* XXX not enough samples provided to be sure of it! */
214 214
 
215 215
 		pushed_esi = loc_edi;
216
-		end_edi = dest + cli_readint32(loc_esi + 0x34) - vma;
217 216
 		if (upack_version == UPACK_0297729)
218 217
 		{
219 218
 			end_edi = dest + cli_readint32(loc_esi + 0x64) - vma;
220 219
 			save3 = cli_readint32(loc_esi + 0x40);
221
-		}
220
+		} else {
221
+                        end_edi = dest + cli_readint32(loc_esi + 0x34) - vma;
222
+                }
223
+                if (loc_edi > end_edi) {
224
+                        cli_dbgmsg("Upack: loc_edi > end_edi breaks cli_rebuildpe() bb#11216\n");
225
+                        return -1;
226
+                }
222 227
 		/* begin end */
223 228
 		cli_dbgmsg("Upack: data initialized, before upack lzma call!\n");
224 229
 		if ((ret = (uint32_t)unupack399(dest, dsize, 0, loc_ebx, 0, loc_edi, end_edi, shlsize, paddr)) == 0xffffffff)
... ...
@@ -376,6 +381,10 @@ int unupack(int upack, char *dest, uint32_t dsize, char *buff, uint32_t vma, uin
376 376
 			end_edi = dest + cli_readint32(loc_esi-0x28) - base; /* read checked above */
377 377
 			loc_esi = save_edi;
378 378
 		}
379
+                if (loc_edi > end_edi) {
380
+                        cli_dbgmsg("Upack(alt begin): loc_edi > end_edi breaks cli_rebuildpe() bb#11216\n");
381
+                        return -1;
382
+                }
379 383
 		cli_dbgmsg("Upack: data initialized, before upack lzma call!\n");
380 384
 		if ((ret = (uint32_t)unupack399(dest, dsize, loc_ecx, loc_ebx, loc_ecx, loc_edi, end_edi, shlsize, paddr)) == 0xffffffff)
381 385
 			return -1;
... ...
@@ -222,6 +222,10 @@ static int pefromupx (const char *src, uint32_t ssize, char *dst, uint32_t *dsiz
222 222
     cli_writeint32(sections+12, urva);
223 223
     cli_writeint32(sections+16, vsize);
224 224
     cli_writeint32(sections+20, foffset);
225
+    if (foffset + vsize < foffset) {
226
+        /* Integer overflow */
227
+        return 0;
228
+    }
225 229
     foffset+=vsize;
226 230
     
227 231
     sections+=0x28;
... ...
@@ -239,7 +243,20 @@ static int pefromupx (const char *src, uint32_t ssize, char *dst, uint32_t *dsiz
239 239
   memcpy(newbuf+0xd0, pehdr,0xf8+0x28*sectcnt);
240 240
   sections = pehdr+0xf8;
241 241
   for (upd = 0; upd <sectcnt ; upd++) {
242
-    memcpy(newbuf+cli_readint32(sections+20), dst+cli_readint32(sections+12)-upx0, cli_readint32(sections+16));
242
+      uint32_t offset1, offset2, offset3;
243
+      offset1 = (uint32_t)cli_readint32(sections+20);
244
+      offset2 = (uint32_t)cli_readint32(sections+16);
245
+      if (offset1 > foffset || offset2 > foffset || offset1 + offset2 > foffset) {
246
+          free(newbuf);
247
+          return 1;
248
+      }
249
+
250
+      offset3 = (uint32_t)cli_readint32(sections+12);
251
+      if (offset3-upx0 > *dsize) {
252
+          free(newbuf);
253
+          return 1;
254
+      }
255
+    memcpy(newbuf+offset1, dst+offset3-upx0, offset2);
243 256
     sections+=0x28;
244 257
   }
245 258
 
... ...
@@ -39,10 +39,26 @@
39 39
 
40 40
 #define EC16(x) le16_to_host(x) /* Convert little endian to host */
41 41
 
42
+#define DO_HEURISTIC 1
43
+
44
+static int yc_bounds_check(cli_ctx *ctx, char *base, unsigned int filesize, char *offset, unsigned int bound)
45
+{
46
+      if ((unsigned int)((offset+bound)-base) > filesize) {
47
+          cli_dbgmsg("yC: Bounds check assertion.\n");
48
+#if DO_HEURISTIC
49
+          cli_append_virus(ctx, "Heuristics.BoundsCheck");
50
+#endif
51
+          return 1;
52
+      }
53
+
54
+      return 0;
55
+}
56
+
57
+
42 58
 /* ========================================================================== */
43 59
 /* "Emulates" the poly decryptors */
44 60
 
45
-static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx, uint32_t max_emu)
61
+static int yc_poly_emulator(cli_ctx *ctx, char *base, unsigned int filesize, char* decryptor_offset, char* code, unsigned int ecx, uint32_t max_emu)
46 62
 {
47 63
 
48 64
   /* 
... ...
@@ -68,15 +84,25 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx
68 68
 
69 69
   for(i=0;i<ecx&&i<max_emu;i++) /* Byte looper - Decrypts every byte and write it back */
70 70
     {
71
+        if (yc_bounds_check(ctx, base, filesize, code, i)) {
72
+            return 2;
73
+        }
71 74
       al = code[i];
72 75
 
73 76
       for(j=0;j<0x30;j++)   /* Poly Decryptor "Emulator" */
74 77
 	{
78
+        if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
79
+            return 2;
80
+        }
81
+
75 82
 	  switch(decryptor_offset[j])
76 83
 	    {
77 84
 
78 85
 	    case '\xEB':	/* JMP short */
79 86
 	      j++;
87
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
88
+                return 2;
89
+            }
80 90
 	      j = j + decryptor_offset[j];
81 91
 	      break;
82 92
 
... ...
@@ -102,36 +128,57 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx
102 102
 	      ;
103 103
 	    case '\x04':	/* ADD AL,num */
104 104
 	      j++;
105
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
106
+                return 2;
107
+            }
105 108
 	      al = al + decryptor_offset[j];
106 109
 	      break;
107 110
 	      ;
108 111
 	    case '\x34':	/* XOR AL,num */
109 112
 	      j++;
113
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
114
+                return 2;
115
+            }
110 116
 	      al = al ^ decryptor_offset[j];
111 117
 	      break;
112 118
 
113 119
 	    case '\x2C':	/* SUB AL,num */
114 120
 	      j++;
121
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
122
+                return 2;
123
+            }
115 124
 	      al = al - decryptor_offset[j];
116 125
 	      break;
117 126
 
118 127
 			
119 128
 	    case '\xC0':
120 129
 	      j++;
130
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
131
+                return 2;
132
+            }
121 133
 	      if(decryptor_offset[j]=='\xC0') /* ROL AL,num */
122 134
 		{
123 135
 		  j++;
136
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
137
+                return 2;
138
+            }
124 139
 		  CLI_ROL(al,decryptor_offset[j]);
125 140
 		}
126 141
 	      else			/* ROR AL,num */
127 142
 		{
128 143
 		  j++;
144
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
145
+                return 2;
146
+            }
129 147
 		  CLI_ROR(al,decryptor_offset[j]);
130 148
 		}
131 149
 	      break;
132 150
 
133 151
 	    case '\xD2':
134 152
 	      j++;
153
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
154
+                return 2;
155
+            }
135 156
 	      if(decryptor_offset[j]=='\xC8') /* ROR AL,CL */
136 157
 		{
137 158
 		  j++;
... ...
@@ -150,11 +197,16 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx
150 150
 	      break;
151 151
 
152 152
 	    default:
153
+            if (yc_bounds_check(ctx, base, filesize, decryptor_offset, j)) {
154
+                return 2;
155
+            }
153 156
 	      cli_dbgmsg("yC: Unhandled opcode %x\n", (unsigned char)decryptor_offset[j]);
154 157
 	      return 1;
155 158
 	    }
156 159
 	}
157 160
       cl--;
161
+            if (yc_bounds_check(ctx, base, filesize, code, i))
162
+                return 2;
158 163
       code[i] = al;
159 164
     }
160 165
   return 0;
... ...
@@ -165,12 +217,13 @@ static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx
165 165
 /* ========================================================================== */
166 166
 /* Main routine which calls all others */
167 167
 
168
-int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sections, unsigned int sectcount, uint32_t peoffset, int desc, uint32_t ecx,int16_t offset) {
168
+int yc_decrypt(cli_ctx *ctx, char *fbuf, unsigned int filesize, struct cli_exe_section *sections, unsigned int sectcount, uint32_t peoffset, int desc, uint32_t ecx,int16_t offset) {
169 169
   uint32_t ycsect = sections[sectcount].raw+offset;
170 170
   unsigned int i;
171 171
   struct pe_image_file_hdr *pe = (struct pe_image_file_hdr*) (fbuf + peoffset);
172 172
   char *sname = (char *)pe + EC16(pe->SizeOfOptionalHeader) + 0x18;
173 173
   uint32_t max_emu;
174
+  unsigned int ofilesize = filesize;
174 175
   /* 
175 176
 
176 177
   First layer (decryptor of the section decryptor) in last section 
... ...
@@ -182,8 +235,12 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sectio
182 182
   */
183 183
   cli_dbgmsg("yC: offset: %x, length: %x\n", offset, ecx);
184 184
   cli_dbgmsg("yC: decrypting decryptor on sect %d\n", sectcount);
185
-  if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx, ecx))
186
-    return 1;
185
+  switch (yc_poly_emulator(ctx, fbuf, filesize, fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx, ecx)) {
186
+  case 2:
187
+      return CL_VIRUS;
188
+  case 1:
189
+      return CL_EUNPACK;
190
+  }
187 191
   filesize-=sections[sectcount].ursz;
188 192
 
189 193
   /* 
... ...
@@ -218,11 +275,15 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sectio
218 218
       cli_dbgmsg("yC: bad emulation length limit %u\n", max_emu);
219 219
       return 1;
220 220
     }
221
-    if (yc_poly_emulator(fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), 
221
+    switch (yc_poly_emulator(ctx, fbuf, ofilesize, fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), 
222 222
 			 fbuf + sections[i].raw, 
223 223
 			 sections[i].ursz, 
224
-			 max_emu))
225
-      return 1;
224
+			 max_emu)) {
225
+    case 2:
226
+        return CL_VIRUS;
227
+    case 1:
228
+        return CL_EUNPACK;
229
+    }
226 230
   }
227 231
 
228 232
   /* Remove yC section */
... ...
@@ -240,7 +301,7 @@ int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sectio
240 240
 
241 241
   if (cli_writen(desc, fbuf, filesize)==-1) {
242 242
     cli_dbgmsg("yC: Cannot write unpacked file\n");
243
-    return 1;
243
+    return CL_EUNPACK;
244 244
   }
245
-  return 0;
245
+  return CL_SUCCESS;
246 246
 }
... ...
@@ -25,6 +25,6 @@
25 25
 #include "execs.h"
26 26
 #include "cltypes.h"
27 27
 
28
-int yc_decrypt(char *, unsigned int, struct cli_exe_section *, unsigned int, uint32_t, int,uint32_t,int16_t);
28
+int yc_decrypt(cli_ctx *, char *, unsigned int, struct cli_exe_section *, unsigned int, uint32_t, int,uint32_t,int16_t);
29 29
 
30 30
 #endif
... ...
@@ -573,8 +573,8 @@ AC_DEFUN([AM_MAINTAINER_MODE],
573 573
 [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
574 574
   dnl maintainer-mode is disabled by default
575 575
   AC_ARG_ENABLE(maintainer-mode,
576
-[  --enable-maintainer-mode enable make rules and dependencies not useful
577
-                          (and sometimes confusing) to the casual installer],
576
+[AS_HELP_STRING([--enable-maintainer-mode], [make rules and dependencies not useful
577
+                                            (and sometimes confusing) to the casual installer])],
578 578
       USE_MAINTAINER_MODE=$enableval,
579 579
       USE_MAINTAINER_MODE=no)
580 580
   AC_MSG_RESULT($USE_MAINTAINER_MODE)
... ...
@@ -181,7 +181,7 @@ return 0;
181 181
 if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then
182 182
     dnl Check whether FD passing works <edwin@clamav.net>
183 183
     AC_MSG_CHECKING([BSD 4.4 / RFC2292 style fd passing])
184
-    AC_ARG_ENABLE([fdpassing],[  --disable-fdpassing        don't build file descriptor passing support],
184
+    AC_ARG_ENABLE([fdpassing],[AS_HELP_STRING([--disable-fdpassing], [do not build file descriptor passing support])],
185 185
         want_fdpassing=$enableval, want_fdpassing="yes")
186 186
 
187 187
     if test "x$want_fdpassing" = "xyes"; then
... ...
@@ -24,7 +24,7 @@ with_gnu_ld=$acl_cv_prog_gnu_ld
24 24
 dnl From libtool-1.4. Sets the variable LD.
25 25
 AC_DEFUN([AC_LIB_PROG_LD],
26 26
 [AC_ARG_WITH(gnu-ld,
27
-[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
27
+[AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])],
28 28
 test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
29 29
 AC_REQUIRE([AC_PROG_CC])dnl
30 30
 AC_REQUIRE([AC_CANONICAL_HOST])dnl
... ...
@@ -132,7 +132,7 @@ AC_DEFUN([AC_LIB_RPATH],
132 132
   acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
133 133
   dnl Determine whether the user wants rpath handling at all.
134 134
   AC_ARG_ENABLE(rpath,
135
-    [  --disable-rpath         do not hardcode runtime library paths],
135
+    [AS_HELP_STRING([--disable-rpath], [do not hardcode runtime library paths])],
136 136
     :, enable_rpath=yes)
137 137
 ])
138 138
 
... ...
@@ -1225,8 +1225,8 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
1225 1225
 AC_DEFUN([_LT_WITH_SYSROOT],
1226 1226
 [AC_MSG_CHECKING([for sysroot])
1227 1227
 AC_ARG_WITH([sysroot],
1228
-[  --with-sysroot[=DIR] Search for dependent libraries within DIR
1229
-                        (or the compiler's sysroot if not specified).],
1228
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [search for dependent libraries within DIR
1229
+                                              (or the compiler's sysroot if not specified).])],
1230 1230
 [], [with_sysroot=no])
1231 1231
 
1232 1232
 dnl lt_sysroot will always be passed unquoted.  We quote it here
... ...
@@ -265,7 +265,7 @@ dnl eponymous directory:
265 265
 AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])])
266 266
 
267 267
 AC_ARG_WITH([ltdl_include],
268
-    [AS_HELP_STRING([--with-ltdl-include=DIR],
268
+    [AS_HELP_STRING([--with-ltdl-include@<:@=DIR@:>@],
269 269
                     [use the ltdl headers installed in DIR])])
270 270
 
271 271
 if test -n "$with_ltdl_include"; then
... ...
@@ -278,7 +278,7 @@ else
278 278
 fi
279 279
 
280 280
 AC_ARG_WITH([ltdl_lib],
281
-    [AS_HELP_STRING([--with-ltdl-lib=DIR],
281
+    [AS_HELP_STRING([--with-ltdl-lib@<:@=DIR@:>@],
282 282
                     [use the libltdl.la installed in DIR])])
283 283
 
284 284
 if test -n "$with_ltdl_lib"; then
... ...
@@ -1,5 +1,5 @@
1 1
 AC_ARG_ENABLE([bigstack],
2
-[  --enable-bigstack	  increase thread stack size],
2
+[AS_HELP_STRING([--enable-bigstack], [increase thread stack size])],
3 3
 enable_bigstack=$enableval, enable_bigstack="no")
4 4
 
5 5
 if test "$enable_bigstack" = "yes"; then
... ...
@@ -1,6 +1,5 @@
1 1
 AC_ARG_ENABLE(clamdtop,
2
-	      AC_HELP_STRING([--enable-clamdtop],
3
-			     [Enable 'clamdtop' tool @<:@default=auto@:>@]),
2
+	     [AC_HELP_STRING([--enable-clamdtop], [build clamdtop tool @<:@default=auto@:>@])],
4 3
 [enable_clamdtop=$enableval], [enable_clamdtop="auto"])
5 4
 
6 5
 if test "$enable_clamdtop" != "no"; then
... ...
@@ -1,3 +1,3 @@
1 1
 AC_ARG_ENABLE([fanotify],
2
-[  --disable-fanotify	  disable fanotify support (Linux only)],
2
+[AS_HELP_STRING([--disable-fanotify], [do not add fanotify support (Linux only)])],
3 3
 want_fanotify=$enableval, want_fanotify="yes")
... ...
@@ -1,7 +1,7 @@
1 1
 dnl we need to try to link with iconv, otherwise there could be a 
2 2
 dnl mismatch between a 32-bit and 64-bit lib. Detect this at configure time.
3 3
 dnl we need to check after zlib/bzip2, because they can change the include path
4
-AC_ARG_WITH([iconv], [  --with-iconv supports iconv() (default=auto)],
4
+AC_ARG_WITH([iconv], [AS_HELP_STRING([--with-iconv], [supports iconv() @<:@default=auto@:>@])],
5 5
 [
6 6
  case "$withval" in
7 7
 	 yes|no) wiconv="$withval";;
... ...
@@ -1,5 +1,5 @@
1 1
 AC_ARG_ENABLE([ipv6],
2
-[  --disable-ipv6          disable IPv6 support],
2
+[AS_HELP_STRING([--disable-ipv6], [do not include IPv6 support])],
3 3
 want_ipv6=$enableval, want_ipv6="yes")
4 4
 
5 5
 if test "$want_ipv6" = "yes"
... ...
@@ -1,4 +1,4 @@
1
-AC_ARG_ENABLE([mempool],[  --disable-mempool       disable memory pools], enable_mempool=$enableval, enable_mempool="yes")
1
+AC_ARG_ENABLE([mempool],[AS_HELP_STRING([--disable-mempool], [do not use memory pools])], enable_mempool=$enableval, enable_mempool="yes")
2 2
 have_mempool="no"
3 3
 if test "$enable_mempool" = "yes"; then
4 4
 	if test "$ac_cv_c_mmap_private" != "yes"; then
... ...
@@ -2,5 +2,5 @@ have_pthreads=no
2 2
 AC_CHECK_HEADER([pthread.h],[have_pthreads=yes])
3 3
 
4 4
 AC_ARG_ENABLE([pthreads],
5
-[  --disable-pthreads      disable POSIX threads support],
5
+[AS_HELP_STRING([--disable-pthreads], [do not include POSIX threads support])],
6 6
 have_pthreads=$enableval,)
... ...
@@ -29,7 +29,7 @@ if test -z "$ac_cv_readdir_args"; then
29 29
 fi
30 30
 
31 31
 AC_ARG_ENABLE([readdir_r],
32
-[  --enable-readdir_r		    enable support for readdir_r],
32
+[AS_HELP_STRING([--enable-readdir_r], [enable support for readdir_r])],
33 33
 enable_readdir_r=$enableval, enable_readdir_r="no")
34 34
 
35 35
 if test "$enable_readdir_r" = "no"; then
... ...
@@ -1,3 +1,3 @@
1 1
 AC_ARG_ENABLE([cr],
2
-[  --disable-cr		  don't link with C reentrant library (BSD) ],
2
+[AS_HELP_STRING([--disable-cr], [do not link with C reentrant library (BSD)])],
3 3
 use_cr=$enableval,)
... ...
@@ -1,7 +1,7 @@
1 1
 enable_check_ut=auto
2 2
 enable_ut_install=no
3 3
 AC_ARG_ENABLE(check,
4
-[  --enable-check           Enable 'check' unit tests (default=auto)], enable_check_ut=$enableval, enable_check_ut="auto" )
4
+[AS_HELP_STRING([--enable-check], [enable check unit tests @<:@default=auto@:>@])], enable_check_ut=$enableval, enable_check_ut="auto" )
5 5
 
6 6
 if test "$enable_check_ut" != "no" ; then
7 7
 case "$host_os" in
... ...
@@ -1,5 +1,5 @@
1 1
 AC_ARG_ENABLE([gcc-vcheck],
2
-[  --disable-gcc-vcheck	  do not check for buggy gcc version ],
2
+[AS_HELP_STRING([--disable-gcc-vcheck], [do not check for buggy gcc version])],
3 3
 gcc_check=$enableval, gcc_check="yes")
4 4
 
5 5
 msg_gcc_check="use --disable-gcc-vcheck to disable this check. Before reporting any bugs check with a supported version of gcc"
... ...
@@ -1,3 +1,3 @@
1 1
 AC_ARG_WITH([version], 
2
-[  --with-version=STR    use custom version string (dev only)],
2
+[AS_HELP_STRING([--with-version@<:@=STR@:>@], [use custom version string (dev only)])],
3 3
 VERSION="$withval", )
... ...
@@ -1,5 +1,5 @@
1 1
 AC_ARG_WITH([dbdir], 
2
-[  --with-dbdir=path	  path to virus database directory],
2
+[AS_HELP_STRING([--with-dbdir@<:@=path@:>@], [path to virus database directory])],
3 3
 db_dir="$withval", db_dir="_default_")
4 4
 
5 5
 dnl I had problems with $pkgdatadir thus these funny checks
... ...
@@ -1,5 +1,5 @@
1 1
 AC_ARG_ENABLE([dns-fix],
2
-[  --enable-dns-fix	  enable workaround for broken DNS servers (as in SpeedTouch 510)],
2
+[AS_HELP_STRING([--enable-dns-fix], [enable workaround for broken DNS servers (as in SpeedTouch 510)])],
3 3
 enable_dnsfix=$enableval, enable_dnsfix="no")
4 4
 
5 5
 if test "$enable_dnsfix" = "yes"; then
... ...
@@ -1,6 +1,6 @@
1 1
 
2 2
 AC_ARG_ENABLE([bzip2],
3
-[  --disable-bzip2	  disable bzip2 support],
3
+[AS_HELP_STRING([--disable-bzip2], [do not include bzip2 support])],
4 4
 want_bzip2=$enableval, want_bzip2="yes")
5 5
 
6 6
 bzip_check="ok"
... ...
@@ -3,8 +3,8 @@ curl_msg="Please use the web interface for submitting FPs/FNs."
3 3
 AC_MSG_CHECKING([for libcurl installation])
4 4
 
5 5
 AC_ARG_WITH([libcurl],
6
-[  --with-libcurl=DIR   path to directory containing libcurl (default=
7
-    /usr/local or /usr if not found in /usr/local)],
6
+[AS_HELP_STRING([--with-libcurl@<:@=DIR@:>@], [path to directory containing libcurl
7
+                @<:@default=/usr/local or /usr if not found in /usr/local@:>@])],
8 8
 [
9 9
 if test "$withval"; then
10 10
     LIBCURL_HOME="$withval"
... ...
@@ -1,8 +1,8 @@
1 1
 dnl Check for libjson
2 2
 
3 3
 AC_ARG_WITH([libjson],
4
-[  --with-libjson=DIR   path to directory containing libjson (default=
5
-    /usr/local or /usr if not found in /usr/local)],
4
+[AS_HELP_STRING([--with-libjson@<:@=DIR@:>@], [path to directory containing libjson
5
+                @<:@default=/usr/local or /usr if not found in /usr/local@:>@])],
6 6
 [
7 7
 AC_MSG_CHECKING([for libjson installation])
8 8
 if test "X$withval" != "Xyes"
... ...
@@ -2,8 +2,8 @@
2 2
 dnl Check for zlib
3 3
 AC_MSG_CHECKING([for zlib installation])
4 4
 AC_ARG_WITH([zlib],
5
-[  --with-zlib=DIR	  path to directory containing zlib library (default=
6
-			  /usr/local or /usr if not found in /usr/local)],
5
+[AS_HELP_STRING([--with-zlib@<:@=DIR@:>@], [path to directory containing zlib library
6
+                @<:@default=/usr/local or /usr if not found in /usr/local@:>@])],
7 7
 [
8 8
 if test "$withval"; then
9 9
   ZLIB_HOME="$withval"
... ...
@@ -21,7 +21,7 @@ AC_MSG_RESULT([$ZLIB_HOME])
21 21
 CLAMDSCAN_LIBS="$FRESHCLAM_LIBS"
22 22
 
23 23
 AC_ARG_ENABLE([zlib-vcheck],
24
-[  --disable-zlib-vcheck	  do not check for buggy zlib version ],
24
+[AS_HELP_STRING([--disable-zlib-vcheck], [do not check for buggy zlib version])],
25 25
 zlib_check=$enableval, zlib_check="yes")
26 26
 
27 27
 if test ! -f "$ZLIB_HOME/include/zlib.h"
... ...
@@ -2,8 +2,8 @@ dnl Check for OpenSSL
2 2
 AC_MSG_CHECKING([for OpenSSL installation])
3 3
 
4 4
 AC_ARG_WITH([openssl],
5
-[  --with-openssl=DIR   path to directory containing openssl (default=
6
-    /usr/local or /usr if not found in /usr/local)],
5
+[AS_HELP_STRING([--with-openssl@<:@=DIR@:>@], [path to directory containing openssl
6
+                @<:@default=/usr/local or /usr if not found in /usr/local@:>@])],
7 7
 [
8 8
 if test "$withval"; then
9 9
     LIBSSL_HOME="$withval"
... ...
@@ -3,8 +3,8 @@ dnl Check for PCRE
3 3
 dnl determine the home of pcre
4 4
 PCRE_HOME=""
5 5
 AC_ARG_WITH([pcre],
6
-[  --with-pcre=DIR        path to directory containing libpcre library (default=
7
-                          /usr/local or /usr if not found in /usr/local)],
6
+[AS_HELP_STRING([--with-pcre@<:@=DIR@:>@], [path to directory containing libpcre library
7
+                @<:@default=/usr/local or /usr if not found in /usr/local@:>@])],
8 8
 [
9 9
   AC_MSG_CHECKING([for libpcre installation])
10 10
   case "$withval" in
... ...
@@ -1,10 +1,10 @@
1 1
 AC_ARG_ENABLE([unrar],
2
-[  --disable-unrar	  don't build libclamunrar and libclamunrar_iface ],
2
+[AS_HELP_STRING([--disable-unrar], [do not build libclamunrar and libclamunrar_iface])],
3 3
 want_unrar=$enableval, want_unrar="yes")
4 4
 AM_CONDITIONAL([ENABLE_UNRAR],[test "$want_unrar" = "yes"])
5 5
 
6 6
 AC_ARG_ENABLE([getaddrinfo],
7
-[  --disable-getaddrinfo          disable support for getaddrinfo],
7
+[AS_HELP_STRING([--disable-getaddrinfo], [do not include support for getaddrinfo])],
8 8
 want_getaddrinfo=$enableval, want_getaddrinfo="yes")
9 9
 
10 10
 if test "$want_getaddrinfo" = "yes"
... ...
@@ -1,15 +1,15 @@
1 1
 
2 2
 want_xml="auto"
3 3
 AC_ARG_ENABLE([xml],
4
-[  --disable-xml	  disable DMG and XAR support],
4
+[AS_HELP_STRING([--disable-xml], [do not include DMG and XAR support])],
5 5
 want_xml=$enableval, want_xml="auto")
6 6
 
7 7
 XML_HOME=""
8 8
 if test "X$want_xml" != "Xno"; then
9 9
   AC_MSG_CHECKING([for libxml2 installation])
10 10
   AC_ARG_WITH([xml],
11
-  [  --with-xml=DIR	  path to directory containing libxml2 library (default=
12
-			  /usr/local or /usr if not found in /usr/local)],
11
+  [AS_HELP_STRING([--with-xml@<:@=DIR@:>@], [path to directory containing libxml2 library
12
+                  @<:@default=/usr/local or /usr if not found in /usr/local@:>@])],
13 13
   [
14 14
   if test "$withval"
15 15
   then
... ...
@@ -1,6 +1,6 @@
1
-AC_ARG_WITH([system-llvm], AC_HELP_STRING([--with-system-llvm],
2
-[Use system llvm instead of built-in, uses full path to llvm-config (default=
3
-/usr/local or /usr if not found in /usr/local)]),
1
+AC_ARG_WITH([system-llvm], [AC_HELP_STRING([--with-system-llvm],
2
+[use system llvm instead of built-in, uses full path to llvm-config
3
+@<:@default=/usr/local or /usr if not found in /usr/local@:>@])],
4 4
 [case "$withval" in
5 5
   yes)
6 6
     system_llvm="default"
... ...
@@ -14,7 +14,7 @@ AC_ARG_WITH([system-llvm], AC_HELP_STRING([--with-system-llvm],
14 14
 ], [system_llvm="built-in"])
15 15
 
16 16
 AC_ARG_ENABLE([llvm],AC_HELP_STRING([--enable-llvm],
17
-[Enable 'llvm' JIT/verifier support @<:@default=auto@:>@]),
17
+[enable 'llvm' JIT/verifier support @<:@default=auto@:>@]),
18 18
 [enable_llvm=$enableval],
19 19
 [
20 20
 if test "x$system_llvm" != "xbuilt-in"; then
... ...
@@ -1,3 +1,3 @@
1 1
 AC_ARG_ENABLE([milter],
2
-[  --enable-milter	  build clamav-milter],
2
+[AS_HELP_STRING([--enable-milter], [build clamav-milter])],
3 3
 have_milter=$enableval, have_milter="no")
... ...
@@ -1,5 +1,5 @@
1 1
 AC_ARG_ENABLE([no-cache],
2
-[  --enable-no-cache	  use "Cache-Control: no-cache" in freshclam],
2
+[AS_HELP_STRING([--enable-no-cache], [use "Cache-Control: no-cache" in freshclam])],
3 3
 enable_nocache=$enableval, enable_nocache="no")
4 4
 
5 5
 if test "$enable_nocache" = "yes"; then
... ...
@@ -1,13 +1,13 @@
1 1
 AC_ARG_ENABLE([yp-check],
2
-[  --enable-yp-check	  use ypmatch utility instead of /etc/passwd parsing],
2
+[AS_HELP_STRING([--enable-yp-check], [use ypmatch utility instead of /etc/passwd parsing])],
3 3
 use_yp=$enableval, use_yp="no")
4 4
 
5 5
 AC_ARG_WITH([user], 
6
-[  --with-user=uid	  name of the clamav user (default=clamav)],
6
+[AS_HELP_STRING([--with-user@<:@=uid@:>@], [name of the clamav user @<:@default=clamav@:>@])],
7 7
 clamav_user="$withval", clamav_user="clamav")
8 8
 
9 9
 AC_ARG_WITH([group], 
10
-[  --with-group=gid	  name of the clamav group (default=clamav)],
10
+[AS_HELP_STRING([--with-group@<:@=gid@:>@], [name of the clamav group @<:@default=clamav@:>@])],
11 11
 clamav_group="$withval", clamav_group="clamav")
12 12
 
13 13
 AC_DEFINE_UNQUOTED([CLAMAVUSER],"$clamav_user",[name of the clamav user])
... ...
@@ -1,3 +1,3 @@
1 1
 AC_ARG_ENABLE([id-check],
2
-[  --enable-id-check	  use id utility instead of /etc/passwd parsing],
2
+[AS_HELP_STRING([--enable-id-check], [use id utility instead of /etc/passwd parsing])],
3 3
 use_id=$enableval, use_id="no")
... ...
@@ -1,3 +1,3 @@
1 1
 AC_ARG_ENABLE([yp-check],
2
-[  --enable-yp-check	  use ypmatch utility instead of /etc/passwd parsing],
2
+[AS_HELP_STRING([--enable-yp-check], [use ypmatch utility instead of /etc/passwd parsing])],
3 3
 use_yp=$enableval, use_yp="no")
... ...
@@ -9,7 +9,7 @@ dnl as symbols are often redefined in resolv.h
9 9
 AC_DEFUN([AC_C_DNS], [
10 10
 
11 11
 AC_ARG_ENABLE([dns],
12
-    AC_HELP_STRING([--disable-dns], [disable support for database verification through DNS]),
12
+    [AC_HELP_STRING([--disable-dns], [do not include support for database verification through DNS])],
13 13
     [want_dns=$enableval], [want_dns=yes]
14 14
 )
15 15
 if test $want_dns = yes; then
... ...
@@ -295,7 +295,7 @@ const struct clam_option __clam_options[] = {
295 295
 	"Allow loading bytecode from outside digitally signed .c[lv]d files.","no"},
296 296
 
297 297
     { "BytecodeMode", "bytecode-mode", 0, CLOPT_TYPE_STRING, "^(Auto|ForceJIT|ForceInterpreter|Test)$", -1, "Auto", FLAG_REQUIRED, OPT_CLAMD | OPT_CLAMSCAN,
298
-	"Set bytecode execution mode.\nPossible values:\n\tAuto - automatically choose JIT if possible, fallback to interpreter\nForceJIT - always choose JIT, fail if not possible\nForceIntepreter - always choose interpreter\nTest - run with both JIT and interpreter and compare results. Make all failures fatal.","Auto"},
298
+	"Set bytecode execution mode.\nPossible values:\n\tAuto - automatically choose JIT if possible, fallback to interpreter\nForceJIT - always choose JIT, fail if not possible\nForceInterpreter - always choose interpreter\nTest - run with both JIT and interpreter and compare results. Make all failures fatal.","Auto"},
299 299
 
300 300
     { "Statistics", "statistics", 0, CLOPT_TYPE_STRING, "^(none|None|bytecode|Bytecode|pcre|PCRE)$", -1, NULL, FLAG_MULTIPLE, OPT_CLAMSCAN | OPT_CLAMBC, "Collect and print execution statistics.\nPossible values:\n\tBytecode - reports bytecode statistics\nPCRE - reports PCRE execution statistics\nNone - reports no statistics", "None" },
301 301
 
... ...
@@ -303,7 +303,7 @@ static char *getdsig(const char *host, const char *user, const unsigned char *da
303 303
 	    return NULL;
304 304
 	}
305 305
 #endif
306
-	if(scanf("%30s", pass) == EOF || !pt) {
306
+	if(scanf("%30s", pass) == EOF) {
307 307
 	    mprintf("!getdsig: Can't get password\n");
308 308
 #ifdef HAVE_TERMIOS_H
309 309
 	    tcsetattr(0, TCSAFLUSH, &old);
... ...
@@ -846,7 +846,7 @@ static int build(const struct optstruct *opts)
846 846
 	builder[sizeof(builder)-1]='\0';
847 847
     } else {
848 848
 	mprintf("Builder name: ");
849
-	if(scanf("%32s", builder) == EOF || !pt) {
849
+	if(scanf("%32s", builder) == EOF) {
850 850
 	    mprintf("!build: Can't get builder name\n");
851 851
 	    free(dblist2);
852 852
 	    return -1;
... ...
@@ -86,3 +86,16 @@
86 86
     ...
87 87
     fun:SSL_library_init
88 88
 }
89
+{
90
+   y0da-cached-virname
91
+   Memcheck:Cond
92
+   fun:cli_scanpe
93
+   fun:magic_scandesc
94
+   fun:cli_base_scandesc
95
+   fun:cli_magic_scandesc
96
+   fun:scan_common
97
+   fun:cl_scandesc_callback
98
+   fun:scanfile
99
+   fun:scanmanager
100
+   fun:main
101
+}
... ...
@@ -3,6 +3,16 @@ ClamAV for Win32
3 3
 
4 4
 --- News ---
5 5
 
6
+In order to support more advanced features planned in future releases, 
7
+ClamAV has switched to using OpenSSL for hashing. The ClamAV Visual Studio 
8
+project included with ClamAV's source code requires the OpenSSL 
9
+distributables to be placed in a specific directory. This article will 
10
+teach you how to compile OpenSSL on a Microsoft Windows system and how 
11
+to link ClamAV against OpenSSL.
12
+
13
+Read More here:
14
+     http://blog.clamav.net/2014/07/compiling-openssl-for-windows.html
15
+
6 16
 Starting from version 0.98 the windows version of ClamAV requires all the
7 17
 input to be UTF-8 encoded.
8 18
 This affects:
... ...
@@ -468,6 +468,11 @@ int CLAMAPI Scan_Initialize(const wchar_t *pEnginesFolder, const wchar_t *pTempR
468 468
 	free_engine_and_unlock();
469 469
 	FAIL(CL_ETMPDIR, "Cannot create pTempRoot '%s': error %d", tmpdir, ret);
470 470
     }
471
+    /* callbacks require cli_map_scan to generate fds */
472
+    if((ret = cl_engine_set_num(engine, CL_ENGINE_FORCETODISK, 1))) {
473
+	free_engine_and_unlock();
474
+	FAIL(ret, "Failed to set engine forced-to-disk: %s", cl_strerror(ret));
475
+    }
471 476
     if((ret = cl_engine_set_str(engine, CL_ENGINE_TMPDIR, tmpdir))) {
472 477
 	free_engine_and_unlock();
473 478
 	FAIL(ret, "Failed to set engine tempdir to '%s': %s", tmpdir, cl_strerror(ret));
... ...
@@ -751,7 +756,7 @@ int CLAMAPI Scan_GetLimit(int option, unsigned int *value) {
751 751
 	limit = CL_ENGINE_MAX_SCANSIZE;
752 752
 	break;
753 753
     case CLAM_LIMIT_RECURSION:
754
-	limit = CL_ENGINE_MAX_SCANSIZE;
754
+	limit = CL_ENGINE_MAX_RECURSION;
755 755
 	break;
756 756
     default:
757 757
 	unlock_engine();
... ...
@@ -793,7 +798,7 @@ int CLAMAPI Scan_SetLimit(int option, unsigned int value) {
793 793
 	break;
794 794
     case CLAM_LIMIT_RECURSION:
795 795
 	logg("CLAM_LIMIT_RECURSION: set to %u\n", value);
796
-	limit = CL_ENGINE_MAX_SCANSIZE;
796
+	limit = CL_ENGINE_MAX_RECURSION;
797 797
 	break;
798 798
     default:
799 799
 	unlock_engine();
... ...
@@ -1167,51 +1172,59 @@ cl_error_t prescan_cb(int fd, const char *type, void *context) {
1167 1167
     si.pInnerObjectPath = NULL;
1168 1168
 
1169 1169
     if(si.scanPhase == SCAN_PHASE_PRESCAN) {
1170
-	long fpos;
1171
-	int rsz;
1172
-	perf2 = GetTickCount();
1173
-	while(1) {
1174
-	    static int tmpn;
1175
-	    snprintf(tmpf, sizeof(tmpf), "%s\\%08x.tmp", tmpdir, ++tmpn);
1176
-	    tmpf[sizeof(tmpf)-1] = '\0';
1177
-	    fdhdl = CreateFile(tmpf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
1178
-	    if(fdhdl != INVALID_HANDLE_VALUE) {
1179
-		logg("*prescan_cb: dumping content to tempfile %s (handle %p)\n", tmpf, fdhdl);
1180
-		break;
1181
-	    }
1182
-	    if((perf = GetLastError()) != ERROR_FILE_EXISTS) {
1183
-		logg("!prescan_cb: failed to create tempfile %s - error %u\n", tmpf, perf);
1184
-		return CL_CLEAN;
1170
+	/* Windows requires lseek fd to be valid */
1171
+	if (fd < 0) {
1172
+	    logg("!prescan_cb: failed to create tempfile - invalid fd %d\n", fd);
1173
+	    logg("!prescan_cb: engine option (force-to-disk) is likely not set\n");
1174
+	    si.object = INVALID_HANDLE_VALUE;
1175
+	    si.objectId = INVALID_HANDLE_VALUE;
1176
+	} else {
1177
+	    long fpos;
1178
+	    int rsz;
1179
+	    perf2 = GetTickCount();
1180
+	    while(1) {
1181
+		static int tmpn;
1182
+		snprintf(tmpf, sizeof(tmpf), "%s\\%08x.tmp", tmpdir, ++tmpn);
1183
+		tmpf[sizeof(tmpf)-1] = '\0';
1184
+		fdhdl = CreateFile(tmpf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
1185
+		if(fdhdl != INVALID_HANDLE_VALUE) {
1186
+		    logg("*prescan_cb: dumping content to tempfile %s (handle %p)\n", tmpf, fdhdl);
1187
+		    break;
1188
+		}
1189
+		if((perf = GetLastError()) != ERROR_FILE_EXISTS) {
1190
+		    logg("!prescan_cb: failed to create tempfile %s - error %u\n", tmpf, perf);
1191
+		    return CL_CLEAN;
1192
+		}
1185 1193
 	    }
1186
-	}
1187 1194
 
1188
-	fpos = lseek(fd, 0, SEEK_CUR);
1189
-	lseek(fd, 0, SEEK_SET);
1190
-	while((rsz = read(fd, tmpf, sizeof(tmpf))) > 0) {
1191
-	    int wsz = 0;
1192
-	    while(wsz != rsz) {
1193
-		DWORD rwsz;
1194
-		if(!WriteFile(fdhdl, &tmpf[wsz], rsz - wsz, &rwsz, NULL)) {
1195
-		    logg("!prescan_cb: failed to write to tempfile %s - error %u\n", GetLastError());
1196
-		    lseek(fd, fpos, SEEK_SET);
1197
-		    CloseHandle(fdhdl);
1198
-		    return CL_CLEAN;
1195
+	    fpos = lseek(fd, 0, SEEK_CUR);
1196
+	    lseek(fd, 0, SEEK_SET);
1197
+	    while((rsz = read(fd, tmpf, sizeof(tmpf))) > 0) {
1198
+		int wsz = 0;
1199
+		while(wsz != rsz) {
1200
+		    DWORD rwsz;
1201
+		    if(!WriteFile(fdhdl, &tmpf[wsz], rsz - wsz, &rwsz, NULL)) {
1202
+			logg("!prescan_cb: failed to write to tempfile %s - error %u\n", GetLastError());
1203
+			lseek(fd, fpos, SEEK_SET);
1204
+			CloseHandle(fdhdl);
1205
+			return CL_CLEAN;
1206
+		    }
1207
+		    wsz += rwsz;
1199 1208
 		}
1200
-		wsz += rwsz;
1201 1209
 	    }
1202
-	}
1203
-	if(rsz) {
1204
-	    logg("!prescan_cb: failed to read from clamav tempfile - errno = %d\n", errno);
1210
+	    if(rsz) {
1211
+		logg("!prescan_cb: failed to read from clamav tempfile - errno = %d\n", errno);
1212
+		lseek(fd, fpos, SEEK_SET);
1213
+		CloseHandle(fdhdl);
1214
+		return CL_CLEAN;
1215
+	    }
1205 1216
 	    lseek(fd, fpos, SEEK_SET);
1206
-	    CloseHandle(fdhdl);
1207
-	    return CL_CLEAN;
1217
+	    SetFilePointer(fdhdl, 0, NULL, FILE_BEGIN);
1218
+	    si.object = fdhdl;
1219
+	    si.objectId = (HANDLE)_get_osfhandle(fd);
1220
+	    perf2 = GetTickCount() - perf2;
1221
+	    sctx->copy_times += perf2;
1208 1222
 	}
1209
-	lseek(fd, fpos, SEEK_SET);
1210
-	SetFilePointer(fdhdl, 0, NULL, FILE_BEGIN);
1211
-	si.object = fdhdl;
1212
-	si.objectId = (HANDLE)_get_osfhandle(fd);
1213
-	perf2 = GetTickCount() - perf2;
1214
-	sctx->copy_times += perf2;
1215 1223
     } else { /* SCAN_PHASE_INITIAL */
1216 1224
 	si.object = INVALID_HANDLE_VALUE;
1217 1225
 	si.objectId = INVALID_HANDLE_VALUE;
... ...
@@ -1270,7 +1283,12 @@ cl_error_t postscan_cb(int fd, int result, const char *virname, void *context) {
1270 1270
 	    si.pThreatName = NULL;
1271 1271
     logg("*in postscan_cb with clamav context %p, instance %p, fd %d, result %d, virusname %S)\n", context, inst, fd, result, si.pThreatName);
1272 1272
     si.pThreatType = threat_type(virname);
1273
-    si.objectId = (HANDLE)_get_osfhandle(fd);
1273
+    if (fd < 0) {
1274
+	logg("!postscan_cb: invalid handle value - invalid fd %d\n", fd);
1275
+	logg("!postscan_cb: engine option (force-to-disk) is likely not set\n");
1276
+	si.objectId = INVALID_HANDLE_VALUE;
1277
+    } else
1278
+	si.objectId = (HANDLE)_get_osfhandle(fd);
1274 1279
     si.object = INVALID_HANDLE_VALUE;
1275 1280
     si.pInnerObjectPath = NULL;
1276 1281
     logg("*postscan_cb (clamav context %p, instance %p) invoking callback %p with context %p\n", context, inst, inst->scancb, inst->scancb_ctx);
... ...
@@ -389,6 +389,7 @@
389 389
     <ClCompile Include="..\libclamav\special.c" />
390 390
     <ClCompile Include="..\libclamav\spin.c" />
391 391
     <ClCompile Include="..\libclamav\str.c" />
392
+    <ClCompile Include="..\libclamav\strlcat.c" />
392 393
     <ClCompile Include="..\libclamav\table.c" />
393 394
     <ClCompile Include="..\libclamav\text.c" />
394 395
     <ClCompile Include="..\libclamav\textdet.c" />
... ...
@@ -258,6 +258,9 @@
258 258
     <ClCompile Include="..\libclamav\str.c">
259 259
       <Filter>Source Files</Filter>
260 260
     </ClCompile>
261
+    <ClCompile Include="..\libclamav\strlcat.c">
262
+      <Filter>Source Files</Filter>
263
+    </ClCompile>
261 264
     <ClCompile Include="..\libclamav\table.c">
262 265
       <Filter>Source Files</Filter>
263 266
     </ClCompile>