Подтвердить что ты не робот

Почему существует ограничение длины для python eval?

Я не утверждаю, что это будет хорошей идеей, но я обнаружил, что вы можете скомпрометировать Python (отметки 2.7 и 3.2), запустив eval на достаточно большой строке ввода:

def kill_python(N):
    S = '+'.join((str(n) for n in xrange(N)))
    return eval(S)

На моем компьютере S может быть сгенерирован просто отлично, но для значений приблизительно N>74900 Python завершится с Segmentation fault (core dumped). Есть ли ограничение на длину строки (или дерева разбора), которую может обрабатывать интерпретатор?

Примечание. Мне не нужно это делать, для меня это более глубокий вопрос, отражающий мое незнание того, что происходит внутри коробки. Я хотел бы понять, почему Python здесь не работает, и так катастрофически (почему бы не выбрасывать исключение?)

4b9b3361

Ответ 1

Эта проблема вызвана переполнением стека в компиляторе CPython. Простой способ воспроизвести ту же проблему -

>>> code = compile("1" + "+1" * 1000000, "", "eval")
Segmentation fault

что доказывает, что segfault происходит на этапе компиляции, а не во время оценки. (Конечно, это также легко подтвердить с помощью gdb.)

[Замечание: для небольших выражений компилятор в любом случае будет применять постоянную фальцовку, поэтому единственное, что происходит во время выполнения кода, - загрузить результат:

>>> code = compile("1" + "+1" * 1000, "", "eval")
>>> eval(code)
1001
>>> dis.dis(code)
  1           0 LOAD_CONST            1000 (1001)
              3 RETURN_VALUE        

Конец боковой заметки.]

Эта проблема - известный дефект. Разработчики Python собрали несколько способов свернуть интерпретатор Python в каталог Lib/test/crashers исходного дистрибутива. Тот, который соответствует этой проблеме, Lib/test/crashers/compiler_recursion.py.