Closed ycrumeyrolle closed 1 year ago
@ycrumeyrolle Yes, max_time
does nothing. There was an attempt at one point to set a maximum runtime for an evaluation. It turns out that this is not possible to control or even monitor well from within the same process (yes, not thread, process) that is running asteval. Basically, you need a separate process to set a maximum runtime.
We could remove the keyword argument, but it is sort of there to not break the existing API. But it does nothing.
FWIW and as mentioned in the documentation, there is just not a clean way to prevent all DOS possibilities with asteval.
Basically, DOS is a runtime problem that cannot be detected lexically or predicted well ahead of time. Eliminating loops will not help. The classic example is out = x**y**z
.
Try this:
import time
for y in (2, 3, 4, 5, 6, 7, 8, 9):
t0 = time.time()
x = 3**y**8
print("%d %9.5f" % (time.time()-t0))
On my test machine, the runtime ranges from 30 microseconds to 30 seconds. Change that "8" to a "9", and the last evaluation "3**9**9" exceeds 800 seconds. And the point is that this is a single statement of pure Python that actually runs in compiled code in a single opcode. This is not interruptable from that Python process - it is not releasing the GIL etc. It is sort of "stuck in C executable code".
So, unless you want to disallow '**' (or maybe want to add a check for a maximum value of the exponent) then it seems, um challenging, to avoid all possible DOS with any mathematical interpreter.
closing, and see documentation discussion.
The parameter
max_time
seems to be unused. https://github.com/newville/asteval/blob/e34947326cf91e1239f09d372f4719d89b638b7b/asteval/asteval.py#L112-L119The documentation mention it as a parameter, but without detail: https://newville.github.io/asteval/api.html#asteval-api