@@ -359,6 +359,8 @@ public function initialize(PKPRequest $request)
359359 $ this ->registerPlugin ('modifier ' , 'count ' , count (...));
360360 $ this ->registerPlugin ('modifier ' , 'intval ' , intval (...));
361361 $ this ->registerPlugin ('modifier ' , 'json_encode ' , json_encode (...));
362+ // Register the safe JSON modifier
363+ $ this ->registerPlugin ('modifier ' , 'json_encode_html_attribute ' , $ this ->smartyJsonEncodeHtmlAttribute (...));
362364 $ this ->registerPlugin ('modifier ' , 'uniqid ' , uniqid (...));
363365 $ this ->registerPlugin ('modifier ' , 'substr ' , substr (...));
364366 $ this ->registerPlugin ('modifier ' , 'strstr ' , strstr (...));
@@ -1792,6 +1794,26 @@ public function smartyTranslate(array $params, Smarty_Internal_Template $smarty)
17921794 return $ count === null ? __ ($ key , $ variables , $ locale ) : __p ($ key , $ count , $ variables , $ locale );
17931795 }
17941796
1797+ /**
1798+ * Smarty modifier: json_encode_html_attribute
1799+ *
1800+ * Encodes a value to JSON with full HTML-attribute safety.
1801+ * Escapes ", ', <, >, & as \u0022, \u0027, \u003C, \u003E, \u0026
1802+ * so the output can be safely placed inside any HTML attribute
1803+ */
1804+ function smartyJsonEncodeHtmlAttribute ($ value )
1805+ {
1806+ return json_encode (
1807+ $ value ,
1808+ JSON_HEX_TAG // < →
1809+ | JSON_HEX_AMP // & →
1810+ | JSON_HEX_APOS // ' →
1811+ | JSON_HEX_QUOT // " →
1812+ | JSON_UNESCAPED_UNICODE
1813+ | JSON_UNESCAPED_SLASHES // optional but highly recommended
1814+ );
1815+ }
1816+
17951817 /**
17961818 * Smarty usage: {html_options_translate ...}
17971819 * For parameter usage, see http://smarty.php.net/manual/en/language.function.html.options.php
0 commit comments