Commit 4b1583c8 authored by Matthieu Rigolot's avatar Matthieu Rigolot Committed by Commit Bot

Allow strings containing '.' after sign (ex: -.8) in Decimal::FromString.

Entering those strings in a <input type=number> leads to validation messages not being displayed in certain cases:
- rangeUnderflow (bug985330)
- rangeOverflow
- stepMisMatch

This is due to Decimal::FromString not recognizing it as valid, hence returning NaN incorrectly. decimal.h and the spec:
https://html.spec.whatwg.org/#valid-floating-point-number say it should be supported.

Fixes it and adds appropriate tests in wtf_unittests and in web_tests.

Bug: 985330
Change-Id: Ic3a3bb1ca855ebcc13f96aac16c31937a2cba0cd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1773262
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#693074}
parent 28c74fee
...@@ -787,6 +787,7 @@ Decimal Decimal::FromString(const String& str) { ...@@ -787,6 +787,7 @@ Decimal Decimal::FromString(const String& str) {
} }
HandleCharAndBreak('0', kStateZero); HandleCharAndBreak('0', kStateZero);
HandleCharAndBreak('.', kStateDot);
return Nan(); return Nan();
case kStateStart: case kStateStart:
......
...@@ -668,6 +668,8 @@ TEST_F(DecimalTest, FromString) { ...@@ -668,6 +668,8 @@ TEST_F(DecimalTest, FromString) {
EXPECT_EQ(Encode(3, 0, kPositive), FromString("+3")); EXPECT_EQ(Encode(3, 0, kPositive), FromString("+3"));
EXPECT_EQ(Encode(0, 3, kPositive), FromString("0E3")); EXPECT_EQ(Encode(0, 3, kPositive), FromString("0E3"));
EXPECT_EQ(Encode(5, -1, kPositive), FromString(".5")); EXPECT_EQ(Encode(5, -1, kPositive), FromString(".5"));
EXPECT_EQ(Encode(5, -1, kPositive), FromString("+.5"));
EXPECT_EQ(Encode(5, -1, kNegative), FromString("-.5"));
EXPECT_EQ(Encode(100, 0, kPositive), FromString("100")); EXPECT_EQ(Encode(100, 0, kPositive), FromString("100"));
EXPECT_EQ(Encode(100, 0, kNegative), FromString("-100")); EXPECT_EQ(Encode(100, 0, kNegative), FromString("-100"));
EXPECT_EQ(Encode(123, -2, kPositive), FromString("1.23")); EXPECT_EQ(Encode(123, -2, kPositive), FromString("1.23"));
......
...@@ -106,7 +106,8 @@ ...@@ -106,7 +106,8 @@
{conditions: {max: "5", value: "1abc"}, expected: false, name: "[target] The value is not a number"}, {conditions: {max: "5", value: "1abc"}, expected: false, name: "[target] The value is not a number"},
{conditions: {max: "5", value: "6"}, expected: true, name: "[target] The value is greater than max(integer)"}, {conditions: {max: "5", value: "6"}, expected: true, name: "[target] The value is greater than max(integer)"},
{conditions: {max: "-5.5", value: "-5.4"}, expected: true, name: "[target] The value is greater than max(floating number)"}, {conditions: {max: "-5.5", value: "-5.4"}, expected: true, name: "[target] The value is greater than max(floating number)"},
{conditions: {max: "-5e-1", value: "5e+2"}, expected: true, name: "[target] The value is greater than max(scientific notation)"} {conditions: {max: "-1", value: "-.8"}, expected: true, name: "[target] The value is greater than max(special floating number)"},
{conditions: {max: "-5e-1", value: "5e+2"}, expected: true, name: "[target] The value is greater than max(scientific notation)"},
] ]
} }
]; ];
......
...@@ -104,6 +104,7 @@ ...@@ -104,6 +104,7 @@
{conditions: {min: "5", value: "6abc"}, expected: false, name: "[target] The value is not a number"}, {conditions: {min: "5", value: "6abc"}, expected: false, name: "[target] The value is not a number"},
{conditions: {min: "6", value: "5"}, expected: true, name: "[target] The value is less than min(integer)"}, {conditions: {min: "6", value: "5"}, expected: true, name: "[target] The value is less than min(integer)"},
{conditions: {min: "-5.4", value: "-5.5"}, expected: true, name: "[target] The value is less than min(floating number)"}, {conditions: {min: "-5.4", value: "-5.5"}, expected: true, name: "[target] The value is less than min(floating number)"},
{conditions: {min: "1", value: "-.8"}, expected: true, name: "[target] The value is less than min(special floating number)"},
{conditions: {min: "5e+2", value: "-5e-1"}, expected: true, name: "[target] The value is less than min(scientific notation)"} {conditions: {min: "5e+2", value: "-5e-1"}, expected: true, name: "[target] The value is less than min(scientific notation)"}
] ]
} }
......
...@@ -66,7 +66,8 @@ ...@@ -66,7 +66,8 @@
types: ["number"], types: ["number"],
testData: [ testData: [
{conditions: {step: "", value: "1"}, expected: false, name: "[target] The step attribute is not set"}, {conditions: {step: "", value: "1"}, expected: false, name: "[target] The step attribute is not set"},
{conditions: {step: 2 * 1 * 1, value: ""}, expected: false, name: "[target] The value attibute is empty string"}, {conditions: {step: "", value: "-.8"}, expected: true, name: "[target] The step attribute is not set and the value attribute is a floating number"},
{conditions: {step: 2 * 1 * 1, value: ""}, expected: false, name: "[target] The value attribute is empty string"},
{conditions: {step: 2 * 1 * 1, value: "2"}, expected: false, name: "[target] The value must match the step"}, {conditions: {step: 2 * 1 * 1, value: "2"}, expected: false, name: "[target] The value must match the step"},
{conditions: {step: 2 * 1 * 1, value: "3"}, expected: true, name: "[target] The value must mismatch the step"} {conditions: {step: 2 * 1 * 1, value: "3"}, expected: true, name: "[target] The value must mismatch the step"}
] ]
......
...@@ -15,6 +15,7 @@ PASS The value "0.999999999999999999999999999999999999999999" doesn't overflow t ...@@ -15,6 +15,7 @@ PASS The value "0.999999999999999999999999999999999999999999" doesn't overflow t
PASS The value "101" overflows the maximum value "100". PASS The value "101" overflows the maximum value "100".
PASS The value "-99" overflows the maximum value "-100". PASS The value "-99" overflows the maximum value "-100".
PASS The value "101" overflows the maximum value "1E+2". PASS The value "101" overflows the maximum value "1E+2".
PASS The value "-.8" overflows the maximum value "-1".
PASS The value "101" overflows the maximum value "100". PASS The value "101" overflows the maximum value "100".
PASS The value "101" doesn't overflow the maximum value "1E+2" when disabled. PASS The value "101" doesn't overflow the maximum value "1E+2" when disabled.
PASS successfullyParsed is true PASS successfullyParsed is true
......
...@@ -57,6 +57,8 @@ checkNotOverflow('0.999999999999999999999999999999999999999999', '0.999999999999 ...@@ -57,6 +57,8 @@ checkNotOverflow('0.999999999999999999999999999999999999999999', '0.999999999999
checkOverflow('101', '100'); checkOverflow('101', '100');
checkOverflow('-99', '-100'); checkOverflow('-99', '-100');
checkOverflow('101', '1E+2'); checkOverflow('101', '1E+2');
input.min = '-2';
checkOverflow('-.8', '-1');
input.min = '200'; // value < min && value > max input.min = '200'; // value < min && value > max
checkOverflow('101', '100'); checkOverflow('101', '100');
......
...@@ -16,6 +16,7 @@ PASS The value "99" undeflows the minimum value "100". ...@@ -16,6 +16,7 @@ PASS The value "99" undeflows the minimum value "100".
PASS The value "-101" undeflows the minimum value "-100". PASS The value "-101" undeflows the minimum value "-100".
PASS The value "99" undeflows the minimum value "1E+2". PASS The value "99" undeflows the minimum value "1E+2".
PASS The value "101" undeflows the minimum value "200". PASS The value "101" undeflows the minimum value "200".
PASS The value "-.8" undeflows the minimum value "1".
PASS The value "99" doesn't underflow the minimum value "1E+2" when disabled. PASS The value "99" doesn't underflow the minimum value "1E+2" when disabled.
PASS successfullyParsed is true PASS successfullyParsed is true
......
...@@ -61,6 +61,7 @@ checkUnderflow('-101', '-100'); ...@@ -61,6 +61,7 @@ checkUnderflow('-101', '-100');
checkUnderflow('99', '1E+2'); checkUnderflow('99', '1E+2');
input.max = '100'; // value < min && value > max input.max = '100'; // value < min && value > max
checkUnderflow('101', '200'); checkUnderflow('101', '200');
checkUnderflow('-.8', '1');
// Disabled // Disabled
checkNotUnderflow('99', '1E+2', true); checkNotUnderflow('99', '1E+2', true);
......
...@@ -27,6 +27,7 @@ PASS stepMismatchFor("0.9", "0.1", "") is false ...@@ -27,6 +27,7 @@ PASS stepMismatchFor("0.9", "0.1", "") is false
PASS stepMismatchFor("0.9", "0.1000001", "") is true PASS stepMismatchFor("0.9", "0.1000001", "") is true
PASS stepMismatchFor("0.9", "0.1000000000000001", "") is false PASS stepMismatchFor("0.9", "0.1000000000000001", "") is false
PASS stepMismatchFor("1.0", "0.3333333333333333", "") is false PASS stepMismatchFor("1.0", "0.3333333333333333", "") is false
PASS stepMismatchFor("-.8", null, "-1") is true
Rounding Rounding
PASS stepMismatchFor("5.005", "0.005", "4") is false PASS stepMismatchFor("5.005", "0.005", "4") is false
Disabled Disabled
......
...@@ -45,6 +45,7 @@ shouldBe('stepMismatchFor("0.9", "0.1", "")', 'false'); ...@@ -45,6 +45,7 @@ shouldBe('stepMismatchFor("0.9", "0.1", "")', 'false');
shouldBe('stepMismatchFor("0.9", "0.1000001", "")', 'true'); shouldBe('stepMismatchFor("0.9", "0.1000001", "")', 'true');
shouldBe('stepMismatchFor("0.9", "0.1000000000000001", "")', 'false'); shouldBe('stepMismatchFor("0.9", "0.1000000000000001", "")', 'false');
shouldBe('stepMismatchFor("1.0", "0.3333333333333333", "")', 'false'); shouldBe('stepMismatchFor("1.0", "0.3333333333333333", "")', 'false');
shouldBe('stepMismatchFor("-.8", null, "-1")', 'true');
debug('Rounding'); debug('Rounding');
shouldBe('stepMismatchFor("5.005", "0.005", "4")', 'false'); shouldBe('stepMismatchFor("5.005", "0.005", "4")', 'false');
debug('Disabled'); debug('Disabled');
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment