diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md
index 151ad7b580..1d6d7f870b 100644
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -38,6 +38,7 @@ Yii Framework 2 Change Log
- Bug #10101: Fixed assignments saving on role removing in `\yii\rbac\PhpManager` (rezident1307)
- Bug #10142: Fixed `yii\validators\EmailValidator` to check the length of email properly (silverfire)
- Bug: Fixed generation of canonical URLs for `ViewAction` pages (samdark)
+- Bug: Fixed `mb_*` functions calls to use `UTF-8` or `Yii::$app->charset` (silverfire)
- Enh #3506: Added `\yii\validators\IpValidator` to perform validation of IP addresses and subnets (SilverFire, samdark)
- Enh #5146: Added `\yii\i18n\Formatter::asDuration()` method (nineinchnick, SilverFire)
- Enh #7341: Client validation now skips disabled inputs (SamMousa)
diff --git a/framework/helpers/BaseFileHelper.php b/framework/helpers/BaseFileHelper.php
index 27b5cf204a..efd27c190a 100644
--- a/framework/helpers/BaseFileHelper.php
+++ b/framework/helpers/BaseFileHelper.php
@@ -189,7 +189,7 @@ class BaseFileHelper
public static function getExtensionsByMimeType($mimeType, $magicFile = null)
{
$mimeTypes = static::loadMimeTypes($magicFile);
- return array_keys($mimeTypes, mb_strtolower($mimeType, 'utf-8'), true);
+ return array_keys($mimeTypes, mb_strtolower($mimeType, 'UTF-8'), true);
}
private static $_mimeTypes = [];
diff --git a/framework/i18n/MessageFormatter.php b/framework/i18n/MessageFormatter.php
index bb743bd007..bd2adb4664 100644
--- a/framework/i18n/MessageFormatter.php
+++ b/framework/i18n/MessageFormatter.php
@@ -7,6 +7,7 @@
namespace yii\i18n;
+use Yii;
use yii\base\Component;
use yii\base\NotSupportedException;
@@ -274,19 +275,20 @@ class MessageFormatter extends Component
*/
private static function tokenizePattern($pattern)
{
+ $charset = Yii::$app ? Yii::$app->charset : 'UTF-8';
$depth = 1;
- if (($start = $pos = mb_strpos($pattern, '{')) === false) {
+ if (($start = $pos = mb_strpos($pattern, '{', 0, $charset)) === false) {
return [$pattern];
}
- $tokens = [mb_substr($pattern, 0, $pos)];
+ $tokens = [mb_substr($pattern, 0, $pos, $charset)];
while (true) {
- $open = mb_strpos($pattern, '{', $pos + 1);
- $close = mb_strpos($pattern, '}', $pos + 1);
+ $open = mb_strpos($pattern, '{', $pos + 1, $charset);
+ $close = mb_strpos($pattern, '}', $pos + 1, $charset);
if ($open === false && $close === false) {
break;
}
if ($open === false) {
- $open = mb_strlen($pattern);
+ $open = mb_strlen($pattern, $charset);
}
if ($close > $open) {
$depth++;
@@ -296,9 +298,9 @@ class MessageFormatter extends Component
$pos = $close;
}
if ($depth === 0) {
- $tokens[] = explode(',', mb_substr($pattern, $start + 1, $pos - $start - 1), 3);
+ $tokens[] = explode(',', mb_substr($pattern, $start + 1, $pos - $start - 1, $charset), 3);
$start = $pos + 1;
- $tokens[] = mb_substr($pattern, $start, $open - $start);
+ $tokens[] = mb_substr($pattern, $start, $open - $start, $charset);
$start = $open;
}
}
@@ -321,7 +323,7 @@ class MessageFormatter extends Component
{
// parsing pattern based on ICU grammar:
// http://icu-project.org/apiref/icu4c/classMessageFormat.html#details
-
+ $charset = Yii::$app ? Yii::$app->charset : 'UTF-8';
$param = trim($token[0]);
if (isset($args[$param])) {
$arg = $args[$param];
@@ -391,11 +393,11 @@ class MessageFormatter extends Component
$selector = trim($plural[$i++]);
if ($i == 1 && strncmp($selector, 'offset:', 7) === 0) {
- $offset = (int) trim(mb_substr($selector, 7, ($pos = mb_strpos(str_replace(["\n", "\r", "\t"], ' ', $selector), ' ', 7)) - 7));
- $selector = trim(mb_substr($selector, $pos + 1));
+ $offset = (int) trim(mb_substr($selector, 7, ($pos = mb_strpos(str_replace(["\n", "\r", "\t"], ' ', $selector), ' ', 7, $charset)) - 7, $charset));
+ $selector = trim(mb_substr($selector, $pos + 1, null, $charset));
}
if ($message === false && $selector === 'other' ||
- $selector[0] === '=' && (int) mb_substr($selector, 1) === $arg ||
+ $selector[0] === '=' && (int) mb_substr($selector, 1, null, $charset) === $arg ||
$selector === 'one' && $arg - $offset == 1
) {
$message = implode(',', str_replace('#', $arg - $offset, $plural[$i]));
diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php
index 60e03091dd..9068069440 100644
--- a/framework/validators/FileValidator.php
+++ b/framework/validators/FileValidator.php
@@ -315,7 +315,7 @@ class FileValidator extends Validator
*/
protected function validateExtension($file)
{
- $extension = mb_strtolower($file->extension, 'utf-8');
+ $extension = mb_strtolower($file->extension, 'UTF-8');
if ($this->checkExtensionByMimeType) {
diff --git a/framework/web/AssetManager.php b/framework/web/AssetManager.php
index bdfe670ae2..ada09ca2c2 100644
--- a/framework/web/AssetManager.php
+++ b/framework/web/AssetManager.php
@@ -351,9 +351,9 @@ class AssetManager extends Component
$asset = $bundle->sourcePath . '/' . $asset;
}
- $n = mb_strlen($asset);
+ $n = mb_strlen($asset, Yii::$app->charset);
foreach ($this->assetMap as $from => $to) {
- $n2 = mb_strlen($from);
+ $n2 = mb_strlen($from, Yii::$app->charset);
if ($n2 <= $n && substr_compare($asset, $from, $n - $n2, $n2) === 0) {
return $to;
}
diff --git a/framework/web/ErrorHandler.php b/framework/web/ErrorHandler.php
index 810dc2e046..ed4929ffa4 100644
--- a/framework/web/ErrorHandler.php
+++ b/framework/web/ErrorHandler.php
@@ -391,8 +391,8 @@ class ErrorHandler extends \yii\base\ErrorHandler
$args[$key] = '' . ($value ? 'true' : 'false') . '';
} elseif (is_string($value)) {
$fullValue = $this->htmlEncode($value);
- if (mb_strlen($value, 'utf8') > 32) {
- $displayValue = $this->htmlEncode(mb_substr($value, 0, 32, 'utf8')) . '...';
+ if (mb_strlen($value, Yii::$app->charset) > 32) {
+ $displayValue = $this->htmlEncode(mb_substr($value, 0, 32, Yii::$app->charset)) . '...';
$args[$key] = "'$displayValue'";
} else {
$args[$key] = "'$fullValue'";
diff --git a/tests/framework/i18n/FormatterDateTest.php b/tests/framework/i18n/FormatterDateTest.php
index 0b9ae94a4c..dc28dd31ed 100644
--- a/tests/framework/i18n/FormatterDateTest.php
+++ b/tests/framework/i18n/FormatterDateTest.php
@@ -129,9 +129,9 @@ class FormatterDateTest extends TestCase
// empty input
$this->formatter->locale = 'de-DE';
- $this->assertSame('01.01.1970 00:00:00', $this->formatter->asDatetime(''));
- $this->assertSame('01.01.1970 00:00:00', $this->formatter->asDatetime(0));
- $this->assertSame('01.01.1970 00:00:00', $this->formatter->asDatetime(false));
+ $this->assertRegExp('~01\.01\.1970,? 00:00:00~', $this->formatter->asDatetime(''));
+ $this->assertRegExp('~01\.01\.1970,? 00:00:00~', $this->formatter->asDatetime(0));
+ $this->assertRegExp('~01\.01\.1970,? 00:00:00~', $this->formatter->asDatetime(false));
}
public function testAsDatetime()