Ответ 1
Как следует из его названия, strip_tags
должен удалить все теги HTML. Единственный способ доказать это - проанализировать исходный код. Следующий анализ применяется к вызову strip_tags('...')
без второго аргумента для белых списков.
Во-первых, некоторая теория о тегах HTML: тег начинается с <
, за которым следуют не-пробельные символы. Если эта строка начинается с ?
, она не должна анализироваться . Если эта строка начинается с !--
, она учитывает комментарий, и следующий текст не должен анализироваться. Комментарий заканчивается -->
, внутри такого комментария допускаются символы типа <
и >
. Атрибуты могут встречаться в тегах, их значения могут быть дополнительно окружены символом кавычки ('
или "
). Если такая цитата существует, она должна быть закрыта, иначе, если встречается a >
, тег не закрыт.
Код <a href="example>xxx</a><a href="second">text</a>
интерпретируется в Firefox как:
<a href="http://example.com%3Exxx%3C/a%3E%3Ca%20href=" second"="">text</a>
Функция PHP strip_tags
ссылается на строка 4036 of ext/standard/string.c. Эта функция вызывает внутреннюю функцию php_strip_tags_ex.
Существуют два буфера, один для вывода, другой для "внутри HTML-тегов". Счетчик с именем depth
содержит число угловых скобок (<
).
Переменная in_q
содержит символ кавычки ('
или "
), если таковой имеется, и 0
в противном случае. Последний символ хранится в переменной lc
.
Функции содержат пять состояний, три упоминаются в описании выше функции. На основе этой информации и тела функции могут быть получены следующие состояния:
- Состояние 0 - это состояние вывода (не в любом теге)
- Состояние 1 означает, что мы находимся внутри нормального тега html (буфер тега содержит
<
) - Состояние 2 означает, что мы находимся внутри тега php
- Состояние 3: мы пришли из состояния вывода и встретили символы
<
и!
(буфер тега содержит<!
) - Состояние 4: внутри комментария HTML
Нам нужно просто быть осторожным, чтобы ни один тег не мог быть вставлен. То есть <
, за которым следует символ без пробелов. Строка 4326 проверяет регистр с символом <
, который описан ниже:
- Если внутри кавычек (например,
<a href="inside quotes">
), символ<
игнорируется (удаляется с выхода). - Если следующий символ является символом пробела,
<
добавляется в выходной буфер. - если вне тега HTML, состояние становится
1
( "внутри HTML-тега" ), а последний символlc
установлен на<
- В противном случае, если внутри тега HTML, счетчик с именем
depth
увеличивается и символ игнорируется.
Если >
выполняется во время открытия тега (state == 1
), in_q
становится 0
( "не в цитате" ), а state
становится 0
( "не в теге" )). Буфер тегов отбрасывается.
Проверки атрибутов (для символов типа '
и "
) выполняются в буфере тега, который отбрасывается. Итак, вывод:
strip_tags без ярлыка тега безопасен для включения внешних тегов, не допускается тег.
Под "внешними тегами" я имею в виду не теги, как в <a href="in tag">outside tag</a>
. Текст может содержать <
и >
, хотя, как в >< a>>
. Результат недействителен HTML, хотя <
, >
и &
еще нужно избежать, особенно &
. Это можно сделать с помощью htmlspecialchars()
.
Описание strip_tags
без аргумента белого списка:
Уверен, что в возвращаемой строке не существует HTML-тега.