From f7bf3f1d8ea5100715435aae08a34fe42b26b425 Mon Sep 17 00:00:00 2001 From: Nils Schnabel Date: Fri, 19 Mar 2021 20:42:38 +0000 Subject: [PATCH] optionally run patterns unrestricted --- ledcontrol/__init__.py | 5 ++++- ledcontrol/animationcontroller.py | 27 +++++++++++++++++++-------- ledcontrol/app.py | 6 ++++-- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/ledcontrol/__init__.py b/ledcontrol/__init__.py index bb5b873..e48d66b 100644 --- a/ledcontrol/__init__.py +++ b/ledcontrol/__init__.py @@ -37,6 +37,8 @@ def main(): help='Do not reset the animation timer when patterns are changed. Default: False') parser.add_argument('--dev', action='store_true', help='Development flag. Default: False') + parser.add_argument('--run-unsafe', dest='run_restricted', action='store_false', help='Do NOT run the pattern Python code in RestrictedPython.') + parser.set_defaults(run_restricted=True) args = parser.parse_args() app = create_app(args.led_count, @@ -51,7 +53,8 @@ def main(): args.save_interval, args.sacn, args.no_timer_reset, - args.dev) + args.dev, + args.run_restricted) if args.dev: app.run(host=args.host, port=args.port) diff --git a/ledcontrol/animationcontroller.py b/ledcontrol/animationcontroller.py index 922cfff..1cd5d07 100644 --- a/ledcontrol/animationcontroller.py +++ b/ledcontrol/animationcontroller.py @@ -24,7 +24,8 @@ def __init__(self, mapping_func, enable_sacn, no_timer_reset, - global_brightness_limit): + global_brightness_limit, + run_restricted): self._led_controller = led_controller self._refresh_rate = refresh_rate self._led_count = led_count @@ -32,6 +33,7 @@ def __init__(self, self._enable_sacn = enable_sacn self._no_timer_reset = no_timer_reset self._global_brightness_limit = global_brightness_limit + self.run_restricted = run_restricted # Initialize prev state array self._prev_state = [(0, 0, 0) for i in range(self._led_count)] @@ -256,21 +258,30 @@ def getiter(obj): restricted_locals = {} arg_names = ['t', 'dt', 'x', 'y', 'z', 'prev_state'] - result = RestrictedPython.compile_restricted_exec(source) - warnings = list(result.warnings) - for name in result.used_names: + results = None + if self.run_restricted: + results = RestrictedPython.compile_restricted_exec(source) + code = results.code + else: + code = compile(source, 'pattern', 'exec') + print('compiled unsafe') + results = type('CompileResult', (object,),{'code': code, 'errors': [], 'warnings': [], 'used_names': []}) + restricted_globals.update(globals()) + + warnings = list(results.warnings) + for name in results.used_names: if name not in restricted_globals and name not in arg_names: warnings.append(f'NameError: name \'{name}\' is not defined') - if result.code: - exec(result.code, restricted_globals, restricted_locals) + if results.code: + exec(results.code, restricted_globals, restricted_locals) - if len(result.errors) == 0 and 'pattern' in restricted_locals: + if len(results.errors) == 0 and 'pattern' in restricted_locals: self._functions[key] = restricted_locals['pattern'] self._check_reset_animation_state() self._update_needed = True - return result.errors, warnings + return results.errors, warnings # Palettes frontend diff --git a/ledcontrol/app.py b/ledcontrol/app.py index b3afae3..6938b2c 100644 --- a/ledcontrol/app.py +++ b/ledcontrol/app.py @@ -28,7 +28,8 @@ def create_app(led_count, save_interval, enable_sacn, no_timer_reset, - dev): + dev, + run_restricted): app = Flask(__name__) # Create pixel mapping function @@ -53,7 +54,8 @@ def create_app(led_count, mapping_func, enable_sacn, no_timer_reset, - led_brightness_limit) + led_brightness_limit, + run_restricted) presets = {} functions = dict(animfunctions.default)