From 24b20d7668eb105d678259596e2d3a03a9b344aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20P=C3=B6hn?= Date: Tue, 22 May 2018 13:08:14 +0200 Subject: [PATCH] use simple ast+operator based calculator for evaluating Vercode Operation --- fdroidserver/checkupdates.py | 2 +- fdroidserver/common.py | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 59e2ddd1..60314160 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -434,7 +434,7 @@ def checkupdates_app(app): .format(field=app.VercodeOperation)) oldvercode = str(int(vercode)) op = app.VercodeOperation.replace("%c", oldvercode) - vercode = str(eval(op)) + vercode = str(common.calculate_math_string(op)) logging.debug("Applied vercode operation: %s -> %s" % (oldvercode, vercode)) if version and any(version.startswith(s) for s in [ diff --git a/fdroidserver/common.py b/fdroidserver/common.py index dcda699a..c1a70003 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -24,6 +24,7 @@ import io import os import sys import re +import ast import shutil import glob import stat @@ -3205,3 +3206,26 @@ def get_git_describe_link(): else: logging.error(_("'{path}' failed to execute!").format(path='git describe')) return '' + + +def calculate_math_string(expr): + ops = {ast.Add: operator.add, ast.Sub: operator.sub, + ast.Mult: operator.mul} + + def execute_ast(node): + if isinstance(node, ast.Num): # + return node.n + elif isinstance(node, ast.BinOp): # + return ops[type(node.op)](execute_ast(node.left), + execute_ast(node.right)) + elif isinstance(node, ast.UnaryOp): # e.g., -1 + return ops[type(node.op)](eval(node.operand)) + else: + raise SyntaxError(node) + + try: + return execute_ast(ast.parse(expr, mode='eval').body) + except SyntaxError as e: + raise SyntaxError("could not parse expression '{expr}', " + "only basic math operations are allowed (+, -, *)" + .format(expr=expr))