Когда оценка JavaScript () не злая?

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

253
задан Peter Mortensen 13 January 2017 в 12:30
поделиться

15 ответов

Я хотел бы занять одну минуту для обращения к предпосылке вопроса - что оценка ()" зло ". Слово" зло ", как используется людьми языка программирования, обычно означает "опасный", или более точно "способный нанести большой ущерб только с выглядящей командой". Так, когда он в порядке для использования чего-то опасного? Когда Вы знаете то, что опасность, и когда Вы принимаете соответствующие меры предосторожности.

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

  • Производительность - оценка () выполняет интерпретатор/компилятор. Если Ваш код компилируется, то это имеет шумный успех, потому что необходимо назвать возможно тяжелый компилятор посреди времени выполнения. Однако JavaScript является все еще главным образом интерпретируемым языком, что означает, что вызов оценки () не является большой производительностью, пораженной в общем случае (но посмотрите мои определенные комментарии ниже).
  • инжекция Кода - оценка () потенциально выполняет строку кода под поднятыми полномочиями. Например, программа, работающая как администратор/корень, никогда не хотела бы к оценке () ввод данных пользователем, потому что тот вход мог потенциально быть "комнатой-rf/etc/important-file" или хуже. Снова, JavaScript в браузере не имеет той проблемы, потому что программа работает в собственной учетной записи пользователя так или иначе. Серверная сторона JavaScript могла иметь ту проблему.

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

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

254
ответ дан user27476 23 November 2019 в 02:51
поделиться

Я верю, что оценка является очень мощной функцией для клиентских веб-приложений и сейфа... Столь же безопасный как JavaScript, которые не являются.:-) проблемами безопасности является по существу проблема серверной стороны, потому что, теперь, с инструментом как Firebug, можно напасть на любое приложение JavaScript.

-1
ответ дан Peter Mortensen 23 November 2019 в 02:51
поделиться

Если этому действительно была нужна оценка, не является злым. Но 99,9% использования оценки, через которую я спотыкаюсь, не необходим (не включая материал setTimeout).

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

0
ответ дан Peter Mortensen 23 November 2019 в 02:51
поделиться

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

Так..., когда не использовать оценку ()? Оценка () не должна только использоваться, когда существует шанс, что третье лицо могло изменить ее. Как прерывание соединения между клиентом и Вашим сервером (но если это - проблемный HTTPS использования). Вы не были должны оценка () для парсинга кода, который записан другими как на форуме.

0
ответ дан Peter Mortensen 23 November 2019 в 02:51
поделиться

Только во время тестирования, если это возможно. Также обратите внимание, что оценка () намного медленнее, чем другой специализированный JSON и т.д. средства анализа.

0
ответ дан Eric Wendelin 23 November 2019 в 02:51
поделиться

Это должно хорошо использовать его, если Вы имеете полный контроль над кодом, это передается эти eval функция.

1
ответ дан John Topley 23 November 2019 в 02:51
поделиться

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

... И 9 раз 10 Вы могли легко постараться не делать это путем рефакторинга.

2
ответ дан Oli 23 November 2019 в 02:51
поделиться

Microsoft объясняет, почему оценка () является медленной в их браузере на Блоге IE, Часть 2 Рекомендаций Производительности IE+JavaScript: Неэффективность кода JavaScript .

3
ответ дан Peter Mortensen 23 November 2019 в 02:51
поделиться

Я видел, что люди рекомендовали не использовать оценку, потому что зло , но я видел, что те же люди использовали Функцию и setTimeout динамично, таким образом, они используют оценку под капотами : D

BTW, если Ваша песочница не достаточно уверена (например, если Вы работаете над сайтом, которые позволяют инжекцию кода) оценка является последним из Ваших проблем. Основное правило безопасности состоит в том, что весь вход является злым, но в случае JavaScript даже сам JavaScript мог быть злым, потому что в JavaScript можно перезаписать любую функцию, и Вы просто не можете быть уверены, что используете реальный, таким образом, если вредоносный код запускается перед Вами, Вы не можете доверять никакой встроенной функции JavaScript: D

Теперь эпилог к этому сообщению:

, Если Вы ДЕЙСТВИТЕЛЬНО потребность это (80% оценки времени НЕ необходимы) и Вы уверены в том, какой Вы' выполнение ре, просто используйте оценку (или лучшая Функция;)), закрытия и ООП покрывают 80/90% случая, где оценка может быть заменена с помощью другого вида логики, остальное динамично сгенерировано код (например, если Вы пишете интерпретатор), и поскольку Вы уже сказали оценку JSON (здесь, можно использовать Crockford безопасная оценка;))

4
ответ дан Peter Mortensen 23 November 2019 в 02:51
поделиться

Я склонен следовать совет Crockford для eval() и избегать его в целом. Даже пути, которые, кажется, требуют его, не делают. Например, эти setTimeout() позволяет Вам передавать функцию, а не оценку

setTimeout(function() {
  alert('hi');
}, 1000);

, Даже если это , доверял источник, я не использую его, потому что код, возвращенный JSON, мог бы быть искажен, который мог в лучшем случае сделать что-то wonky, в худшем случае, представить что-то плохо.

18
ответ дан swilliams 23 November 2019 в 02:51
поделиться

Когда Вы доверяете источнику.

В случае JSON, более или менее трудно вмешаться в источник, потому что это прибывает из веб-сервера, которым Вы управляете. Пока сам JSON не содержит данных, которые загрузил пользователь, нет никакого главного недостатка для использования оценки

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

55
ответ дан Tomalak 23 November 2019 в 02:51
поделиться

eval() не является злым. Или, если это, это является злым таким же образом, что отражение, ввод-вывод файла/сети, поточная обработка и IPC являются "злыми" на других языках.

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

72
ответ дан Peter Mortensen 23 November 2019 в 02:51
поделиться

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

1
ответ дан yfeldblum 23 November 2019 в 02:51
поделиться

Рассматривали ли вы использование Open XML SDK от Microsoft? Единственная зависимость - от .NET 3.5.

Документация: http://msdn.microsoft.com/en-us/library/bb448854%28office.14%29.aspx

Загрузить: http://www.microsoft.com/downloads/details.aspx?familyid=C6E744E5-36E9-45F5-8D8C-331DF206E0D0&displaylang=en[124pting-121--4351503-

Что касается клиентского скрипта, я думаю, что вопрос безопасности - спорный вопрос. Все, что загружается в браузер, может быть изменено и должно рассматриваться как таковое. Существует нулевой риск при использовании оператора eval (), когда есть гораздо более простые способы выполнения кода JavaScript и / или манипулирования объектами в DOM, такими как строка URL-адреса в вашем браузере.

javascript:alert("hello");

Если кто-то хочет манипулировать своей DOM, Я говорю, уходи прочь. Ответственность за безопасность для предотвращения любого типа атак всегда должна лежать на серверном приложении, точка.

С прагматической точки зрения нет никакой пользы от использования eval () в ситуации, когда все можно сделать иначе. Однако в некоторых случаях СЛЕДУЕТ использовать eval. В таком случае это определенно можно сделать без риска взорвать страницу.

<html>
    <body>
        <textarea id="output"></textarea><br/>
        <input type="text" id="input" />
        <button id="button" onclick="execute()">eval</button>

        <script type="text/javascript">
            var execute = function(){
                var inputEl = document.getElementById('input');
                var toEval = inputEl.value;
                var outputEl = document.getElementById('output');
                var output = "";

                try {
                    output = eval(toEval);
                }
                catch(err){
                    for(var key in err){
                        output += key + ": " + err[key] + "\r\n";
                    }
                }
                outputEl.value = output;
            }
        </script>
    <body>
</html>
0
ответ дан 23 November 2019 в 02:51
поделиться

Давайте поговорим о реальных людях:

  1. Каждый крупный браузер теперь имеет встроенную консоль, которую ваш потенциальный хакер может использовать в изобилии для вызова любой функции с любым значением - зачем им вообще использовать оператор eval - даже если они могли?

  2. Если для компиляции 2000 строк JavaScript требуется 0,2 секунды, какова моя деградация производительности, если я оцениваю четыре строки JSON?

Даже объяснение Крокфорда «eval - это зло» слабо.

eval - это зло. Функция eval является наиболее часто используемой функцией JavaScript . Избегайте этого

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

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

Кстати: Prototype.js вызывает eval напрямую пять раз (в том числе в evalJSON () и evalResponse ()). jQuery использует его в parseJSON (через конструктор функций).

23
ответ дан 23 November 2019 в 02:51
поделиться
Другие вопросы по тегам:

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