Задать вопрос
26DiDi12
@26DiDi12
Энтузиаст :3

Как работать с командой eval?

Вот код:

var result = message.content.split(" ").slice(1).join(" ")
    let evaled = eval(result);

Все математические выражения он вычисляет, но если сделать сломанное выражение (например "2+", просто без второй цифры), то бот ломается. Как это исправить?
  • Вопрос задан
  • 593 просмотра
Подписаться 3 Средний Комментировать
Решения вопроса 1
Не использовать eval, а парсить уравнение самостоятельно или при помощи какой-нибудь готовой библиотеки.
Например вот: https://nerdamer.com/ или https://mathjs.org/
PS: серьезно. Не используйте eval. Никогда
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
SagePtr
@SagePtr
Еда - это святое
Использовать eval на стороне сервера, да ещё и отдавать на выполнение данные, полученные от пользователей - верный способ отдать сервер на растерзание злоумышленникам. Худшей дыры невозможно себе представить. Даже опаснее, чем SQL-инъекции - там-то хотя бы дальше базы данных злоумышленник залезть не сможет, а тут - сможет легко получить полный доступ ко всей инфраструктуре под правами пользователя, под которым запущена nodejs.
Ответ написан
Alexandroppolus
@Alexandroppolus
кодир
В node.js, кстати, есть превосходная альтернатива евалу - модуль vm

Он умеет запускать код в совершенно изолированной песочнице, где нет ничего, кроме стандартной библиотеки js. То есть никаких require, импортов, взаимодействий с операционной системой и т.д. Там нет даже setTimeout! Всё необходимое ты сам передаешь внутрь через "контекст". Вот в нем и можно запустить код безопасно. Если код свалится от синтаксической ошибки, как в примере из вопроса, то надо просто обернуть вызов в try-catch
try {
    vm.runInNewContext(code, {}); // второй параметр - тот самый "контекст", см. примеры
} catch (e) {
    console.log('error: ', e.message);
}

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

потому, если исполняемый код ограничен только математическим выражением, то таки да, лучше кастомный парсер.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы