diff --git a/assets/language/en.json b/assets/language/en.json index ed0fbf4..ea8d2d8 100644 --- a/assets/language/en.json +++ b/assets/language/en.json @@ -99,6 +99,7 @@ "FORBIDDEN_TRACKGROUP_ATTRIBUTE": "Forbidden TrackGroup attribute", "SAFE_EVAL_ERROR": "Safe eval error", "TEMPLATE_USED": "Template used", - "MORE_IN_ERROR_LOG": "More information in the error.log file" + "MORE_IN_ERROR_LOG": "More information in the error.log file", + "COPY_FUNCTION_FORBIDDEN": "Copying functions is forbidden" } } \ No newline at end of file diff --git a/assets/language/fr.json b/assets/language/fr.json index 3815dd9..4b3a919 100644 --- a/assets/language/fr.json +++ b/assets/language/fr.json @@ -100,6 +100,7 @@ "FORBIDDEN_TRACKGROUP_ATTRIBUTE": "Attribut de groupe de course interdit", "SAFE_EVAL_ERROR": "Erreur lors d'un safe eval", "TEMPLATE_USED": "Modèle utilisé", - "MORE_IN_ERROR_LOG": "Plus d'information dans le fichier error.log" + "MORE_IN_ERROR_LOG": "Plus d'information dans le fichier error.log", + "COPY_FUNCTION_FORBIDDEN": "Impossible de copier une fonction" } } \ No newline at end of file diff --git a/source/safe_eval/safe_eval.py b/source/safe_eval/safe_eval.py index 5b3d210..ca5328c 100644 --- a/source/safe_eval/safe_eval.py +++ b/source/safe_eval/safe_eval.py @@ -1,5 +1,4 @@ import ast -import copy from typing import TYPE_CHECKING, Iterable, Callable from source.safe_eval import better_safe_eval_error @@ -24,7 +23,6 @@ class SafeEvalException(Exception): # dict of every value used by every safe_eval call all_globals = { "__builtins__": {}, - "deepcopy": copy.deepcopy } | { func.__name__: func for func in get_all_safe_functions() } @@ -91,7 +89,7 @@ def safe_eval(template: "TemplateSafeEval", env: "Env" = None, macros: dict[str, case ast.NamedExpr: # embed the value into a deepcopy, to avoid interaction with class attribute node.value = ast.Call( - func=ast.Name(id="deepcopy", ctx=ast.Load()), + func=ast.Name(id="copy", ctx=ast.Load()), args=[node.value], keywords=[], ) diff --git a/source/safe_eval/safe_function.py b/source/safe_eval/safe_function.py index b3c1e59..242a78c 100644 --- a/source/safe_eval/safe_function.py +++ b/source/safe_eval/safe_function.py @@ -1,3 +1,4 @@ +import copy from typing import Callable, Generator, TYPE_CHECKING from source.translation import translate as _ @@ -52,3 +53,13 @@ class safe_function: """ from source.safe_eval.safe_eval import safe_eval return safe_eval(template=template, env=env)() + + @staticmethod + def copy(obj: any) -> any: + """ + Deepcopy an object, and raise an exception if it is a function / method. + :param obj: the object to copy + :return: the copied object + """ + if callable(obj): raise Exception(_("COPY_FUNCTION_FORBIDDEN", ' : "', obj.__name__, '"')) + return copy.deepcopy(obj)