From f8e0b5e17e5ad05df2059d65713d4810259c166a Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Mon, 26 Feb 2024 21:28:27 +0100 Subject: [PATCH] [#366] Context variables should be dynamically assigned through `locals()` instead of `exec()`. Closes: #366 --- platypush/backend/http/request/__init__.py | 33 ++-------------------- platypush/message/request/__init__.py | 15 ++-------- platypush/procedure/__init__.py | 24 ++-------------- 3 files changed, 7 insertions(+), 65 deletions(-) diff --git a/platypush/backend/http/request/__init__.py b/platypush/backend/http/request/__init__.py index bfce6523ff..c9a41426e7 100644 --- a/platypush/backend/http/request/__init__.py +++ b/platypush/backend/http/request/__init__.py @@ -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 diff --git a/platypush/message/request/__init__.py b/platypush/message/request/__init__.py index 51ec284574..b470b3dc41 100644 --- a/platypush/message/request/__init__.py +++ b/platypush/message/request/__init__.py @@ -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): diff --git a/platypush/procedure/__init__.py b/platypush/procedure/__init__.py index 34c42f88c1..bf3afc0a06 100644 --- a/platypush/procedure/__init__.py +++ b/platypush/procedure/__init__.py @@ -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()