Последовательности экранирования
Почти каждая ошибка экранирования — это ошибка контекста, а не ошибка синтаксиса. Символ известен — кавычка, обратный слеш, амперсанд — и неясно, какое из шести конфликтующих правил применяется там, где строка вот-вот попадёт.
Поэтому эта таблица организована по контексту, а не по символу. Одна и та же кавычка удвоена в ячейке CSV, экранирована обратным слешем в JSON, превращена в " в HTML и полностью оставлена в одиночных кавычках оболочки. Четыре строки, четыре правила, один символ.
Наиболее важное правило — то, к которому люди обращаются в последнюю очередь: экранируйте на границе, через которую переходит значение, и экранируйте его один раз. Текст, экранированный дважды — & в исходнике страницы, \\n в выходном файле — это подпись значения, которое прошло через два кодировщика, каждый из которых предполагал, что он первый.
Строки JSON
10JSON допускает точно эти экранирования. Буквальный перевод строки или вкладка внутри строки недействительны.
| Экранирование | Означает | Когда вам это нужно | В контексте |
|---|---|---|---|
| \" | " | Двойная кавычка внутри строки | "say \"hi\"" |
| \\ | \ | Буквальный обратный слешПричина, по которой пути Windows ломают JSON. | "C:\\dir" |
| \/ | / | Косая черта — необязательноЗаконно, но ненужно; привычка от встраивания JSON в теги <script>. | "a\/b" |
| \n | U+000A | Подача ленты | "line\nline" |
| \r | U+000D | Возврат каретки | |
| \t | U+0009 | Вкладка | |
| \b | U+0008 | Возврат на рассчёт | |
| \f | U+000C | Форма подачи | |
| \u00e9 | é | Любой символ по его четырёхзначному коду точки | "caf\u00e9" |
| \ud83d\ude00 | 😀 | Символ выше U+FFFF, как пара суррогатаJSON не имеет форма \u{…}, поэтому астральные символы занимают два экранирования. |
Строки JavaScript
10Надмножество JSON, плюс экранирования буквального шаблона.
| Экранирование | Означает | Когда вам это нужно | В контексте |
|---|---|---|---|
| \' | ' | Одиночная кавычка внутри строки одиночных кавычек | |
| \" | " | Двойная кавычка внутри строки двойных кавычек | |
| \` | ` | Обратная кавычка внутри буквального шаблона | |
| \${ | ${ | Буквальный ${ внутри буквального шаблонаБез обратного слеша он запускает интерполяцию. | |
| \n | U+000A | Подача ленты | |
| \xe9 | é | Символ по двум шестнадцатеричным цифрам, до U+00FF | |
| \u00e9 | é | Символ по четырём шестнадцатеричным цифрам | |
| \u{1f600} | 😀 | Любая кодовая точка, однако долгоНе требует пары суррогата, в отличие от четырёхзначной формы. | |
| \0 | U+0000 | Нулевой символ | |
| \u2028 | U+2028 | Разделитель линииДопустимо в строке JS, но не в JSON — классический перерыв JSONP. |
Текст HTML и атрибуты
8Только & и < строго должны быть экранированы в тексте; кавычки имеют значение внутри атрибутов.
| Экранирование | Означает | Когда вам это нужно | В контексте |
|---|---|---|---|
| & | & | АмперсандЭкранируйте этот сначала, иначе каждое другое экранирование удвоится. | |
| < | < | Знак «меньше», поэтому оно не начинает тег | |
| > | > | Знак «больше» | |
| " | " | Двойная кавычка внутри атрибута | |
| ' | ' | Одиночная кавычка внутри атрибута' также работает в HTML5, но числовая форма безопасна везде. | |
| | U+00A0 | Неразрывное пространство | |
| é | é | Любой символ по десятичному коду точки | |
| é | é | Любой символ по шестнадцатеричному коду точки |
URL-адреса (процентное кодирование)
9Какие символы требуют экранирования, зависит от части URL, в которой они находятся.
| Экранирование | Означает | Когда вам это нужно | В контексте |
|---|---|---|---|
| %20 | Пробел, допустимый везде в URL | ||
| + | Пробел, но только в строке запроса, кодированной в формеВ сегменте пути это буквальный знак плюс. | ||
| %25 | % | Буквальный знак процентаПропустите это, и значение декодируется дважды. | |
| %2F | / | Косая черта внутри одного сегмента пути | |
| %3F | ? | Знак вопроса внутри значения | |
| %26 | & | Амперсанд внутри значения параметра | |
| %3D | = | Знак равно внутри значения параметра | |
| %23 | # | Хеш, поэтому он не запускает фрагмент | |
| %C3%A9 | é | Символ не-ASCII как его UTF-8 байтыОдин символ может стать двумя, тремя или четырьмя группами процентов. |
Поля CSV
5RFC 4180: цитируйте поле, затем удвойте любую кавычку внутри него. Обратные слеши ничего не значат.
| Экранирование | Означает | Когда вам это нужно | В контексте |
|---|---|---|---|
| "" | " | Кавычка внутри цитируемого поля — удвойте её | "say ""hi""" |
| "a,b" | , | Поле, содержащее разделитель — цитируйте поле | |
| "a b" | U+000A | Поле, содержащее разрыв строки — цитируйте поле | |
| " a" | Сохранить начальные или конечные пробелыБез кавычек, многие парсеры их обрезают. | ||
| '=SUM(A1) | = | Остановите электронную таблицу, выполняя ячейку как формулуПрименяется к значениям, начинающимся с =, +, - или @. Это инъекция формулы. |
Литералы и идентификаторы SQL
6Прочитайте их; не пишите их. Вместо этого используйте параметризованные запросы.
| Экранирование | Означает | Когда вам это нужно | В контексте |
|---|---|---|---|
| '' | ' | Кавычка внутри строкового литерала — удвойте её | 'O''Brien' |
| "order" | order | Зарезервированное слово, используемое как имя столбцаДвойные кавычки — стандарт; SQL Server использует [скобки]. | |
| `order` | order | То же самое в MySQL и MariaDB | |
| \% | % | Буквальный % внутри шаблона LIKE | |
| \_ | _ | Буквальный _ внутри шаблона LIKE | |
| $tag$ … $tag$ | ' | Кодирование PostgreSQL доллара — абсолютно нет экранирования внутриПолезно для тел кода, где удвоение каждой кавычки нечитаемо. |
Аргументы оболочки
6Одиночные кавычки буквальны, двойные кавычки по-прежнему расширяют переменные.
| Экранирование | Означает | Когда вам это нужно | В контексте |
|---|---|---|---|
| '…' | $ ` \ | Всё внутри буквальноСамое безопасное цитирование есть — но оно не может содержать одиночную кавычку. | |
| "…" | * ? space | Глобусы и пробелы безопасны, переменные по-прежнему расширяютсяAlways quote variables: "$var", never bare $var. | |
| \ | Пробел в неприводимом имени файла | ||
| \$ | $ | Буквальный знак доллара внутри двойных кавычек | |
| \` | ` | Буквальная обратная кавычка, а не замена команды | |
| '\'' | ' | Одиночная кавычка внутри одиночных кавычекЗакрыть, уйти, переоткрыть — нет способа вложить его напрямую. |