Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.270.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Bug fixes:
- xoops_aw_encode() and xoops_aw_decode() take their element by reference, so the array_walk() calls that encode and decode XOBJ_DTYPE_UNICODE_ARRAY values act on the array; write.php and XoopsObject::setVar() serialize the walked array instead of array_walk()'s boolean, and XoopsObject::getVar() returns the decoded array instead of true (include/functions.encoding.php, class/model/write.php, kernel/object.php)
- a XOBJ_DTYPE_UNICODE_ARRAY value reloads as the array that was stored: assignVar() keeps the serialized string as is instead of url-decoding it, which broke the string lengths of elements such as café or a+b and made getVar() return [], and XoopsModelWrite::cleanVars() no longer addslashes() the elements before url-encoding them, which stored the backslashes (kernel/object.php, class/model/write.php, tests/unit/htdocs/kernel/XoopsObjectUnicodeArrayTest.php)
- xoops_getUrlDomain() checks the host key only when parse_url() returned an array (include/functions.php)
- the |replace and |escape modifiers no longer emit PHP 8.6 deprecations: Smarty's smarty_mb_str_replace() uses str_replace() instead of mb_regex_encoding()/mb_split(), which are deprecated since PHP 8.6 and scheduled for removal in PHP 9.0; non-UTF-8 charsets are still round-tripped through UTF-8 (xoops_lib/vendor/smarty/smarty/libs/plugins/shared.mb_str_replace.php)
- templates can use |sprintf without a Smarty 4 deprecation notice: XoopsTpl registers sprintf as a modifier, as it already does for strstr, trim and file_exists (class/template.php) (#264)

Libraries and assets:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,42 +44,18 @@ function smarty_mb_str_replace($search, $replace, $subject, &$count = 0)
}
}
} else {
$mb_reg_charset = mb_regex_encoding();
// Check if mbstring regex is using UTF-8
$reg_is_unicode = !strcasecmp($mb_reg_charset, "UTF-8");
if(!$reg_is_unicode) {
// ...and set to UTF-8 if not
mb_regex_encoding("UTF-8");
// mb_regex_encoding()/mb_split() are deprecated since PHP 8.6 (bundled oniguruma is unmaintained).
// str_replace() is byte-exact and safe on UTF-8, which is self-synchronizing; other multibyte
// charsets (EUC-JP, GB2312, ...) are round-tripped through UTF-8 so no match spans a character boundary.
$convert = (bool)strcasecmp(Smarty::$_CHARSET, 'UTF-8');
if ($convert) {
$subject = mb_convert_encoding($subject ?? '', 'UTF-8', Smarty::$_CHARSET);
$search = mb_convert_encoding($search, 'UTF-8', Smarty::$_CHARSET);
$replace = mb_convert_encoding($replace, 'UTF-8', Smarty::$_CHARSET);
}

// See if charset used by Smarty is matching one used by regex...
$current_charset = mb_regex_encoding();
$convert_result = (bool)strcasecmp(Smarty::$_CHARSET, $current_charset);
if($convert_result) {
// ...convert to it if not.
$subject = mb_convert_encoding($subject, $current_charset, Smarty::$_CHARSET);
$search = mb_convert_encoding($search, $current_charset, Smarty::$_CHARSET);
$replace = mb_convert_encoding($replace, $current_charset, Smarty::$_CHARSET);
}

$parts = mb_split(preg_quote($search), $subject ?? "") ?: array();
// If original regex encoding was not unicode...
if(!$reg_is_unicode) {
// ...restore original regex encoding to avoid breaking the system.
mb_regex_encoding($mb_reg_charset);
}
if($parts === false) {
// This exception is thrown if call to mb_split failed.
// Usually it happens, when $search or $replace are not valid for given mb_regex_encoding().
// There may be other cases for it to fail, please file an issue if you find a reproducible one.
throw new SmartyException("Source string is not a valid $current_charset sequence (probably)");
}

$count = count($parts) - 1;
$subject = implode($replace, $parts);
// Convert results back to charset used by Smarty, if needed.
if($convert_result) {
$subject = mb_convert_encoding($subject, Smarty::$_CHARSET, $current_charset);
$subject = str_replace($search, $replace, $subject ?? '', $count);
if ($convert) {
$subject = mb_convert_encoding($subject, Smarty::$_CHARSET, 'UTF-8');
}
}
return $subject;
Expand Down