Skip to content

Commit d9fec70

Browse files
committed
minor symfony#10890 Lower mbstring dep, remove it for Yaml and CssSelector components (nicolas-grekas)
This PR was merged into the 2.3 branch. Discussion ---------- Lower mbstring dep, remove it for Yaml and CssSelector components | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | none | License | MIT | Doc PR | none Commits ------- a4b805d Lower mbstring dep, remove it for Yaml and CssSelector components
2 parents a29a60d + a4b805d commit d9fec70

File tree

9 files changed

+51
-64
lines changed

9 files changed

+51
-64
lines changed

src/Symfony/Component/Console/Tests/Helper/FormatterHelperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function testFormatBlock()
5454

5555
public function testFormatBlockWithDiacriticLetters()
5656
{
57-
if (!extension_loaded('mbstring')) {
57+
if (!function_exists('mb_detect_encoding')) {
5858
$this->markTestSkipped('This test requires mbstring to work.');
5959
}
6060

src/Symfony/Component/CssSelector/Parser/Tokenizer/TokenizerEscaping.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,18 @@ public function escapeUnicodeAndNewLine($value)
6565
*/
6666
private function replaceUnicodeSequences($value)
6767
{
68-
return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), function (array $match) {
69-
$code = $match[1];
68+
return preg_replace_callback($this->patterns->getUnicodeEscapePattern(), function ($match) {
69+
$c = hexdec($match[1]);
7070

71-
if (bin2hex($code) > 0xFFFD) {
72-
$code = '\\FFFD';
71+
if (0x80 > $c %= 0x200000) {
72+
return chr($c);
73+
}
74+
if (0x800 > $c) {
75+
return chr(0xC0 | $c>>6).chr(0x80 | $c & 0x3F);
76+
}
77+
if (0x10000 > $c) {
78+
return chr(0xE0 | $c>>12).chr(0x80 | $c>>6 & 0x3F).chr(0x80 | $c & 0x3F);
7379
}
74-
75-
return mb_convert_encoding(pack('H*', $code), 'UTF-8', 'UCS-2BE');
7680
}, $value);
7781
}
7882
}

src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,25 +133,19 @@ public function reverseTransform($value)
133133
}
134134

135135
if (function_exists('mb_detect_encoding') && false !== $encoding = mb_detect_encoding($value)) {
136-
$strlen = function ($string) use ($encoding) {
137-
return mb_strlen($string, $encoding);
138-
};
139-
$substr = function ($string, $offset, $length) use ($encoding) {
140-
return mb_substr($string, $offset, $length, $encoding);
141-
};
136+
$length = mb_strlen($value, $encoding);
137+
$remainder = mb_substr($value, $position, $length, $encoding);
142138
} else {
143-
$strlen = 'strlen';
144-
$substr = 'substr';
139+
$length = strlen($value);
140+
$remainder = substr($value, $position, $length);
145141
}
146142

147-
$length = $strlen($value);
148-
149143
// After parsing, position holds the index of the character where the
150144
// parsing stopped
151145
if ($position < $length) {
152146
// Check if there are unrecognized characters at the end of the
153147
// number (excluding whitespace characters)
154-
$remainder = trim($substr($value, $position, $length), " \t\n\r\0\x0b\xc2\xa0");
148+
$remainder = trim($remainder, " \t\n\r\0\x0b\xc2\xa0");
155149

156150
if ('' !== $remainder) {
157151
throw new TransformationFailedException(

src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public function testReverseTransformWithGrouping($to, $from, $locale)
119119
// https://github.com/symfony/symfony/issues/7609
120120
public function testReverseTransformWithGroupingAndFixedSpaces()
121121
{
122-
if (!extension_loaded('mbstring')) {
122+
if (!function_exists('mb_detect_encoding')) {
123123
$this->markTestSkipped('The "mbstring" extension is required for this test.');
124124
}
125125

@@ -335,7 +335,7 @@ public function testReverseTransformDisallowsCenteredExtraCharacters()
335335
*/
336336
public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte()
337337
{
338-
if (!extension_loaded('mbstring')) {
338+
if (!function_exists('mb_detect_encoding')) {
339339
$this->markTestSkipped('The "mbstring" extension is required for this test.');
340340
}
341341

@@ -352,7 +352,7 @@ public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte()
352352
*/
353353
public function testReverseTransformIgnoresTrailingSpacesInExceptionMessage()
354354
{
355-
if (!extension_loaded('mbstring')) {
355+
if (!function_exists('mb_detect_encoding')) {
356356
$this->markTestSkipped('The "mbstring" extension is required for this test.');
357357
}
358358

@@ -380,7 +380,7 @@ public function testReverseTransformDisallowsTrailingExtraCharacters()
380380
*/
381381
public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte()
382382
{
383-
if (!extension_loaded('mbstring')) {
383+
if (!function_exists('mb_detect_encoding')) {
384384
$this->markTestSkipped('The "mbstring" extension is required for this test.');
385385
}
386386

src/Symfony/Component/Form/Tests/Extension/Core/EventListener/TrimListenerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public function testTrimSkipNonStrings()
5252
*/
5353
public function testTrimUtf8Separators($hex)
5454
{
55-
if (!function_exists('mb_check_encoding')) {
56-
$this->markTestSkipped('The "mb_check_encoding" function is not available');
55+
if (!function_exists('mb_convert_encoding')) {
56+
$this->markTestSkipped('The "mb_convert_encoding" function is not available');
5757
}
5858

5959
// Convert hexadecimal representation into binary

src/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class IcuResFileDumperTest extends \PHPUnit_Framework_TestCase
1818
{
1919
public function testDump()
2020
{
21-
if (!extension_loaded('mbstring')) {
21+
if (!function_exists('mb_convert_encoding')) {
2222
$this->markTestSkipped('This test requires mbstring to work.');
2323
}
2424

src/Symfony/Component/Yaml/Parser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function parse($value, $exceptionOnInvalidType = false, $objectSupport =
5555
$this->currentLine = '';
5656
$this->lines = explode("\n", $this->cleanup($value));
5757

58-
if (function_exists('mb_detect_encoding') && false === mb_detect_encoding($value, 'UTF-8', true)) {
58+
if (!preg_match('//u', $value)) {
5959
throw new ParseException('The YAML value does not appear to be valid UTF-8.');
6060
}
6161

src/Symfony/Component/Yaml/Tests/ParserTest.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@ protected function tearDown()
3333
*/
3434
public function testSpecifications($file, $expected, $yaml, $comment)
3535
{
36-
if ('escapedCharacters' == $file) {
37-
if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) {
38-
$this->markTestSkipped('The iconv and mbstring extensions are not available.');
39-
}
40-
}
41-
4236
$this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
4337
}
4438

@@ -446,8 +440,8 @@ public function testObjectsSupportDisabledWithExceptions()
446440

447441
public function testNonUtf8Exception()
448442
{
449-
if (!function_exists('mb_detect_encoding') || !function_exists('iconv')) {
450-
$this->markTestSkipped('Exceptions for non-utf8 charsets require the mb_detect_encoding() and iconv() functions.');
443+
if (!function_exists('iconv')) {
444+
$this->markTestSkipped('Exceptions for non-utf8 charsets require the iconv() function.');
451445

452446
return;
453447
}

src/Symfony/Component/Yaml/Unescaper.php

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class Unescaper
2121
{
2222
// Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
2323
// must be converted to that encoding.
24+
// @deprecated since 2.5, to be removed in 3.0
2425
const ENCODING = 'UTF-8';
2526

2627
// Regex fragment that matches an escaped character in a double quoted
@@ -80,13 +81,13 @@ public function unescapeCharacter($value)
8081
case 'n':
8182
return "\n";
8283
case 'v':
83-
return "\xb";
84+
return "\xB";
8485
case 'f':
85-
return "\xc";
86+
return "\xC";
8687
case 'r':
87-
return "\xd";
88+
return "\r";
8889
case 'e':
89-
return "\x1b";
90+
return "\x1B";
9091
case ' ':
9192
return ' ';
9293
case '"':
@@ -97,50 +98,44 @@ public function unescapeCharacter($value)
9798
return '\\';
9899
case 'N':
99100
// U+0085 NEXT LINE
100-
return $this->convertEncoding("\x00\x85", self::ENCODING, 'UCS-2BE');
101+
return "\xC2\x85";
101102
case '_':
102103
// U+00A0 NO-BREAK SPACE
103-
return $this->convertEncoding("\x00\xA0", self::ENCODING, 'UCS-2BE');
104+
return "\xC2\xA0";
104105
case 'L':
105106
// U+2028 LINE SEPARATOR
106-
return $this->convertEncoding("\x20\x28", self::ENCODING, 'UCS-2BE');
107+
return "\xE2\x80\xA8";
107108
case 'P':
108109
// U+2029 PARAGRAPH SEPARATOR
109-
return $this->convertEncoding("\x20\x29", self::ENCODING, 'UCS-2BE');
110+
return "\xE2\x80\xA9";
110111
case 'x':
111-
$char = pack('n', hexdec(substr($value, 2, 2)));
112-
113-
return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
112+
return self::utf8chr(hexdec(substr($value, 2, 2)));
114113
case 'u':
115-
$char = pack('n', hexdec(substr($value, 2, 4)));
116-
117-
return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
114+
return self::utf8chr(hexdec(substr($value, 2, 4)));
118115
case 'U':
119-
$char = pack('N', hexdec(substr($value, 2, 8)));
120-
121-
return $this->convertEncoding($char, self::ENCODING, 'UCS-4BE');
116+
return self::utf8chr(hexdec(substr($value, 2, 8)));
122117
}
123118
}
124119

125120
/**
126-
* Convert a string from one encoding to another.
121+
* Get the UTF-8 character for the given code point.
127122
*
128-
* @param string $value The string to convert
129-
* @param string $to The input encoding
130-
* @param string $from The output encoding
123+
* @param int $c The unicode code point
131124
*
132-
* @return string The string with the new encoding
133-
*
134-
* @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring)
125+
* @return string The corresponding UTF-8 character
135126
*/
136-
private function convertEncoding($value, $to, $from)
127+
private static function utf8chr($c)
137128
{
138-
if (function_exists('mb_convert_encoding')) {
139-
return mb_convert_encoding($value, $to, $from);
140-
} elseif (function_exists('iconv')) {
141-
return iconv($from, $to, $value);
129+
if (0x80 > $c %= 0x200000) {
130+
return chr($c);
131+
}
132+
if (0x800 > $c) {
133+
return chr(0xC0 | $c>>6).chr(0x80 | $c & 0x3F);
134+
}
135+
if (0x10000 > $c) {
136+
return chr(0xE0 | $c>>12).chr(0x80 | $c>>6 & 0x3F).chr(0x80 | $c & 0x3F);
142137
}
143138

144-
throw new \RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).');
139+
return chr(0xF0 | $c>>18).chr(0x80 | $c>>12 & 0x3F).chr(0x80 | $c>>6 & 0x3F).chr(0x80 | $c & 0x3F);
145140
}
146141
}

0 commit comments

Comments
 (0)