Browse code

libclamav/matcher-ac.c: add support for line marker (L) (matches CR, CRLF and boundaries)

Tomasz Kojm authored on 2009/09/25 17:38:10
Showing 2 changed files
... ...
@@ -1,3 +1,8 @@
1
+Fri Sep 25 10:36:48 CEST 2009 (tk)
2
+----------------------------------
3
+ * libclamav/matcher-ac.c: add support for line marker (L) (matches CR,
4
+			   CRLF and boundaries)
5
+
1 6
 Fri Sep 25 00:35:56 CEST 2009 (acab)
2 7
 ------------------------------------
3 8
  * libclamav/sis.c: size check fix, thanks Tomasz
... ...
@@ -47,14 +47,17 @@
47 47
 
48 48
 #define AC_SPECIAL_ALT_CHAR	1
49 49
 #define AC_SPECIAL_ALT_STR	2
50
-#define AC_SPECIAL_LINE_START	3
51
-#define AC_SPECIAL_LINE_END	4
52
-#define AC_SPECIAL_BOUNDARY	5
53
-
54
-#define AC_BOUNDARY_LEFT	    1
55
-#define AC_BOUNDARY_LEFT_NEGATIVE   2
56
-#define AC_BOUNDARY_RIGHT	    4
57
-#define AC_BOUNDARY_RIGHT_NEGATIVE  8
50
+#define AC_SPECIAL_LINE_MARKER	3
51
+#define AC_SPECIAL_BOUNDARY	4
52
+
53
+#define AC_BOUNDARY_LEFT		1
54
+#define AC_BOUNDARY_LEFT_NEGATIVE	2
55
+#define AC_BOUNDARY_RIGHT		4
56
+#define AC_BOUNDARY_RIGHT_NEGATIVE	8
57
+#define AC_LINE_MARKER_LEFT		16
58
+#define AC_LINE_MARKER_LEFT_NEGATIVE	32
59
+#define AC_LINE_MARKER_RIGHT		64
60
+#define AC_LINE_MARKER_RIGHT_NEGATIVE	128
58 61
 
59 62
 static char boundary[256] = {
60 63
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 
... ...
@@ -721,6 +724,15 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne
721 721
 		    }									\
722 722
 		    break;								\
723 723
 											\
724
+		case AC_SPECIAL_LINE_MARKER:						\
725
+		    if(b == '\n') {							\
726
+			match = !special->negative;					\
727
+		    } else if(b == '\r' && (bp + 1 < length && buffer[bp + 1] == '\n')) {   \
728
+			bp++;								\
729
+			match = !special->negative;					\
730
+		    }									\
731
+		    break;								\
732
+											\
724 733
 		case AC_SPECIAL_BOUNDARY:						\
725 734
 		    if(boundary[b])							\
726 735
 			match = !special->negative;					\
... ...
@@ -785,6 +797,22 @@ inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uin
785 785
 	    return 0;
786 786
     }
787 787
 
788
+    if(pattern->boundary & AC_LINE_MARKER_LEFT) {
789
+	match = !!(pattern->boundary & AC_LINE_MARKER_LEFT_NEGATIVE);
790
+	if(!fileoffset || (offset && (buffer[offset - 1] == '\n')))
791
+	    match = !match;
792
+	if(!match)
793
+	    return 0;
794
+    }
795
+
796
+    if(pattern->boundary & AC_LINE_MARKER_RIGHT) {
797
+	match = !!(pattern->boundary & AC_LINE_MARKER_RIGHT_NEGATIVE);
798
+	if((length <= SCANBUFF) && (bp == length || buffer[bp] == '\n' || (buffer[bp] == '\r' && bp + 1 < length && buffer[bp + 1] == '\n')))
799
+	    match = !match;
800
+	if(!match)
801
+	    return 0;
802
+    }
803
+
788 804
     if(!(pattern->ch[1] & CLI_MATCH_IGNORE)) {
789 805
 	bp += pattern->ch_mindist[1];
790 806
 	for(i = pattern->ch_mindist[1]; i <= pattern->ch_maxdist[1]; i++) {
... ...
@@ -1407,8 +1435,21 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1407 1407
 		    mpool_free(root->mempool, newspecial);
1408 1408
 		    continue;
1409 1409
 		}
1410
+	    } else if(!strcmp(pt, "L")) {
1411
+		if(!*start) {
1412
+		    new->boundary |= AC_LINE_MARKER_RIGHT;
1413
+		    if(newspecial->negative)
1414
+			new->boundary |= AC_LINE_MARKER_RIGHT_NEGATIVE;
1415
+		    mpool_free(root->mempool, newspecial);
1416
+		    continue;
1417
+		} else if(pt - 1 == hexcpy) {
1418
+		    new->boundary |= AC_LINE_MARKER_LEFT;
1419
+		    if(newspecial->negative)
1420
+			new->boundary |= AC_LINE_MARKER_LEFT_NEGATIVE;
1421
+		    mpool_free(root->mempool, newspecial);
1422
+		    continue;
1423
+		}
1410 1424
 	    }
1411
-
1412 1425
 	    strcat(hexnew, "()");
1413 1426
 	    new->special++;
1414 1427
 	    newtable = (struct cli_ac_special **) mpool_realloc(root->mempool, new->special_table, new->special * sizeof(struct cli_ac_special *));
... ...
@@ -1424,11 +1465,9 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
1424 1424
 
1425 1425
 	    if(!strcmp(pt, "B")) {
1426 1426
 		newspecial->type = AC_SPECIAL_BOUNDARY;
1427
-	    /* TODO
1428
-	    } else if(strcmp(pt, "S")) {
1429
-		newspecial->type = AC_SPECIAL_LINE_START;
1430
-	    } else if(strcmp(pt, "E")) {
1431
-		newspecial->type = AC_SPECIAL_LINE_END;
1427
+	    } else if(!strcmp(pt, "L")) {
1428
+		newspecial->type = AC_SPECIAL_LINE_MARKER;
1429
+	    /*
1432 1430
 	    } else if(strcmp(pt, "W")) {
1433 1431
 		newspecial->type = AC_SPECIAL_WHITE;
1434 1432
 	    */