Открыть сервис

Функция eval в языках программирования

Функция eval — это встроенная конструкция ряда языков программирования, которая принимает строку (или иной исполняемый объект) и интерпретирует её как программный код, выполняя его в текущем контексте. Такая возможность позволяет программе динамически порождать и исполнять инструкции во время выполнения, что отличает eval от обычного статического разбора исходного текста на этапе компиляции.

Общая характеристика

Семантика eval зависит от языка. В интерпретируемых средах (Python, JavaScript, PHP, Perl, Ruby, Lisp) строка разбирается парсером и исполняется немедленно. В компилируемых языках (C, C++, Java, C#) аналога в стандартной библиотеке обычно нет: динамическое исполнение кода там реализуется иными механизмами — отражением (reflection), генерацией байт-кода или внешними интерпретаторами.

Ключевые особенности:

  • Контекст исполнения. Код, переданный в eval, обычно получает доступ к переменным и функциям окружающей области видимости (в JavaScript — к локальной, в Python — к глобальной и локальной).
  • Возвращаемое значение. Если строка содержит выражение, eval возвращает его результат; если инструкцию — результат зависит от языка (например, в Python eval работает только с выражениями, а exec — с инструкциями).
  • Тип аргумента. В большинстве языков аргументом служит строка; в Lisp-подобных языках — уже готовая структура данных (S-выражение).

Примеры в языках

ЯзыкКонструкцияОсобенность
Pythoneval(), exec()eval — только выражения, exec — любые инструкции
JavaScripteval(), Function()Прямой и косвенный вызов различаются по области видимости
PHPeval()Выполняет код в текущей области; возвращает значение return
PerlevalИспользуется также для перехвата исключений
LispevalОдна из базовых функций; код и данные изоморфны
Rubyeval, instance_evalНесколько вариантов с разным контекстом

В Python различают eval, принимающий выражение (eval("2 + 2") вернёт 4), и exec, выполняющий произвольный блок кода. В JavaScript прямой вызов eval исполняется в локальной области видимости, а косвенный (например, (0, eval)(code)) — в глобальной.

Применение

eval используется в задачах, где код формируется во время работы программы:

  • калькуляторы и интерпретаторы пользовательских формул;
  • конфигурационные файлы, записанные в виде кода;
  • системы плагинов и скриптов;
  • метапрограммирование и генерация кода;
  • REPL-среды и отладчики.

Риски и критика

Основная проблема eval — безопасность. Если строка поступает из ненадёжного источника (ввод пользователя, сеть, файл), злоумышленник может внедрить произвольный код, что ведёт к выполнению команд, краже данных или компрометации системы. Это делает eval классическим примером уязвимости типа «инъекция кода».

Дополнительные недостатки:

  • Производительность. Строка разбирается и компилируется во время выполнения, что медленнее заранее скомпилированного кода.
  • Отладка. Ошибки в динамически исполняемом коде труднее локализовать; трассировка стека усложняется.
  • Читаемость и статический анализ. Инструменты анализа кода не могут предсказать содержимое строки, что затрудняет проверку и оптимизацию.
  • Оптимизация компилятором. Наличие eval часто блокирует ряд оптимизаций, поскольку область видимости становится непредсказуемой.

В связи с этим во многих руководствах по стилю eval относят к нежелательным конструкциям. Рекомендуемые альтернативы: специализированные парсеры выражений, таблицы соответствия (словари функций), модули ast.literal_eval в Python для безопасного разбора литералов, сериализация данных в форматах JSON или YAML вместо исполняемого кода.

Регулирование в веб-среде

В браузерах политика безопасности контента (CSP) позволяет запретить использование eval директивой, блокирующей небезопасное исполнение строк. Это снижает риск XSS-атак, при которых внедрённый скрипт исполняется через eval. Аналогично в серверных средах применяют песочницы и ограничение прав процессов, исполняющих динамический код.

IRONLIVE — база данных и аналитика по компаниям России.

На главную IRONLIVE →