LINUX.ORG.RU

А чем так плоха функция eval() в питоне?

 , , ,


0

1

Недавно я попробовал сделать свой калькулятор на питоне. Но все застопорилось на моменте, когда надо было как-то преобразовать тип «строки» в арифметические операции, а такого в обычном преобразовании типов нет. И чтобы не городить небоскребы из if’ов, мне подсказали, что есть такая функция eval(), которая сделает все как надо.

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

Но тут я полистал форумы, и на многих форумах отговаривают от использования eval(). Пишут, что использовать эту функцию нежелательно, т.к. она отъедает много ресурсов процессора, и вообще небезопасна, т.к. можно пропихнуть через эту функцию вредоносный код.

Так ли это на самом деле? Что за вредоносный код? Зачем кому-то пропихивать его в своей же программе? Если все так плохо, какие еще варианты?

Перемещено leave из general


Что за вредоносный код? Зачем кому-то пропихивать его в своей же программе?

Кажется каникулы начались.

cloun1902
()
Ответ на: комментарий от cloun1902

Не знаю, может у кого-то и начались. В другой теме мне посоветовали функцию eval() как идеальное решение для калькулятора. Но на многих форумах пишут, что лучше ей не пользоваться, т.к. она небезопасная, хотелось бы понять почему, и в каких конкретно случаях она небезопасная (и что можно с этим сделать).

utrack
() автор топика

Т.е. фраза «выполнение произвольного кода из переданных аргументов» тебе ни о чем не говорит? Тогда брысь обратно в школу.

gruy ★★★★★
()
Ответ на: комментарий от utrack

Не знаю, может у кого-то и начались.

Не палишься, молодец.

Но на многих форумах пишут, что лучше ей не пользоваться, т.к. она небезопасная

Гугл знае про это. Причём безотносительно питона.

cloun1902
()

Погуглил еще, пишут что eval() везде опасен - в Python, JavaScript, PHP, и вообще использовать его никогда не надо. Вот еще нашел статью с примером на питоне.

https://habr.com/ru/post/221937/

Это очень мощная, но в то же время и очень опасная инструкция, особенно если строки, которые вы передаёте в eval, получены не из доверенного источника. Что будет, если строкой, которую мы решим скормить eval'у, окажется os.system('rm -rf /')? Интерпретатор честно запустит процесс удаления всех данных с компьютера

Т.е. получается, функция безопасна, только когда ты единственный пользователь своей программы?

utrack
() автор топика
Ответ на: комментарий от utrack

нет, ведь ты можешь по ошибке передать туда код, который не следует исполнять //покормил бота

anonymous
()

Почему плоха? Главное контролировать, какая строка в нее попала, или выполнится любой код, который eval сможет интерпретировать. Можно же и так считать факториал (pwsh) iex $((1..10) -join '*')

anonymous
()
Ответ на: комментарий от utrack

в твоем случае да. в песочнице, из которой ничего не выносится наружу много чего безопасно.
прост потом такие «программисты из песочницы» начинают вставлять эвелинку в свои последующие рабочие/отвественные проекты, а там она своей дырдочкой начинает светить везде где не нужно… просто не привыкай.

pfg ★★★★★
()
Ответ на: комментарий от kardapoltsev

Вообще интересно, почему система позволяет питону, который запускается от простого юзера, выполнить такую команду, явно требующую привилегий админа в обычной консоли.

utrack
() автор топика
Ответ на: комментарий от utrack

Лол, а почему система должна требовать привелегий root для удаления содержимого домашнего каталога юзера?

Aswed ★★★★★
()

Так ли это на самом деле?

да

Что за вредоносный код?

тот, который введет юзер

Зачем кому-то пропихивать его в своей же программе?

вопрос некорректный

Если все так плохо, какие еще варианты?

Тебе в предыдущем треде ответили. Читай внимательно.

Aswed ★★★★★
()

Ты неправильно задаешь вопрос. Начни с того для чего вообще в разных ЯП существует такая функция. Мне сейчас лень писать, ибо ночь у меня глубокая. Даже странно, что адепты метапрога еще не пришли в тред.

ilinsky ★★★★★
()
Ответ на: комментарий от Aswed

Почему домашнего? Еще раз посмотри пример отсюда.

https://habr.com/ru/post/221937/

Что будет, если строкой, которую мы решим скормить eval’у, окажется os.system(‘rm -rf /’)? Интерпретатор честно запустит процесс удаления всех данных с компьютера

utrack
() автор топика
Ответ на: комментарий от utrack

~~

Почему домашнего?

По качану, еще раз перечитай, что тебе ответили. Или ты не улавливаешь разницу между / и ~?

anonymous
()
Ответ на: комментарий от utrack

Внимательней читай, я HOME предложил почистить от лишнего мусора.

kardapoltsev ★★★★★
()

Ну, допустим, от инъекции кода в калькулятор вы избавитесь, будете проверять, что строка состоит из чисел, арифметических операторов и скобок. Потом решите добавить синус и косинус, притащите регулярные выражения, которые будут выцеплять идентификаторы и сравнивать с whitelist. Потом перечитаете техзадание, поймёте что ^ должно быть возведением в степень, станете заменять его на ** текстовой подстановкой, налажаете в регекспах, поправитесь. Потом захотите оператор %%% (хз что делает, но) чтоб был право-ассоциативный и по приоритету между сложением и умножением. Тут-то и придётся писать нормальный парсер, ну и стоило тогда огород городить?

В общем, зависит от постановки задачи: «вычислить кусок питона» это прямая задача для eval, «вычислить питоновское арифметическое выражение с адски урезанными возможностями и без побочных эффектов» уже так не очень, но можно втиснуть, «сделать удобный калькулятор и потом его развивать» как-то совсем не.

В учебных задачах на «сделать калькулятор» eval часто считается читерством (может и не считаться, наверное, если курс про какое-нибудь художественное гуерисованиe).

LeninGad
()

А чем так плоха функция eval() в питоне?

Это вопрос типа «почему плохо лезть руками в высоковольтный трансформатор». 🙂

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

Потому ответ: если вы понимаете все последствия её использования, то вы можете её использовать там, где это нужно.

Если вы этого пока не понимаете ­— то поверьте на слово, вам эту функцию использовать рано.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.