Skip to content

Commit a3f17e8

Browse files
Merge pull request #256 from thorinaboenke/fix_regex_output_varibles
Clear regex output variables
2 parents a625843 + bab8495 commit a3f17e8

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

src/attackmate/executors/common/regexexecutor.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ def register_outputvars(self, outputvars: dict, matches):
4343
if not matches:
4444
self.logger.debug('no match!')
4545
self.varstore.set_variable('REGEX_MATCHES_LIST', [])
46+
# Clear the output variables so a stale value from a previous
47+
# loop iteration doesn't produce a false positive when the
48+
# current input has no match.
49+
for k in outputvars:
50+
self.varstore.set_variable(k, '')
4651
return
4752

4853
for k, v in outputvars.items():
@@ -73,7 +78,7 @@ async def _exec_cmd(self, command: RegExCommand) -> Result:
7378
if m3 is not None and isinstance(m3, Match):
7479
self.forge_and_register_variables(command.output, m3.group())
7580
else:
76-
self.varstore.set_variable('REGEX_MATCHES_LIST', [])
81+
self.forge_and_register_variables(command.output, None)
7782
if command.mode == 'sub':
7883
if command.replace:
7984
replaced = re.sub(command.cmd, command.replace, self.varstore.get_str(command.input))

test/units/test_regexexecutor.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ async def test_exec_cmd_findall_no_match(self):
129129
output={'output_var': 'Found: $MATCH_0'},
130130
)
131131
await self.executor._exec_cmd(command)
132-
assert 'output_var' not in self.varstore.variables
132+
assert self.varstore.get_variable('output_var') == ''
133133
assert self.varstore.get_variable('REGEX_MATCHES_LIST') == []
134134

135135
@pytest.mark.asyncio
@@ -156,7 +156,7 @@ async def test_exec_cmd_search_no_match(self):
156156
output={'output_var': 'Found: $MATCH_0'},
157157
)
158158
await self.executor._exec_cmd(command)
159-
assert 'output_var' not in self.varstore.variables
159+
assert self.varstore.get_variable('output_var') == ''
160160
assert self.varstore.get_variable('REGEX_MATCHES_LIST') == []
161161

162162
@pytest.mark.asyncio
@@ -175,3 +175,20 @@ async def test_exec_cmd_sub_no_match(self):
175175
await self.executor._exec_cmd(command)
176176
assert self.varstore.get_variable('output_var') == 'Replaced: no matches here'
177177
assert self.varstore.get_variable('REGEX_MATCHES_LIST') == ['no matches here']
178+
179+
@pytest.mark.asyncio
180+
async def test_exec_cmd_search_no_match_clears_stale_value(self):
181+
# Regression: in a loop a previous iteration might set output
182+
# variable. A following no-match must clear it, not leave the old value.
183+
self.varstore.set_variable('PORT_STATUS', 'open')
184+
self.varstore.set_variable('input_var', 'closed')
185+
command = RegExCommand(
186+
type='regex',
187+
cmd='open',
188+
mode='search',
189+
input='input_var',
190+
output={'PORT_STATUS': '$MATCH_0'},
191+
)
192+
await self.executor._exec_cmd(command)
193+
assert self.varstore.get_variable('PORT_STATUS') == ''
194+
assert self.varstore.get_variable('REGEX_MATCHES_LIST') == []

0 commit comments

Comments
 (0)