Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit efb8db8

Browse filesBrowse files
committed
[Form] fix parsing invalid floating point numbers
1 parent dd490af commit efb8db8
Copy full SHA for efb8db8

File tree

2 files changed

+98
-3
lines changed
Filter options

2 files changed

+98
-3
lines changed

‎src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Core/DataTransformer/PercentToLocalizedStringTransformer.php
+32-3Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public function reverseTransform($value)
116116
return;
117117
}
118118

119+
$position = 0;
119120
$formatter = $this->getNumberFormatter();
120121
$groupSep = $formatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
121122
$decSep = $formatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
@@ -129,18 +130,46 @@ public function reverseTransform($value)
129130
$value = str_replace(',', $decSep, $value);
130131
}
131132

133+
if (false !== strpos($value, $decSep)) {
134+
$type = \NumberFormatter::TYPE_DOUBLE;
135+
} else {
136+
$type = \PHP_INT_SIZE === 8 ? \NumberFormatter::TYPE_INT64 : \NumberFormatter::TYPE_INT32;
137+
}
138+
132139
// replace normal spaces so that the formatter can read them
133-
$value = $formatter->parse(str_replace(' ', "\xc2\xa0", $value));
140+
$result = $formatter->parse(str_replace(' ', "\xc2\xa0", $value), $type, $position);
134141

135142
if (intl_is_failure($formatter->getErrorCode())) {
136143
throw new TransformationFailedException($formatter->getErrorMessage());
137144
}
138145

139146
if (self::FRACTIONAL == $this->type) {
140-
$value /= 100;
147+
$result /= 100;
141148
}
142149

143-
return $value;
150+
if (\function_exists('mb_detect_encoding') && false !== $encoding = mb_detect_encoding($value, null, true)) {
151+
$length = mb_strlen($value, $encoding);
152+
$remainder = mb_substr($value, $position, $length, $encoding);
153+
} else {
154+
$length = strlen($value);
155+
$remainder = substr($value, $position, $length);
156+
}
157+
158+
// After parsing, position holds the index of the character where the
159+
// parsing stopped
160+
if ($position < $length) {
161+
// Check if there are unrecognized characters at the end of the
162+
// number (excluding whitespace characters)
163+
$remainder = trim($remainder, " \t\n\r\0\x0b\xc2\xa0");
164+
165+
if ('' !== $remainder) {
166+
throw new TransformationFailedException(
167+
sprintf('The number contains unrecognized characters: "%s"', $remainder)
168+
);
169+
}
170+
}
171+
172+
return $result;
144173
}
145174

146175
/**

‎src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/PercentToLocalizedStringTransformerTest.php
+66Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,70 @@ public function testDecimalSeparatorMayBeCommaIfGroupingSeparatorIsCommaButNoGro
236236
$this->assertEquals(1234.5, $transformer->reverseTransform('1234,5'));
237237
$this->assertEquals(1234.5, $transformer->reverseTransform('1234.5'));
238238
}
239+
240+
/**
241+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
242+
*/
243+
public function testReverseTransformDisallowsLeadingExtraCharacters()
244+
{
245+
$transformer = new PercentToLocalizedStringTransformer();
246+
247+
$transformer->reverseTransform('foo123');
248+
}
249+
250+
/**
251+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
252+
* @expectedExceptionMessage The number contains unrecognized characters: "foo3"
253+
*/
254+
public function testReverseTransformDisallowsCenteredExtraCharacters()
255+
{
256+
$transformer = new PercentToLocalizedStringTransformer();
257+
258+
$transformer->reverseTransform('12foo3');
259+
}
260+
261+
/**
262+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
263+
* @expectedExceptionMessage The number contains unrecognized characters: "foo8"
264+
* @requires extension mbstring
265+
*/
266+
public function testReverseTransformDisallowsCenteredExtraCharactersMultibyte()
267+
{
268+
// Since we test against other locales, we need the full implementation
269+
IntlTestHelper::requireFullIntl($this, false);
270+
271+
\Locale::setDefault('ru');
272+
273+
$transformer = new PercentToLocalizedStringTransformer();
274+
275+
$transformer->reverseTransform("12\xc2\xa0345,67foo8");
276+
}
277+
278+
/**
279+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
280+
* @expectedExceptionMessage The number contains unrecognized characters: "foo"
281+
*/
282+
public function testReverseTransformDisallowsTrailingExtraCharacters()
283+
{
284+
$transformer = new PercentToLocalizedStringTransformer();
285+
286+
$transformer->reverseTransform('123foo');
287+
}
288+
289+
/**
290+
* @expectedException \Symfony\Component\Form\Exception\TransformationFailedException
291+
* @expectedExceptionMessage The number contains unrecognized characters: "foo"
292+
* @requires extension mbstring
293+
*/
294+
public function testReverseTransformDisallowsTrailingExtraCharactersMultibyte()
295+
{
296+
// Since we test against other locales, we need the full implementation
297+
IntlTestHelper::requireFullIntl($this, false);
298+
299+
\Locale::setDefault('ru');
300+
301+
$transformer = new PercentToLocalizedStringTransformer();
302+
303+
$transformer->reverseTransform("12\xc2\xa0345,678foo");
304+
}
239305
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.