diff --git a/buildtools/re2/cre2.patch b/buildtools/re2/cre2.patch index 8f609e34fc73..8ef08f3c16eb 100644 --- a/buildtools/re2/cre2.patch +++ b/buildtools/re2/cre2.patch @@ -1,8 +1,36 @@ diff --git a/src/cre2.cpp b/src/cre2.cpp -index 5a63b93..12bc2ed 100644 +index 5a63b93..54152ff 100644 --- a/src/cre2.cpp +++ b/src/cre2.cpp -@@ -462,7 +462,6 @@ DEFINE_MATCH_REX_FUN2(cre2_find_and_consume_re,FindAndConsumeN) +@@ -288,6 +288,27 @@ cre2_match (const cre2_regexp_t *re , const char *text, + } + return (retval)? 1 : 0; + } ++ ++int ++cre2_match8 (const cre2_regexp_t *re , const char *text, ++ int textlen, int startpos, int endpos, cre2_anchor_t anchor, ++ cre2_string_t *match, int nmatch) ++{ ++ re2::StringPiece text_re2(text, textlen); ++ re2::StringPiece match_re2[8]; ++ RE2::Anchor anchor_re2 = to_cre2_anchor(anchor); ++ bool retval; // 0 for no match ++ // 1 for successful matching ++ retval = TO_CONST_RE2(re)->Match(text_re2, startpos, endpos, anchor_re2, match_re2, 8); ++ if (retval) { ++ for (int i=0; i<8; i++) { ++ match[i].data = match_re2[i].data(); ++ match[i].length = match_re2[i].length(); ++ } ++ } ++ return (retval)? 1 : 0; ++} ++ + int + cre2_easy_match (const char * pattern, int pattern_len, + const char *text, int text_len, +@@ -462,7 +483,6 @@ DEFINE_MATCH_REX_FUN2(cre2_find_and_consume_re,FindAndConsumeN) int cre2_replace (const char * pattern, cre2_string_t * text_and_target, cre2_string_t * rewrite) { @@ -10,7 +38,7 @@ index 5a63b93..12bc2ed 100644 std::string S(text_and_target->data, text_and_target->length); re2::StringPiece R(rewrite->data, rewrite->length); char * buffer; /* this exists to make GCC shut up about const */ -@@ -477,12 +476,6 @@ cre2_replace (const char * pattern, cre2_string_t * text_and_target, cre2_string +@@ -477,12 +497,6 @@ cre2_replace (const char * pattern, cre2_string_t * text_and_target, cre2_string } else return -1; return int(retval); @@ -23,3 +51,19 @@ index 5a63b93..12bc2ed 100644 } int cre2_replace_re (cre2_regexp_t * rex, cre2_string_t * text_and_target, cre2_string_t * rewrite) +diff --git a/src/cre2.h b/src/cre2.h +index 92eaf65..a34051f 100644 +--- a/src/cre2.h ++++ b/src/cre2.h +@@ -160,6 +160,11 @@ cre2_decl int cre2_match (const cre2_regexp_t * re, + int startpos, int endpos, cre2_anchor_t anchor, + cre2_string_t * match, int nmatch); + ++cre2_decl int cre2_match8 (const cre2_regexp_t * re, ++ const char * text, int textlen, ++ int startpos, int endpos, cre2_anchor_t anchor, ++ cre2_string_t * match, int nmatch); ++ + cre2_decl int cre2_easy_match (const char * pattern, int pattern_len, + const char * text, int text_len, + cre2_string_t * match, int nmatch); diff --git a/internal/operators/rx.go b/internal/operators/rx.go index 5f5052095a4d..791f2ce0a186 100644 --- a/internal/operators/rx.go +++ b/internal/operators/rx.go @@ -26,16 +26,9 @@ func (o *rx) Init(options coraza.RuleOperatorOptions) error { } func (o *rx) Evaluate(tx *coraza.Transaction, value string) bool { - matches := o.re.FindStringSubmatch(value, 8) - if len(matches) == 0 { - return false - } - - if tx.Capture { - for i, c := range matches { - tx.CaptureField(i, c) + return o.re.FindStringSubmatch8(value, func(i int, match string) { + if tx.Capture { + tx.CaptureField(i, match) } - } - - return true + }) } diff --git a/internal/re2/re2.go b/internal/re2/re2.go index 44a1c79154d5..b96e4d98bf2b 100644 --- a/internal/re2/re2.go +++ b/internal/re2/re2.go @@ -21,6 +21,10 @@ func cre2Delete(rePtr unsafe.Pointer) func cre2Match(rePtr unsafe.Pointer, textPtr unsafe.Pointer, textLen uint32, startPos uint32, endPos uint32, anchor uint32, matchArrPtr unsafe.Pointer, nmatch uint32) uint32 +//export cre2_match8 +func cre2Match8(rePtr unsafe.Pointer, textPtr unsafe.Pointer, textLen uint32, startPos uint32, endPos uint32, + anchor uint32, matchArrPtr unsafe.Pointer, nmatch uint32) uint32 + type RegExp struct { ptr unsafe.Pointer } @@ -33,14 +37,14 @@ func Compile(pattern string) (RegExp, error) { return RegExp{ptr: rePtr}, nil } -func (re RegExp) FindStringSubmatch(text string, n int) []string { +func (re RegExp) FindStringSubmatch8(text string, f func(int, string)) bool { sh := (*reflect.StringHeader)(unsafe.Pointer(&text)) // Array of cre2_string_t, which is const char* and int, easiest way to get it is an array of ints. - matchArr := make([]uint32, 2*n) + var matchArr [16]uint32 matchArrPtr := unsafe.Pointer(&matchArr[0]) - res := cre2Match(re.ptr, unsafe.Pointer(sh.Data), uint32(sh.Len), 0, uint32(sh.Len), 0, matchArrPtr, uint32(n)) + res := cre2Match8(re.ptr, unsafe.Pointer(sh.Data), uint32(sh.Len), 0, uint32(sh.Len), 0, matchArrPtr, 8) if res == 0 { - return nil + return false } // Pointer math! re2 will return matches which are memory pointers into memory corresponding to text. @@ -48,8 +52,7 @@ func (re RegExp) FindStringSubmatch(text string, n int) []string { // pointers directly. textPtr := uint32(sh.Data) - var matches []string - for i := 0; i < n; i++ { + for i := 0; i < 8; i++ { sPtr := matchArr[2*i] if sPtr == 0 { break @@ -57,7 +60,8 @@ func (re RegExp) FindStringSubmatch(text string, n int) []string { sLen := matchArr[2*i+1] textIdx := sPtr - textPtr - matches = append(matches, text[textIdx:textIdx+sLen]) + f(i, text[textIdx:textIdx+sLen]) } - return matches + + return true } diff --git a/lib/libcre2.a b/lib/libcre2.a index ebe1cfd0ec61..d06e68a31e57 100644 Binary files a/lib/libcre2.a and b/lib/libcre2.a differ