1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
def test_parsemath():
from ase.utils.parsemath import eval_expression
import math
param_dct = {
"param_1": 1,
"param_2": 4.0,
"param_3": 478245.7586,
"param_4": 1.58e-5,
"param_5": -2.48757,
"param_6": -2.0,
"param_7": math.pi/4.0,
}
expressions = [
"3.0*param_1",
"param_2**-2.0",
"(param_6)**2.0",
"param_1 / param_5",
"param_1 + param_2 * 30.0 - param_5",
"(param_1 + 1) / param_2",
"sqrt(param_2)",
"fmod(param_4, param_1)",
"sin(param_7)",
"cos(param_7)",
"tan(param_7)",
"asin(param_7)",
"acos(param_7)",
"atan(param_7)",
"atan2(param_7, 2.0)",
"hypot(3.0, 4.0)",
"sinh(param_7)",
"cosh(param_7)",
"tanh(param_7)",
"asinh(param_7)",
"acosh(param_2)",
"atanh(param_7)",
"degrees(radians(param_7))",
"log(param_3)",
"log10(param_3)",
"log2(param_3)",
"abs(param_5)",
"ceil(param_5)",
"floor(param_5)",
"round(param_5)",
"exp(param_1)",
"2.0*e",
"pi+1",
"tau / pi",
"param_5 % param_6",
"param_3 // param_6",
]
solutions = [
3*param_dct["param_1"],
param_dct["param_2"]**-2.0,
(param_dct["param_6"])**2.0,
param_dct["param_1"] / param_dct["param_5"],
param_dct["param_1"] + param_dct["param_2"] * 30.0 - param_dct["param_5"],
(param_dct["param_1"] + 1) / param_dct["param_2"],
math.sqrt(param_dct["param_2"]),
math.fmod(param_dct["param_4"], param_dct["param_1"]),
math.sin(param_dct["param_7"]),
math.cos(param_dct["param_7"]),
math.tan(param_dct["param_7"]),
math.asin(param_dct["param_7"]),
math.acos(param_dct["param_7"]),
math.atan(param_dct["param_7"]),
math.atan2(param_dct["param_7"], 2.0),
math.hypot(3.0, 4.0),
math.sinh(param_dct["param_7"]),
math.cosh(param_dct["param_7"]),
math.tanh(param_dct["param_7"]),
math.asinh(param_dct["param_7"]),
math.acosh(param_dct["param_2"]),
math.atanh(param_dct["param_7"]),
math.degrees(math.radians(param_dct["param_7"])),
math.log(param_dct["param_3"]),
math.log10(param_dct["param_3"]),
math.log2(param_dct["param_3"]),
math.fabs(param_dct["param_5"]),
math.ceil(param_dct["param_5"]),
math.floor(param_dct["param_5"]),
round(param_dct["param_5"]),
math.exp(param_dct["param_1"]),
2.0*math.e,
math.pi+1,
2.0,
param_dct["param_5"] % param_dct["param_6"],
]
for expr, soln in zip(expressions, solutions):
assert abs(eval_expression(expr, param_dct) - soln) < 1e-13
try:
eval_expression("99**99**99*99**99**99")
raise RuntimeError("This should not be reached, the parser is now vulnerable to computational time based DNS attack")
except ValueError:
pass
try:
eval_expression("e"*10000000, dict())
raise RuntimeError("This should not be reached, the parser is now vulnerable to memory based DNS attack")
except ValueError:
pass
try:
eval_expression("__import__('os').system('echo $HOME')")
raise RuntimeError("This should not be reached, the parser can execute malicious code")
except TypeError:
pass
|