Skip to content

Commit 855eb10

Browse files
authored
Produce warnings when bad mods are used (#12749)
1 parent 35a329d commit 855eb10

File tree

4 files changed

+55
-18
lines changed

4 files changed

+55
-18
lines changed

plugins/header_rewrite/condition.cc

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,43 +80,43 @@ Condition::initialize(Parser &p)
8080
{
8181
Statement::initialize(p);
8282

83-
if (p.mod_exist("OR")) {
84-
if (p.mod_exist("AND")) {
83+
if (p.consume_mod("OR")) {
84+
if (p.consume_mod("AND")) {
8585
TSError("[%s] Can't have both AND and OR in mods", PLUGIN_NAME);
8686
} else {
8787
_mods |= CondModifiers::OR;
8888
}
89-
} else if (p.mod_exist("AND")) {
89+
} else if (p.consume_mod("AND")) {
9090
_mods |= CondModifiers::AND;
9191
}
9292

93-
if (p.mod_exist("NOT")) {
93+
if (p.consume_mod("NOT")) {
9494
_mods |= CondModifiers::NOT;
9595
}
9696

9797
// The NOCASE / CASE modifier is a bit special, since it ripples down into the Matchers for
9898
// strings and regexes.
9999
int _substr_seen = 0;
100100

101-
if (p.mod_exist("NOCASE")) {
101+
if (p.consume_mod("NOCASE")) {
102102
_mods |= CondModifiers::MOD_NOCASE;
103-
} else if (p.mod_exist("CASE")) {
103+
} else if (p.consume_mod("CASE")) {
104104
// Nothing to do — default is case-sensitive, but still allow this string for clearness.
105105
}
106106

107-
if (p.mod_exist("EXT")) {
107+
if (p.consume_mod("EXT")) {
108108
_mods |= CondModifiers::MOD_EXT;
109109
_substr_seen++;
110110
}
111-
if (p.mod_exist("SUF")) {
111+
if (p.consume_mod("SUF")) {
112112
_mods |= CondModifiers::MOD_SUF;
113113
_substr_seen++;
114114
}
115-
if (p.mod_exist("PRE")) {
115+
if (p.consume_mod("PRE")) {
116116
_mods |= CondModifiers::MOD_PRE;
117117
_substr_seen++;
118118
}
119-
if (p.mod_exist("MID")) {
119+
if (p.consume_mod("MID")) {
120120
_mods |= CondModifiers::MOD_MID;
121121
_substr_seen++;
122122
}
@@ -125,10 +125,10 @@ Condition::initialize(Parser &p)
125125
throw std::runtime_error("Only one substring modifier (EXT, SUF, PRE, MID) may be used.");
126126
}
127127

128-
// Deal with the "last" modifier as well.
129-
if (p.mod_exist("L")) {
128+
if (p.consume_mod("L")) {
130129
_mods |= CondModifiers::MOD_L;
131130
}
132131

133132
_cond_op = parse_matcher_op(p.get_arg());
133+
p.validate_mods();
134134
}

plugins/header_rewrite/operator.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,19 @@ Operator::initialize(Parser &p)
3838
{
3939
Statement::initialize(p);
4040

41-
if (p.mod_exist("L") || p.mod_exist("LAST")) {
41+
if (p.consume_mod("L") || p.consume_mod("LAST")) {
4242
_mods = static_cast<OperModifiers>(_mods | OPER_LAST);
4343
}
4444

45-
if (p.mod_exist("QSA")) {
45+
if (p.consume_mod("QSA")) {
4646
_mods = static_cast<OperModifiers>(_mods | OPER_QSA);
4747
}
4848

49-
if (p.mod_exist("I") || p.mod_exist("INV")) {
49+
if (p.consume_mod("I") || p.consume_mod("INV")) {
5050
_mods = static_cast<OperModifiers>(_mods | OPER_INV);
5151
}
52+
53+
p.validate_mods();
5254
}
5355

5456
void

plugins/header_rewrite/parser.cc

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,12 @@ Parser::preprocess(std::vector<std::string> tokens)
181181
std::string t;
182182

183183
while (getline(iss, t, ',')) {
184-
_mods.push_back(t);
184+
if (std::find(_mods.begin(), _mods.end(), t) != _mods.end()) {
185+
// This produces an error, but it's not fatal for load / reload. ToDo: ATS v11 fix.
186+
TSError("[%s] Duplicate modifier: %s", PLUGIN_NAME, t.c_str());
187+
} else {
188+
_mods.push_back(t);
189+
}
185190
}
186191
} else {
187192
_mods.push_back(m);
@@ -303,6 +308,26 @@ Parser::cond_is_hook(TSHttpHookID &hook) const
303308
return false;
304309
}
305310

311+
// This is a TSError() here, but where this is called from does not treat "false" as a
312+
// load failure. This is a systemic problem in a some of the parsing. ToDo: ATS v11 fix.
313+
bool
314+
Parser::validate_mods() const
315+
{
316+
if (_mods.empty()) {
317+
return true;
318+
}
319+
320+
auto it = _mods.begin();
321+
std::string list = *it++;
322+
323+
for (; it != _mods.end(); ++it) {
324+
list += ", ";
325+
list += *it;
326+
}
327+
TSError("[%s] Unknown modifier(s): [%s]", PLUGIN_NAME, list.c_str());
328+
return false;
329+
}
330+
306331
HRWSimpleTokenizer::HRWSimpleTokenizer(const std::string &line)
307332
{
308333
ParserState state = PARSER_DEFAULT;

plugins/header_rewrite/parser.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,22 @@ class Parser
195195
return _val;
196196
}
197197

198+
// Check if the modifier exists and consume it from the list.
198199
bool
199-
mod_exist(const std::string &m) const
200+
consume_mod(const std::string &m)
200201
{
201-
return std::find(_mods.begin(), _mods.end(), m) != _mods.end();
202+
auto it = std::find(_mods.begin(), _mods.end(), m);
203+
204+
if (it != _mods.end()) {
205+
_mods.erase(it);
206+
return true;
207+
}
208+
return false;
202209
}
203210

211+
// Validate that all modifiers were consumed; logs error and returns false if not
212+
bool validate_mods() const;
213+
204214
bool cond_is_hook(TSHttpHookID &hook) const;
205215

206216
const std::vector<std::string> &

0 commit comments

Comments
 (0)