• Модуль: forum
  • Путь к файлу: ~/bitrix/modules/forum/classes/general/functions.php
  • Класс: CForumSimpleHTMLParser
  • Вызов: CForumSimpleHTMLParser::findTagEnd
function findTagEnd($startIndex)
{
	if ($startIndex === false || (intval($startIndex) == 0 && $startIndex !== 0))
		return $this->setError('E_PARSE_INVALID_INDEX');
	$tmp = mb_substr($this->data, $startIndex);

	$this->lastError = '';
	$arStack = [];
	$offset = 0;
	$closeMistmatch = 2;
	$tag_id = 0;

	while ($tmp <> '' && preg_match($this->parse_tag, $tmp, $matches) > 0)
	{
		$tag_id++;
		$tag_name = mb_strtoupper($matches['tag']);
		$localOffset = mb_strpos($tmp, $matches[0]) + mb_strlen($matches[0]);

		if ($matches['closing'] == '/') // close tag
		{
			if (end($arStack) == $tag_name)
			{
				array_pop($arStack);
			}
			else // lost close tag somewhere
			{
				$fixed = false;
				for ($i=2;$i<=$closeMistmatch+1;$i++)
				{
					if (sizeof($arStack) > $i && $arStack[sizeof($arStack)-$i] == $tag_name)
					{
						$arStack = array_slice($arStack, 0, -$i);
						$fixed = true;
					}
				}
				if (!$fixed)
				{
					return $this->setError('E_PARSE_INVALID_DOM_2');
				}
			}
		}
		else if ($matches['selfclosing'] == '/') // self close tag
		{
			// do nothing
		}
		else if ($tag_name == 'LI' && end($arStack) == 'LI') // oh
		{
			// do nothing
		}
		else // open tag
		{
			$arStack[] = $tag_name;
		}
		if (sizeof($arStack) > 300)
		{
			return $this->setError('E_PARSE_TOO_BIG_DOM_3');  // too big DOM
		}
		else if (sizeof($arStack) == 0) // done !
		{
			return $offset + $localOffset;
		}
		else // continue
		{
			$offset += $localOffset;
			$tmp = mb_substr($tmp, $localOffset);
		}
		// skip special tags
		while ($skip = $this->skipTags($tmp))
		{
			$offset += $skip;
			$tmp = mb_substr($tmp, $skip);
		}
	}
	return $this->setError('E_PARSE_INVALID_DOM_4');  // not enough data in $data ?
}