Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 95f16ea

Browse files
committed
Add proper error handling to @rx operator
1 parent 5437b44 commit 95f16ea

File tree

7 files changed

+102
-7
lines changed

7 files changed

+102
-7
lines changed

‎src/operators/rx.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ namespace operators {
2929

3030
bool Rx::init(const std::string &arg, std::string *error) {
3131
if (m_string->m_containsMacro == false) {
32+
std::string regex_error;
3233
m_re = new Regex(m_param);
34+
if (!m_re->ok(&regex_error)) {
35+
*error = "Failed to compile regular expression " + m_re->getPattern() + ": " + regex_error;
36+
return false;
37+
}
3338
}
3439

3540
return true;
@@ -47,6 +52,14 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule,
4752
if (m_string->m_containsMacro) {
4853
std::string eparam(m_string->evaluate(transaction));
4954
re = new Regex(eparam);
55+
std::string regex_error;
56+
if (!re->ok(&regex_error)) {
57+
ms_dbg_a(transaction, 2,
58+
"Failed to compile regular expression with macro "
59+
+ re->getPattern() + ": " + regex_error);
60+
delete re;
61+
return false;
62+
}
5063
} else {
5164
re = m_re;
5265
}

‎src/regex/backend/backend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Backend {
2929
public:
3030
virtual ~Backend() {}
3131

32-
virtual bool ok() const = 0;
32+
virtual bool ok(std::string *error = nullptr) const = 0;
3333

3434
virtual std::list<RegexMatch> searchAll(const std::string& s) const = 0;
3535
virtual bool searchOneMatch(const std::string& s, std::vector<RegexMatchCapture>& captures) const = 0;

‎src/regex/backend/pcre.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,18 @@ Pcre::Pcre(const std::string& pattern_)
4444

4545
m_pc = pcre_compile(pattern.c_str(), PCRE_DOTALL|PCRE_MULTILINE,
4646
&errptr, &erroffset, NULL);
47+
if (m_pc == NULL) {
48+
m_error = "pcre_compile error at offset " + std::to_string(erroffset) + ": " + std::string(errptr);
49+
return;
50+
}
4751

4852
m_pce = pcre_study(m_pc, pcre_study_opt, &errptr);
53+
if (m_pce == NULL) {
54+
m_error = "pcre_study error: " + std::string(errptr);
55+
pcre_free(m_pc);
56+
m_pc = nullptr;
57+
return;
58+
}
4959
}
5060

5161

‎src/regex/backend/pcre.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,15 @@ class Pcre : public Backend {
5252
int search(const std::string &s, RegexMatch *m) const override;
5353
int search(const std::string &s) const override;
5454

55-
virtual bool ok() const override {
56-
return m_pc != NULL;
55+
virtual bool ok(std::string *error = nullptr) const override {
56+
if (m_pc != NULL) {
57+
return true;
58+
}
59+
if (error != nullptr) {
60+
*error= m_error;
61+
}
62+
63+
return false;
5764
}
5865

5966
virtual const std::string& getPattern() const override {
@@ -64,6 +71,8 @@ class Pcre : public Backend {
6471

6572
pcre *m_pc = NULL;
6673
pcre_extra *m_pce = NULL;
74+
75+
std::string m_error;
6776
};
6877

6978
#endif

‎src/regex/backend/re2.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,14 @@ class Re2 : public Backend {
4545
bool searchOneMatch(const std::string& s, std::vector<RegexMatchCapture>& captures) const override;
4646
int search(const std::string &s, RegexMatch *m) const override;
4747
int search(const std::string &s) const override;
48-
virtual bool ok() const override {
49-
return re.ok();
48+
virtual bool ok(std::string *error = nullptr) const override {
49+
if (re.ok()) {
50+
return true;
51+
}
52+
if (error != nullptr) {
53+
*error = re.error();
54+
}
55+
return false;
5056
}
5157

5258
virtual const std::string& getPattern() const override {

‎src/regex/backend_fallback.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class BackendFallback : public backend::Backend {
4545
: backend(compile_regex_fallback<Args...>(pattern))
4646
{}
4747

48-
virtual bool ok() const override {
49-
return backend->ok();
48+
virtual bool ok(std::string *error = nullptr) const override {
49+
return backend->ok(error);
5050
}
5151

5252
std::list<RegexMatch> searchAll(const std::string& s) const override {

‎test/test-cases/regression/operator-rx.json

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,62 @@
8585
"SecRuleEngine On",
8686
"SecRule REQUEST_HEADERS:Content-Length \"!^0$\" \"id:1,phase:2,pass,t:trim,block\""
8787
]
88+
},
89+
{
90+
"enabled":1,
91+
"version_min":300000,
92+
"version_max":0,
93+
"title":"Testing Operator :: @rx with invalid regular expression",
94+
"expected":{
95+
"parser_error":"Rules error.*Failed to compile regular expression \\(\\(value1\\):"
96+
},
97+
"rules":[
98+
"SecRuleEngine On",
99+
"SecRule ARGS \"@rx ((value1)\" \"id:1,phase:2,pass,t:trim\""
100+
]
101+
},
102+
{
103+
"enabled":1,
104+
"version_min":300000,
105+
"title":"Testing Operator :: @rx with invalid regular expression after macro expansion",
106+
"client":{
107+
"ip":"200.249.12.31",
108+
"port":123
109+
},
110+
"server":{
111+
"ip":"200.249.12.31",
112+
"port":80
113+
},
114+
"request":{
115+
"headers":{
116+
"Host":"localhost",
117+
"User-Agent":"curl/7.38.0",
118+
"Accept":"*/*",
119+
"Content-Length": "27",
120+
"Content-Type": "application/x-www-form-urlencoded"
121+
},
122+
"uri":"/",
123+
"method":"POST",
124+
"body": [
125+
"param1=value1&param2=value2"
126+
]
127+
},
128+
"response":{
129+
"headers":{
130+
"Date":"2015年7月13日 20:02:41 GMT",
131+
"Last-Modified":"2014年10月26日 22:33:37 GMT",
132+
"Content-Type":"text/html"
133+
},
134+
"body":[
135+
"no need."
136+
]
137+
},
138+
"expected":{
139+
"debug_log":"Failed to compile regular expression with macro \\(\\(\\):"
140+
},
141+
"rules":[
142+
"SecRuleEngine On",
143+
"SecRule ARGS \"@rx ((%{TX.DOESNT_NEED_TO_EXIST_IT_WILL_BE_AN_EMPTY_STRING})\" \"id:1,phase:2,pass,t:trim\""
144+
]
88145
}
89146
]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /