Skip to content

Instantly share code, notes, and snippets.

@vitkarpov
Last active August 29, 2015 14:02
Show Gist options
  • Save vitkarpov/6214e5f35b60c5114940 to your computer and use it in GitHub Desktop.
Save vitkarpov/6214e5f35b60c5114940 to your computer and use it in GitHub Desktop.
История про i18n и yate

История про i18n

Пусть, у нас есть 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)))
}

Зачем yate экранирует скаляры?

В шаблонах содержатся пользовательские данные, поэтому есть опасность XSS. Назову я свой файл <script>alert(1);</script>,

match / {
  .resource.name
}

И yr.run выполнит этот скрипт.

Экранирование аргументов i18n после сборки d2-build-tools

Пусть есть скомпилированный шаблон:

out += yr.externals("key_i18n_value", someValue)

После запуска локализации (d2-build-tools) шаблон приобретает следующий вид:

out += yr.externals("key_i18n_value", yr.externals.entityify(someValue))

Если в качестве аргументов i18n строки, то они не экранируются. (если nodeset или переменная, то экранируются).

@doochik
Copy link

doochik commented Jun 20, 2014

Это происходит из-за того, что все аргументы для i18n проходяет через entityify, чтобы обезопаситься от XSS

@vitkarpov
Copy link
Author

Точнее не аргументы, а то, что возвращает i18n, правильно?
Там формируется строка, а yate уже экранирует, т.к. это scalar. Верно?

@vitkarpov
Copy link
Author

Разобрались. Обновил gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment