Skip to content

Commit 0cfdd0e

Browse files
WGH-zimmerle
authored andcommitted
Add RE2 regex backend
1 parent 082a881 commit 0cfdd0e

File tree

4 files changed

+159
-2
lines changed

4 files changed

+159
-2
lines changed

src/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ UTILS = \
247247

248248
REGEX = \
249249
regex/regex.cc \
250-
regex/backend/pcre.cc
250+
regex/backend/pcre.cc \
251+
regex/backend/re2.cc
251252

252253

253254
COLLECTION = \

src/regex/backend/re2.cc

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* ModSecurity, http://www.modsecurity.org/
3+
* Copyright (c) 2019
4+
*
5+
* You may not use this file except in compliance with
6+
* the License. You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* If any of the files related to licensing are missing or if you have any
11+
* other questions related to licensing please contact Trustwave Holdings, Inc.
12+
* directly using the email address security@modsecurity.org.
13+
*
14+
*/
15+
#include <iostream>
16+
#include <fstream>
17+
#include <string>
18+
#include <list>
19+
20+
#include "src/regex/backend/re2.h"
21+
#include "src/regex/regex_match.h"
22+
23+
namespace modsecurity {
24+
namespace regex {
25+
namespace backend {
26+
27+
#ifdef WITH_RE2
28+
29+
static RE2::Options get_re2_options() {
30+
RE2::Options res;
31+
32+
res.set_dot_nl(true);
33+
34+
return res;
35+
}
36+
37+
38+
Re2::Re2(const std::string& pattern_)
39+
: pattern(pattern_.empty() ? ".*" : pattern_),
40+
re(pattern, get_re2_options())
41+
{
42+
}
43+
44+
std::list<RegexMatch> Re2::searchAll(const std::string& s) const {
45+
std::list<RegexMatch> retList;
46+
47+
re2::StringPiece subject(s);
48+
49+
size_t offset = 0;
50+
while (offset <= s.size()) {
51+
int ngroups = re.NumberOfCapturingGroups() + 1;
52+
re2::StringPiece submatches[ngroups];
53+
54+
if (!re.Match(subject, offset, s.size(), RE2::UNANCHORED,
55+
&submatches[0], ngroups)) {
56+
break;
57+
}
58+
59+
for (int i = 0; i < ngroups; i++) {
60+
// N.B. StringPiece::as_string returns value, not reference
61+
auto match_string = submatches[i].as_string();
62+
auto start = &submatches[i][0] - &subject[0];
63+
retList.push_front(RegexMatch(std::move(match_string), start));
64+
}
65+
66+
offset = (&submatches[0][0] - &subject[0]) + submatches[0].length();
67+
if (submatches[0].size() == 0) {
68+
offset++;
69+
}
70+
}
71+
72+
return retList;
73+
}
74+
75+
int Re2::search(const std::string& s, RegexMatch *match) const {
76+
re2::StringPiece subject(s);
77+
re2::StringPiece submatches[1];
78+
if (re.Match(subject, 0, s.size(), RE2::UNANCHORED, &submatches[0], 1)) {
79+
// N.B. StringPiece::as_string returns value, not reference
80+
auto match_string = submatches[0].as_string();
81+
auto start = &submatches[0][0] - &subject[0];
82+
*match = RegexMatch(std::move(match_string), start);
83+
return 1;
84+
} else {
85+
return 0;
86+
}
87+
}
88+
89+
int Re2::search(const std::string& s) const {
90+
re2::StringPiece subject(s);
91+
return re.Match(subject, 0, s.size(), RE2::UNANCHORED, NULL, 0);
92+
}
93+
#endif
94+
95+
} // namespace backend
96+
} // namespace regex
97+
} // namespace modsecurity
98+

src/regex/backend/re2.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* ModSecurity, http://www.modsecurity.org/
3+
* Copyright (c) 2019
4+
*
5+
* You may not use this file except in compliance with
6+
* the License. You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* If any of the files related to licensing are missing or if you have any
11+
* other questions related to licensing please contact Trustwave Holdings, Inc.
12+
* directly using the email address security@modsecurity.org.
13+
*
14+
*/
15+
16+
#ifdef WITH_RE2
17+
#include <re2/re2.h>
18+
#endif
19+
20+
#include <string>
21+
#include <list>
22+
23+
#include "src/regex/regex_match.h"
24+
25+
#ifndef SRC_REGEX_BACKEND_RE2_H_
26+
#define SRC_REGEX_BACKEND_RE2_H_
27+
28+
namespace modsecurity {
29+
namespace regex {
30+
namespace backend {
31+
32+
#ifdef WITH_RE2
33+
34+
class Re2 {
35+
public:
36+
explicit Re2(const std::string& pattern_);
37+
38+
// RE2 class is not copyable, so neither is this
39+
Re2(const Re2&) = delete;
40+
Re2& operator=(const Re2&) = delete;
41+
42+
std::list<RegexMatch> searchAll(const std::string& s) const;
43+
int search(const std::string &s, RegexMatch *m) const;
44+
int search(const std::string &s) const;
45+
46+
const std::string pattern;
47+
private:
48+
const RE2 re;
49+
};
50+
51+
#endif
52+
53+
} // namespace backend
54+
} // namespace regex
55+
} // namespace modsecurity
56+
57+
#endif // SRC_REGEX_BACKEND_PCRE_H_

src/regex/regex.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <list>
2222

2323
#include "src/regex/backend/pcre.h"
24+
#include "src/regex/backend/re2.h"
2425
#include "src/regex/regex_match.h"
2526

2627
#ifndef SRC_REGEX_REGEX_H_
@@ -33,7 +34,7 @@ namespace regex {
3334
#ifdef WITH_PCRE
3435
using selectedBackend = backend::Pcre;
3536
#elif WITH_RE2
36-
//using selectedBackend = backend::Re2;
37+
using selectedBackend = backend::Re2;
3738
#else
3839
#error "no regex backend selected"
3940
#endif

0 commit comments

Comments
 (0)