From: Jeremy Harris Date: Sun, 2 Feb 2014 23:10:07 +0000 (+0000) Subject: Refactor reges operations X-Git-Url: https://git.exim.org/users/jgh/exim.git/commitdiff_plain/1cd74e56d1483d2573bd52aea5d958f2efa5c040 Refactor reges operations --- diff --git a/src/src/malware.c b/src/src/malware.c index 62758580c..b72253e7b 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -336,6 +336,32 @@ m_sock_send(int sock, uschar * buf, int cnt, uschar ** errstr) return sock; } +static const pcre * +m_pcre_compile(const uschar * re, uschar ** errstr) +{ + const uschar * rerror; + int roffset; + const pcre * cre; + + cre = pcre_compile(re, PCRE_COPT, (const char **)&rerror, &roffset, NULL); + if (!cre) + *errstr= string_sprintf("regular expression error in '%s': %s at offset %d", + re, rerror, roffset); + return cre; +} + +uschar * +m_pcre_exec(const pcre * cre, uschar * text) +{ + int ovector[10*3]; + int i = pcre_exec(cre, NULL, CS text, Ustrlen(text), 0, 0, + ovector, nelements(ovector)); + uschar * substr = NULL; + if (i >= 2) /* Got it */ + pcre_get_substring(CS text, ovector, i, 1, (const char **) &substr); + return substr; +} + /************************************************* * Scan content for malware * *************************************************/ @@ -384,9 +410,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) uschar malware_regex_default[] = ".+"; unsigned long mbox_size; FILE *mbox_file; - int roffset; const pcre *re; - const uschar *rerror; uschar * errstr; struct scan * scanent; const uschar * scanner_options; @@ -424,11 +448,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) sep = 0; /* compile the regex, see if it works */ - re = pcre_compile(CS malware_regex, PCRE_COPT, (const char **)&rerror, &roffset, NULL); - if (!re) - return malware_errlog_defer( - string_sprintf("regular expression error in '%s': %s at offset %d", - malware_regex, rerror, roffset)); + if (!(re = m_pcre_compile(CS malware_regex, &errstr))) + return malware_errlog_defer(errstr); /* if av_scanner starts with a dollar, expand it first */ if (*av_scanner == '$') { @@ -513,13 +534,13 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* v0.0 - initial release -- support for unix sockets */ { struct sockaddr_un server; - int sock, result, ovector[10*3]; + int sock, result; unsigned int fsize; uschar * tmpbuf, *drweb_fbuf; int drweb_rc, drweb_cmd, drweb_flags = 0x0000, drweb_fd, drweb_vnum, drweb_slen, drweb_fin = 0x0000; unsigned long bread; - pcre *drweb_re; + const pcre *drweb_re; if (*scanner_options != '/') { if ((sock = m_tcpsocket_fromdef(scanner_options, &errstr)) < 0) @@ -640,13 +661,12 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) malware_name = malware_name_internal; /* set up match regex */ - drweb_re = pcre_compile( "infected\\swith\\s*(.+?)$", PCRE_COPT, - (const char **)&rerror, &roffset, NULL ); + drweb_re = m_pcre_compile( "infected\\swith\\s*(.+?)$", &errstr); /* read and concatenate virus names into one string */ for (i=0;i= 2) { - /* Got it */ - pcre_get_substring(CS av_buffer, ovector, i, 1, - (const char **) &malware_name_internal); - malware_name = malware_name_internal; - } - } + malware_name = m_pcre_exec(fs_inf, av_buffer); } while (Ustrstr(av_buffer, "OK\tScan ok.") == NULL); (void)close(sock); @@ -882,7 +893,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) uschar * scanrequest; int kav_rc; unsigned long kav_reportlen, bread; - pcre *kav_re; + const pcre *kav_re; uschar *p; if((sock = m_unixsocket(scanner_options, &errstr)) < 0) @@ -958,19 +969,13 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) reportsize is 0 (!?) */ if (kav_reportlen > 0) { /* set up match regex, depends on retcode */ - kav_re = pcre_compile( kav_rc == 3 - ? "suspicion:\\s*(.+?)\\s*$" - : "infected:\\s*(.+?)\\s*$", - PCRE_COPT, - (const char **)&rerror, - &roffset, - NULL ); + kav_re = m_pcre_compile( kav_rc == 3 + ? "suspicion:\\s*(.+?)\\s*$" + : "infected:\\s*(.+?)\\s*$", + &errstr ); /* read report, linewise */ while (kav_reportlen > 0) { - int result = 0; - int ovector[10*3]; - bread = 0; while ( recv(sock, &tmpbuf[bread], 1, 0) == 1 ) { kav_reportlen--; @@ -981,13 +986,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) tmpbuf[bread] = '\0'; /* try matcher on the line, grab substring */ - result = pcre_exec(kav_re, NULL, CS tmpbuf, Ustrlen(tmpbuf), 0, 0, - ovector, nelements(ovector)); - if (result >= 2) { - pcre_get_substring(CS tmpbuf, ovector, result, 1, - (const char **) &malware_name_internal); + if ((malware_name = m_pcre_exec(kav_re, tmpbuf))) break; - } } } } @@ -1014,8 +1014,6 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) FILE *scanner_record = NULL; uschar linebuffer[32767]; int trigger = 0; - int result; - int ovector[10*3]; uschar *p; BOOL fits; @@ -1027,22 +1025,16 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) return cmdl_errlog_defer("missing trigger specification"); /* precompile trigger regex */ - cmdline_trigger_re = pcre_compile(CS cmdline_trigger, PCRE_COPT, (const char **)&rerror, &roffset, NULL); - if (cmdline_trigger_re == NULL) - return cmdl_errlog_defer( - string_sprintf("regular expression error in '%s': %s at offset %d", - cmdline_trigger, rerror, roffset)); + if (!(cmdline_trigger_re = m_pcre_compile(CS cmdline_trigger, &errstr))) + return cmdl_errlog_defer(errstr); /* find scanner name regex */ if (!(cmdline_regex = string_nextinlist(&av_scanner_work, &sep, NULL, 0))) return cmdl_errlog_defer("missing virus name regex specification"); /* precompile name regex */ - cmdline_regex_re = pcre_compile(CS cmdline_regex, PCRE_COPT, (const char **)&rerror, &roffset, NULL); - if (cmdline_regex_re == NULL) - return cmdl_errlog_defer( - string_sprintf("regular expression error in '%s': %s at offset %d", - cmdline_regex, rerror, roffset)); + if (!(cmdline_regex_re = m_pcre_compile(CS cmdline_regex, &errstr))) + return cmdl_errlog_defer(errstr); /* prepare scanner call; despite the naming, file_name holds a directory name which is documented as the value given to %s. */ @@ -1106,6 +1098,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) signal(SIGPIPE,eximsigpipe); if (trigger) { + uschar * s; /* setup default virus name */ malware_name = US"unknown"; @@ -1113,12 +1106,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) scanner_record = fopen(CS file_name, "rb"); while(fgets(CS linebuffer,32767,scanner_record) != NULL) { /* try match */ - result = pcre_exec(cmdline_regex_re, NULL, - CS linebuffer, Ustrlen(linebuffer), 0, 0, - ovector, nelements(ovector)); - if (result >= 2) - pcre_get_substring(CS linebuffer, ovector, result, 1, - (const char **) &malware_name_internal); + if ((s = m_pcre_exec(cmdline_regex_re, linebuffer))) + malware_name = s; } (void)fclose(scanner_record); } @@ -1606,11 +1595,9 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) uschar *sockline_scanner; uschar sockline_scanner_default[] = "%s\n"; uschar *sockline_trigger; - const pcre *sockline_trigger_re; + const pcre *sockline_trig_re; uschar *sockline_regex; - const pcre *sockline_regex_re; - int result; - int ovector[10*3]; + const pcre *sockline_name_re; /* find scanner command line */ if (!(sockline_scanner = string_nextinlist(&av_scanner_work, &sep, @@ -1623,11 +1610,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) return sock_errlog_defer("missing trigger specification"); /* precompile trigger regex */ - sockline_trigger_re = pcre_compile(CS sockline_trigger, PCRE_COPT, (const char **)&rerror, &roffset, NULL); - if (sockline_trigger_re == NULL) - return sock_errlog_defer( - string_sprintf("regular expression error in '%s': %s at offset %d", - sockline_trigger, rerror, roffset)); + if (!(sockline_trig_re = m_pcre_compile(CS sockline_trigger, &errstr))) + return sock_errlog_defer(errstr); /* find virus name regex */ if (!(sockline_regex = string_nextinlist(&av_scanner_work, &sep, @@ -1635,11 +1619,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) return sock_errlog_defer("missing virus name regex specification"); /* precompile name regex */ - sockline_regex_re = pcre_compile(CS sockline_regex, PCRE_COPT, (const char **)&rerror, &roffset, NULL); - if (sockline_regex_re == NULL) - return sock_errlog_defer( - string_sprintf("regular expression error in '%s': %s at offset %d", - sockline_regex, rerror, roffset)); + if (!(sockline_name_re = m_pcre_compile(CS sockline_regex, &errstr))) + return sock_errlog_defer(errstr); /* prepare scanner call */ commandline = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, message_id); @@ -1674,14 +1655,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) linebuffer = string_copy(av_buffer); /* try trigger match */ - if (regex_match_and_setup(sockline_trigger_re, linebuffer, 0, -1)) { - result = pcre_exec(sockline_regex_re, NULL, - CS av_buffer, Ustrlen(av_buffer), 0, 0, - ovector, nelements(ovector)); - if (result >= 2) - pcre_get_substring(CS av_buffer, ovector, result, 1, - (const char **)&malware_name); - else + if (regex_match_and_setup(sockline_trig_re, linebuffer, 0, -1)) { + if (!(malware_name = m_pcre_exec(sockline_name_re, av_buffer))) malware_name = US "unknown"; } else /* no virus found */