Пусть, у нас есть yate-шаблон:
match / {
string = (
'<span>'
.somedata.somevalue
'</span>'
)
i18n('%key', string)
}
i18n
— для yate внешняя функция, которая возвращает scalar
. Любой scalar
в yate экранируется.
match / {
// это скаляр, он будет заэкранирован
'<div class="hello"></div>'
// такая строка (но это еще не scalar) будет выведена как html
html('<div class="hello"></div>')
// здесь i18n будет сначала заэкранирован, потому что это scalar
// и html не выведет правильную разметку!
html(i18n('%key', string))
// здесь deentityify отменяет экранирование,
// и html выводит правильную разметку
html(deentityify(i18n('%key', string)))
}
В шаблонах содержатся пользовательские данные, поэтому есть опасность XSS
. Назову я свой файл <script>alert(1);</script>
,
match / {
.resource.name
}
И yr.run
выполнит этот скрипт.
Пусть есть скомпилированный шаблон:
out += yr.externals("key_i18n_value", someValue)
После запуска локализации (d2-build-tools
) шаблон приобретает следующий вид:
out += yr.externals("key_i18n_value", yr.externals.entityify(someValue))
Если в качестве аргументов i18n
строки, то они не экранируются. (если nodeset
или переменная, то экранируются).
Это происходит из-за того, что все аргументы для i18n проходяет через entityify, чтобы обезопаситься от XSS