All streams
Search
Write a publication
Pull to refresh
4
0
Сковорода Никита Андреевич @ChALkeRx

re-evaluating native module sources is not suppor…

Send message
Поясните, пожалуйста, зачем выкладывать «расковырянную» версию и почему то, что лежит сейчас на github нереальные исходники? )

Исходники — предпочтительная для внесения изменений форма программы. Вам же самому удобнее вносить изменения в «расковыренную» версию, а эту вы собираете (или я не так понял?). Остальные люди тоже обычно не любят ковырять файлы на 10 тысяч строк, а разбивают на более мелкие куски.


Следовательно, исходники — именно «расковырянная» версия.

Edit: промазал с ответом, извините. Переношу на нужный уровень.

То что вы видите на github, да и на промо сайте — это уже результирующий файл.

Ну так выложите на гитхаб реальные исходники и скрипт для сборки из них тогда =).

Ещё замечание: у вас в единственном файле исходника количество строчек почти дошло до 10 тысяч (9820).
Наверное, надо что-то разбить на более мелкие файлы и затем собирать их в один.

Если вы про https://github.com/DmitryAstafyev/Patterns/commit/3cdd1ba89, то этого будет недостаточно — вы экранируете только < и >.


Ничто не мешает <input value="{{value}}" /> превратиться в <input value="" onmouseover="…">, если я правильно понимаю.


И ещё — этот коммит сломал поля ввода: когда я тут в поле набираю <3 и убираю фокус, видимое содержимое поля превращается в &lt;3.


Вы точно хорошо подумали над архитектурой?

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


Поэтому, пожалуйста, сделайте подстановку значений в шаблон безопасной из коробки =).

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

Неверно (если речь действительно про конкретную модель, а не про включение глобального флага «экранировать всё везде»).
Так можно предотвратить только частный случай, но это не решает проблемы в целом — рано или поздно у вас в проекте окажется какая-то модель, где вы забыли поставить условную галочку «убрать xss» (как в этом примере).


Это та же самая причина, по которой никогда не стоит использовать ручную конкатенацию для построения SQL запросов — люди ошибаются, и в проекте больше хелловорлда у вас с достаточно большой вероятностью будет уязвимость.


Категорично — именно поэтому. Для реальных проектов это нельзя использовать как минимум пока не будет исправлена эта проблема (выше я написал, почему). «На данный момент» — потому что я всё-таки надеюсь, что вы проблему исправите =).


А по поводу архитектуры — в таких случая можно сделать opt-out из автоматического экранирования, например по коду шаблона или по типу передаваемой переменной (по-разному делают).


Извините, но это всё, что надо знать о вашем шаблонизаторе на данный момент.


Переделывайте архитектуру — все подставляемые переменные должны экранироваться по умолчанию, как минимум.

Так. Давайте заново. Я утверждаю, что этот код в условии чистого окружения (в котором не было заранее объявлено переменной y):


(function() { eval('var y=10;'); console.log(y)})(); console.log(y);

вне strict mode бросит исключение на втором console.log, а в strict mode — на первом.


Вы мне написали, что он выводит два раза 10, и сказали что я пытаюсь вас ввести в заблуждение:


Во-вторых, думаете, что я не проверю ваш код

Очевидно, вы не ожидаете увидеть там исключения. На самом деле — оно там есть, проверьте ещё раз.
Скорее всего, вы неправильно что-то сделали, когда проверяли первый раз (например, заранее объявили глобальный y равный 10) — отсюда и неверные выводы. Попробуйте назвать переменную yyy, например.


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

Вот вам ещё пример с eval, для размышлений:


var z = 20;
function x() {
  z = 10;
  eval('var z');
  console.log(z);
}
x();
console.log(z);

Угадаете, что будет?


Это, кстати, пример того, почему eval нельзя считать полностью равноценным вставке кода в тело функции — вызов eval изменил привязку (примечание для всех: пожалуйста, не делайте так в реальном коде).

Во-первых, вы не ответили на вопрос, в чём вы выполняете код, что он даёт такие результаты, как у вас выше. Или вы в этом всё-таки ошиблись?


Во-вторых, в вашем примере var x = new Function(тыры-пыры); вообще не выполняет код внутри функции, как несложно увидеть. Пока мы её не вызовем, конечно. Не верите — напишите там console.log, что ли. Не верите в console.log — напишите там долгий цикл.


Во-третьих, я советую вам разобрать именно по шагам все приведённые примеры, и понять, что вы ожидаете в них получить следуя вашей логике. Как минимум в одном случае вы уже явно удивились результату — когда сказали «думаете, что я не проверю ваш код».

Вот вам ещё один пример, с режимами, кстати:


'use strict';
eval('console.log((function() { return !this; })())');
(new Function('console.log((function() { return !this; })())'))();

выдаёт


true
false

Как видно из примера, eval наследует текущий режим strict mode, а new Function — нет.


Ещё раз — eval и new Function не одинаковые, они имеют разное влияние на окружение, они выполняются в разных режимах, они наследуют разные области видимости.

Во-вторых, думаете, что я не проверю ваш код:

В чём выполняете, если не секрет? Я не могу воспроизвести такого поведения, как у вас, независимо от браузера или режима. Вы точно очистили окружение после предыдущей команды (в которой вы задали глобальный y в 10)?


Поведение eval действительно зависит от режима, и в strict mode он ведёт себя несколько не так — объявленные в нём переменные не добавляются в окружающий контекст. Но и совсем не так, как вы показали. И это не решает всех его проблем.


Зависимость поведения eval от strict mode — ещё один повод не использовать eval, кстати говоря.

Когда это eval стал наследовать текущую область видимости? Он использует глобальную область.

> var x; (function() { var x; eval('x=10'); console.log(x)})(); console.log(x);
10
undefined

x в какой области поменялся? В текущей (той, из которой был вызван). А вы сказали — в глобальной.


> (function() { eval('var y=10;'); console.log(y)})(); console.log(y);
10
ReferenceError: y is not defined

y объявился в какой области видимости? В текущей (той, из которой был вызван). А вы сказали — в глобальной. И это явно не просто использование переменной, на которое вы ссылаетесь тут:


new Function отличается от eval только тем, что он не может использовать переменные из области видимости, в которой он был вызван.

И да, то, что через eval можно сэмулировать поведение new Function — верно: засунув туда new Function, например. Но я не вижу никаких разумных причин вызывать eval вместо new Function — используя new Function, вы можете быть уверены, что у вас не захватится текущая область видимости, без дополнительных костылей.


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


И да, см. http://www.ecma-international.org/ecma-262/6.0/#sec-eval-x и http://www.ecma-international.org/ecma-262/6.0/#sec-function-constructor.

Читайте внимательнее — задания будут раздаваться партнёрами (коих несколько сотен) и фраза «например, нужно будет закачать приложение или написать положительный комментарий на сайте отзывов» присутствует в статье.


Даже если приложение самого оператора будет нормальным, партнёры смогут попросить загрузить что угодно.

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


Но никак не в четверть самой картины по размеру.

Знаете, а я мог ошибиться с процентами — это стоит перепроверить на более адекватном бенчмарке.
Сейчас посмотрел ещё раз — разброс сам по себе очень большой, хоть он и говорит о том, что точность ±1-2%.

На всякий случай: я — не автор поста.

Его приняли уже. И он есть в вебките (что в следующем сафари) из коробки и в v8 за флагом.

Выделение нагруженной части в нативный аддон автоматически выигрыша в скорости не приносит — его надо ещё тщательно оптимизировать, чтобы оказаться быстрее JITа. При этом ошибки в нативном аддоне могут обойтись дороже, из-за ручной работы с памятью.


На тестовых задачах с числодробилками — да, возможно. Но в реальной жизни такое случается не так часто, обычно время уходит не на алгоритмы, стоящие за логикой работы сервера.


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


И да, стоимость переписывания на нативный код и поддержки нативного аддона в человеко-часах в большинстве случаев будет больше, чем стоимость сэкономленных ресурсов. Кроме случаев очень больших компаний со множеством серверов (Facebook, вон, предпочёл форкнуть PHP). Если можно добавить в код волшебный костыль для ускорения работы какого-то нагруженного места на порядок и забыть про это — почему бы и нет. Переписывать всё на нативном — зачем?


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

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity