[#366] Context variables should be dynamically assigned through locals() instead of exec().

Closes: #366
This commit is contained in:
Fabio Manganiello 2024-02-26 21:28:27 +01:00
parent 6c2e9deda4
commit f8e0b5e17e
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774
3 changed files with 7 additions and 65 deletions

View file

@ -1,7 +1,6 @@
import logging
import re
from threading import Thread
import time
from threading import Thread
import requests
from frozendict import frozendict
@ -91,7 +90,7 @@ class HttpRequest:
Thread(target=_thread_func, name='HttpPoll').start()
def get_new_items(self, response):
def get_new_items(self, *_, **__):
"""Gets new items out of a response"""
raise NotImplementedError(
"get_new_items must be implemented in a derived class"
@ -105,34 +104,6 @@ class HttpRequest:
yield key, value
class JsonHttpRequest(HttpRequest):
"""
Specialization of the HttpRequest class for JSON requests.
"""
def __init__(self, *args, path=None, **kwargs):
super().__init__(*args, **kwargs)
self.path = path
self.seen_entries = set()
def get_new_items(self, response):
response = response.json()
new_entries = []
if self.path:
m = re.match(r'\${\s*(.*)\s*}', self.path)
if m:
response = eval(m.group(1)) # pylint: disable=eval-used
for entry in response:
flattened_entry = deep_freeze(entry)
if flattened_entry not in self.seen_entries:
new_entries.append(entry)
self.seen_entries.add(flattened_entry)
return new_entries
def deep_freeze(x):
"""
Deep freezes a Python object - works for strings, dictionaries, sets and

View file

@ -141,19 +141,8 @@ class Request(Message):
for k, v in context.items():
if isinstance(v, Message):
v = json.loads(str(v))
try:
exec('{}={}'.format(k, v)) # pylint: disable=exec-used
except Exception:
if isinstance(v, str):
try:
exec( # pylint: disable=exec-used
'{}="{}"'.format(k, re.sub(r'(^|[^\\])"', '\1\\"', v))
)
except Exception as e2:
logger.debug(
'Could not set context variable %s=%s: %s', k, v, e2
)
logger.debug('Context: %s', context)
locals()[k] = v
parsed_value = ''
if not isinstance(_value, str):

View file

@ -422,10 +422,7 @@ class WhileProcedure(LoopProcedure):
response = Response()
context = self._get_context(**context)
for k, v in context.items():
try:
exec(f'{k}={v}') # pylint: disable=exec-used
except Exception as e:
logger.debug('Evaluation error: %s=%s: %s', k, v, e)
locals()[k] = v
while True:
condition_true = eval(self.condition) # pylint: disable=eval-used
@ -451,10 +448,7 @@ class WhileProcedure(LoopProcedure):
if response.output and isinstance(response.output, dict):
new_context = self._get_context(**response.output)
for k, v in new_context.items():
try:
exec(f'{k}={v}') # pylint: disable=exec-used
except Exception as e:
logger.debug('Evaluation error: %s=%s: %s', k, v, e)
locals()[k] = v
return response
@ -550,19 +544,7 @@ class IfProcedure(Procedure):
def execute(self, *_, **context):
for k, v in context.items():
try:
exec(f'{k}={v}') # pylint: disable=exec-used
except Exception:
if isinstance(v, str):
try:
exec( # pylint: disable=exec-used
f'{k}="' + re.sub(r'(^|[^\\])"', '\1\\"', v) + '"'
)
except Exception as e:
logger.debug(
'Could not set context variable %s=%s: %s', k, v, e
)
logger.debug('Context: %s', context)
locals()[k] = v
condition_true = eval(self.condition) # pylint: disable=eval-used
response = Response()