Implement better contextual escape for template v2

This commit is contained in:
Kijin Sung 2025-03-19 00:12:39 +09:00
parent baadb36e37
commit 9689a1ed68
2 changed files with 21 additions and 4 deletions

View file

@ -955,6 +955,23 @@ class Template
return UA::isMobile() && (config('mobile.tablets') || !UA::isTablet());
}
/**
* Contextual escape function for v2.
*
* @param string $str
* @param string $type
* @return string
*/
protected function _v2_escape(string $str, string $type = ''): string
{
switch ($this->config->context)
{
case 'CSS': return escape_css($str);
case 'JS': return escape_js($str);
default: return escape($str);
}
}
/**
* Lang shortcut for v2.
*

View file

@ -782,7 +782,7 @@ class TemplateParser_v2
'json_encode(%s, self::$_json_options2) : ' .
'htmlspecialchars(json_encode(%s, self::$_json_options), \ENT_QUOTES, \'UTF-8\', false); ?>', $args, $args);
case 'lang':
return sprintf('<?php echo $this->config->context === \'JS\' ? escape_js($this->_v2_lang(%s)) : $this->_v2_lang(%s); ?>', $args, $args);
return sprintf('<?php echo $this->config->context === \'HTML\' ? $this->_v2_lang(%s) : $this->_v2_escape($this->_v2_lang(%s)); ?>', $args, $args);
case 'dump':
return sprintf('<?php ob_start(); var_dump(%s); \$__dump = ob_get_clean(); echo rtrim(\$__dump); ?>', $args);
case 'dd':
@ -790,7 +790,7 @@ class TemplateParser_v2
case 'stack':
return sprintf('<?php echo implode("\n", self::\$_stacks[%s] ?? []) . "\n"; ?>', $args);
case 'url':
return sprintf('<?php echo $this->config->context === \'JS\' ? escape_js(getNotEncodedUrl(%s)) : getUrl(%s); ?>', $args, $args);
return sprintf('<?php echo $this->config->context === \'HTML\' ? getUrl(%s) : $this->_v2_escape(getNotEncodedUrl(%s)); ?>', $args, $args);
default:
return $match[0];
}
@ -968,11 +968,11 @@ class TemplateParser_v2
switch($option)
{
case 'autocontext':
return "\$this->config->context === 'JS' ? escape_js({$str2}) : htmlspecialchars({$str}, \ENT_QUOTES, 'UTF-8', false)";
return "\$this->config->context === 'HTML' ? htmlspecialchars({$str}, \ENT_QUOTES, 'UTF-8', false) : \$this->_v2_escape({$str2})";
case 'autocontext_json':
return "\$this->config->context === 'JS' ? {$str2} : htmlspecialchars({$str}, \ENT_QUOTES, 'UTF-8', false)";
case 'autocontext_lang':
return "\$this->config->context === 'JS' ? escape_js({$str2}) : ({$str})";
return "\$this->config->context === 'HTML' ? ({$str}) : \$this->_v2_escape({$str2})";
case 'autoescape':
return "htmlspecialchars({$str}, \ENT_QUOTES, 'UTF-8', false)";
case 'autolang':