diff --git a/src/utils/__tests__/PhutilUTF8TestCase.php b/src/utils/__tests__/PhutilUTF8TestCase.php index 7e85f89c..ab2b7b8a 100644 --- a/src/utils/__tests__/PhutilUTF8TestCase.php +++ b/src/utils/__tests__/PhutilUTF8TestCase.php @@ -824,4 +824,13 @@ final class PhutilUTF8TestCase extends PhutilTestCase { phutil_set_system_locale($original_locale); } + public function testUTF8StringlikeObjects() { + // See T13527. In some versions and configurations of PHP, passing an + // object which implements "__toString()" to "mb_check_encoding()" could + // fail. + $any_stringlike_object = new PhutilURI('/'); + + $this->assertTrue(phutil_is_utf8($any_stringlike_object)); + } + } diff --git a/src/utils/utf8.php b/src/utils/utf8.php index 7aff7f76..f03663f3 100644 --- a/src/utils/utf8.php +++ b/src/utils/utf8.php @@ -95,6 +95,10 @@ function phutil_is_utf8_with_only_bmp_characters($string) { */ function phutil_is_utf8($string) { if (function_exists('mb_check_encoding')) { + // See T13527. In some versions of PHP, "mb_check_encoding()" strictly + // requires a string parameter. + $string = phutil_string_cast($string); + // If mbstring is available, this is significantly faster than using PHP. return mb_check_encoding($string, 'UTF-8'); }