Diff
Modified: trunk/LayoutTests/ChangeLog (286868 => 286869)
--- trunk/LayoutTests/ChangeLog 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/ChangeLog 2021-12-10 20:37:40 UTC (rev 286869)
@@ -1,3 +1,25 @@
+2021-12-10 Chris Dumez <cdu...@apple.com>
+
+ Improve <type="datetime-local"> value parsing and sanitization
+ https://bugs.webkit.org/show_bug.cgi?id=234039
+
+ Reviewed by Darin Adler.
+
+ * fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal-expected.txt:
+ * fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal.html:
+ * fast/forms/datetimelocal/input-valueasnumber-datetimelocal-expected.txt:
+ * fast/forms/datetimelocal/input-valueasnumber-datetimelocal.html:
+ Update a couple of existing tests to reflect behavior change.
+
+ * fast/forms/datetimelocal/datetime-local-value-sanitization-expected.txt: Added.
+ * fast/forms/datetimelocal/datetime-local-value-sanitization.html: Added.
+ Improve test coverage for datetime-local value sanitization.
+
+ * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt:
+ * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt:
+ * platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt:
+ Rebaseline WPT tests now that more checks are passing.
+
2021-12-10 Gabriel Nava Marino <gnavamar...@apple.com>
nullptr deref in ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded
Modified: trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal-expected.txt (286868 => 286869)
--- trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -9,17 +9,17 @@
PASS "2009-09-07T16:49:31.1" is a correct valid datetime-local string.
PASS "2009-09-07T16:49:31.12" is a correct valid datetime-local string.
PASS "2009-09-07T16:49:31.123" is a correct valid datetime-local string.
-PASS "2009-09-07T16:49:31.1234567890" is a correct valid datetime-local string.
PASS "275760-09-13T00:00:00.000" is a correct valid datetime-local string.
PASS "0001-01-01T00:00:00.000" is a correct valid datetime-local string.
+PASS "2009-09-07 16:49" is a correct valid datetime-local string.
PASS " 2009-09-07T16:49 " is an invalid datetime-local string and was sanitized.
PASS "2009-09-07t16:49" is an invalid datetime-local string and was sanitized.
-PASS "2009-09-07 16:49" is an invalid datetime-local string and was sanitized.
PASS "2009/09/07T16:49" is an invalid datetime-local string and was sanitized.
PASS "a" is an invalid datetime-local string and was sanitized.
PASS "-1-09-07T16:49" is an invalid datetime-local string and was sanitized.
PASS "0000-12-31T23:59:59.999" is an invalid datetime-local string and was sanitized.
PASS "275760-09-13T00:00:00.001" is an invalid datetime-local string and was sanitized.
+PASS "2009-09-07T16:49:31.1234567890" is an invalid datetime-local string and was sanitized.
PASS "invalid" is an invalid datetime-local string and was sanitized while disabled.
PASS successfullyParsed is true
Modified: trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal.html (286868 => 286869)
--- trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal.html 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/datetimelocal/ValidityState-typeMismatch-datetimelocal.html 2021-12-10 20:37:40 UTC (rev 286869)
@@ -45,19 +45,19 @@
shouldBeValid('2009-09-07T16:49:31.1');
shouldBeValid('2009-09-07T16:49:31.12');
shouldBeValid('2009-09-07T16:49:31.123');
-shouldBeValid('2009-09-07T16:49:31.1234567890');
shouldBeValid('275760-09-13T00:00:00.000');
shouldBeValid('0001-01-01T00:00:00.000');
+shouldBeValid('2009-09-07 16:49');
// Invalid values
shouldBeInvalid(' 2009-09-07T16:49 ');
shouldBeInvalid('2009-09-07t16:49');
-shouldBeInvalid('2009-09-07 16:49');
shouldBeInvalid('2009/09/07T16:49');
shouldBeInvalid('a');
shouldBeInvalid('-1-09-07T16:49');
shouldBeInvalid('0000-12-31T23:59:59.999');
shouldBeInvalid('275760-09-13T00:00:00.001');
+shouldBeInvalid('2009-09-07T16:49:31.1234567890');
// Disabled
shouldBeInvalid('invalid', true);
Added: trunk/LayoutTests/fast/forms/datetimelocal/datetime-local-value-sanitization-expected.txt (0 => 286869)
--- trunk/LayoutTests/fast/forms/datetimelocal/datetime-local-value-sanitization-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/forms/datetimelocal/datetime-local-value-sanitization-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -0,0 +1,19 @@
+Tests the sanitization of the value of elements of type datetime-local.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS input.value is "2000-01-01T12:30:00.5"
+PASS input.value is "2000-01-01T12:30:00.6"
+PASS input.value is "2000-01-01T12:30:00.7"
+PASS input.value is "2000-01-01T12:30:00.04"
+PASS input.value is "2000-01-01T12:30:00.003"
+PASS input.value is ""
+PASS input.value is "2000-01-01T12:30"
+PASS input.value is "2000-01-01T12:30"
+PASS input.value is "2000-01-01T12:30:01"
+PASS input.value is "2000-01-01T12:30:10"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/forms/datetimelocal/datetime-local-value-sanitization.html (0 => 286869)
--- trunk/LayoutTests/fast/forms/datetimelocal/datetime-local-value-sanitization.html (rev 0)
+++ trunk/LayoutTests/fast/forms/datetimelocal/datetime-local-value-sanitization.html 2021-12-10 20:37:40 UTC (rev 286869)
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests the sanitization of the value of <input> elements of type datetime-local.");
+
+function testSanitization(inputValue, expectedOutputValue)
+{
+ input = document.createElement("input");
+ input.type = "datetime-local";
+ input.value = inputValue;
+ shouldBeEqualToString("input.value", "" + expectedOutputValue);
+}
+
+let tests = [
+ ["2000-01-01 12:30:00.5", "2000-01-01T12:30:00.5"],
+ ["2000-01-01 12:30:00.60", "2000-01-01T12:30:00.6"],
+ ["2000-01-01 12:30:00.700", "2000-01-01T12:30:00.7"],
+ ["2000-01-01 12:30:00.04", "2000-01-01T12:30:00.04"],
+ ["2000-01-01 12:30:00.003", "2000-01-01T12:30:00.003"],
+ ["2000-01-01 12:30:00.1234", ""],
+ ["2000-01-01 12:30:00", "2000-01-01T12:30"],
+ ["2000-01-01 12:30:00.0", "2000-01-01T12:30"],
+ ["2000-01-01 12:30:01.0", "2000-01-01T12:30:01"],
+ ["2000-01-01 12:30:10.0", "2000-01-01T12:30:10"],
+];
+
+for (let test of tests)
+ testSanitization(test[0], test[1]);
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal-expected.txt (286868 => 286869)
--- trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -8,7 +8,7 @@
PASS valueAsNumberFor("1970-01-01T00:00:00.000") is Date.UTC(1970, 0, 1, 0, 0, 0)
PASS valueAsNumberFor("2009-12-22T11:32:11") is Date.UTC(2009, 11, 22, 11, 32, 11)
PASS setValueAsNumberAndGetValue(1969, 11, 1, 0, 0, 0, 0) is "1969-12-01T00:00"
-PASS setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100) is "1970-01-01T10:01:00.100"
+PASS setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100) is "1970-01-01T10:01:00.1"
PASS setValueAsNumberAndGetValue(2009, 11, 31, 23, 59, 59, 999) is "2009-12-31T23:59:59.999"
PASS setValueAsNumberAndGetValue(10000, 0, 1, 12, 0, 1, 0) is "10000-01-01T12:00:01"
PASS setValueAsNumberAndGetValue(-1, 0, 1, 0, 0, 0, 0) is ""
@@ -26,8 +26,8 @@
PASS input.valueAsNumber = Number.NEGATIVE_INFINITY threw exception NotSupportedError: The operation is not supported..
PASS input.valueAsNumber = Date.UTC(275760, 8, 13, 0, 0, 0, 1) threw exception NotSupportedError: The operation is not supported..
Step attribute value and string representation:
-PASS input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00"
-PASS input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00.000"
+PASS input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00"
+PASS input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00"
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal.html (286868 => 286869)
--- trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal.html 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal.html 2021-12-10 20:37:40 UTC (rev 286869)
@@ -32,7 +32,7 @@
shouldBe('valueAsNumberFor("2009-12-22T11:32:11")', 'Date.UTC(2009, 11, 22, 11, 32, 11)');
shouldBe('setValueAsNumberAndGetValue(1969, 11, 1, 0, 0, 0, 0)', '"1969-12-01T00:00"');
-shouldBe('setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100)', '"1970-01-01T10:01:00.100"');
+shouldBe('setValueAsNumberAndGetValue(1970, 0, 1, 10, 1, 0, 100)', '"1970-01-01T10:01:00.1"');
shouldBe('setValueAsNumberAndGetValue(2009, 11, 31, 23, 59, 59, 999)', '"2009-12-31T23:59:59.999"');
shouldBe('setValueAsNumberAndGetValue(10000, 0, 1, 12, 0, 1, 0)', '"10000-01-01T12:00:01"');
@@ -54,9 +54,9 @@
debug('Step attribute value and string representation:');
// If the step attribute value is 1 second and the second part is 0, we should show the second part.
-shouldBe('input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00"');
+shouldBe('input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00"');
// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
-shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00.000"');
+shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00"');
</script>
<script src=""
</body>
Modified: trunk/LayoutTests/fast/forms/time/time-validity-typemismatch-expected.txt (286868 => 286869)
--- trunk/LayoutTests/fast/forms/time/time-validity-typemismatch-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/time/time-validity-typemismatch-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -10,8 +10,6 @@
PASS "23:59:59.1" is a correct valid time string.
PASS "23:59:59.12" is a correct valid time string.
PASS "23:59:59.123" is a correct valid time string.
-PASS "23:59:59.1234567890" is a correct valid time string.
-PASS "00:00:00.0000000000" is a correct valid time string.
PASS " 00:00 " is an invalid time string and was sanitized.
PASS "1:23" is an invalid time string and was sanitized.
PASS "011:11" is an invalid time string and was sanitized.
@@ -33,6 +31,8 @@
PASS "23:45:06." is an invalid time string and was sanitized.
PASS "23:45:06.abc" is an invalid time string and was sanitized.
PASS "23:45:06.789abc" is an invalid time string and was sanitized.
+PASS "23:59:59.1234567890" is an invalid time string and was sanitized.
+PASS "00:00:00.0000000000" is an invalid time string and was sanitized.
PASS "invalid" is an invalid time string and was sanitized while disabled.
PASS successfullyParsed is true
Modified: trunk/LayoutTests/fast/forms/time/time-validity-typemismatch.html (286868 => 286869)
--- trunk/LayoutTests/fast/forms/time/time-validity-typemismatch.html 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/time/time-validity-typemismatch.html 2021-12-10 20:37:40 UTC (rev 286869)
@@ -46,8 +46,6 @@
shouldBeValid('23:59:59.1');
shouldBeValid('23:59:59.12');
shouldBeValid('23:59:59.123');
-shouldBeValid('23:59:59.1234567890');
-shouldBeValid('00:00:00.0000000000');
// Invalid values
shouldBeInvalid(' 00:00 ');
@@ -71,6 +69,8 @@
shouldBeInvalid('23:45:06.');
shouldBeInvalid('23:45:06.abc');
shouldBeInvalid('23:45:06.789abc');
+shouldBeInvalid('23:59:59.1234567890');
+shouldBeInvalid('00:00:00.0000000000');
// Disabled
shouldBeInvalid('invalid', true);
Modified: trunk/LayoutTests/fast/forms/time/time-valueasdate-expected.txt (286868 => 286869)
--- trunk/LayoutTests/fast/forms/time/time-valueasdate-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/time/time-valueasdate-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -23,7 +23,7 @@
PASS input.value = "00:00"; input.valueAsDate = null; input.value is ""
Step attribute value and string representation:
PASS input.step = "1"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00"
-PASS input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00.000"
+PASS input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00.0"
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/forms/time/time-valueasdate.html (286868 => 286869)
--- trunk/LayoutTests/fast/forms/time/time-valueasdate.html 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/time/time-valueasdate.html 2021-12-10 20:37:40 UTC (rev 286869)
@@ -50,7 +50,7 @@
// If the step attribute value is 1 second and the second part is 0, we should show the second part.
shouldBe('input.step = "1"; setValueAsDateAndGetValue(0, 0, 0, 0)', '"00:00:00"');
// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
-shouldBe('input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0)', '"00:00:00.000"');
+shouldBe('input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0)', '"00:00:00.0"');
</script>
<script src=""
</body>
Modified: trunk/LayoutTests/fast/forms/time/time-valueasnumber-expected.txt (286868 => 286869)
--- trunk/LayoutTests/fast/forms/time/time-valueasnumber-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/time/time-valueasnumber-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -26,7 +26,7 @@
PASS input.valueAsNumber = Number.NEGATIVE_INFINITY threw exception NotSupportedError: The operation is not supported..
Step attribute value and string representation:
PASS input.step = "1"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00"
-PASS input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00.000"
+PASS input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00.0"
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/forms/time/time-valueasnumber.html (286868 => 286869)
--- trunk/LayoutTests/fast/forms/time/time-valueasnumber.html 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/fast/forms/time/time-valueasnumber.html 2021-12-10 20:37:40 UTC (rev 286869)
@@ -50,7 +50,7 @@
// If the step attribute value is 1 second and the second part is 0, we should show the second part.
shouldBe('input.step = "1"; setValueAsNumberAndGetValue(0, 0, 0, 0)', '"00:00:00"');
// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
-shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0)', '"00:00:00.000"');
+shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0)', '"00:00:00.0"');
</script>
<script src=""
</body>
Modified: trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (286868 => 286869)
--- trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -19,12 +19,12 @@
PASS [INPUT in PASSWORD status] The value is empty and required is true
PASS [INPUT in DATETIME-LOCAL status] The required attribute is not set
PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10T12:00:00)
-FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00) assert_false: The validity.valueMissing should be false. expected false got true
+PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00)
PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14T12:00:00.001)
PASS [INPUT in DATETIME-LOCAL status] The value attribute is a number(1234567)
PASS [INPUT in DATETIME-LOCAL status] The value attribute is a Date object
PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(1979-10-99 99:99)
-FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00) assert_false: The validity.valueMissing should be false. expected false got true
+PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00)
PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(2001-12-21 12:00)-two white space
PASS [INPUT in DATETIME-LOCAL status] the value attribute is a string(abc)
PASS [INPUT in DATETIME-LOCAL status] The value attribute is empty string
Modified: trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt (286868 => 286869)
--- trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -1,9 +1,9 @@
PASS empty value
PASS datetime-local input value set to 2014-01-01T11:11:11.111 without min/max
-FAIL datetime-local input value set to 2014-01-01 11:11:11.111 without min/max assert_equals: expected "2014-01-01T11:11:11.111" but got ""
-FAIL datetime-local input value set to 2014-01-01 11:11 without min/max assert_equals: expected "2014-01-01T11:11" but got ""
-FAIL datetime-local input value set to 2014-01-01 00:00:00.000 without min/max assert_equals: expected "2014-01-01T00:00" but got ""
+PASS datetime-local input value set to 2014-01-01 11:11:11.111 without min/max
+PASS datetime-local input value set to 2014-01-01 11:11 without min/max
+PASS datetime-local input value set to 2014-01-01 00:00:00.000 without min/max
PASS datetime-local input value set to 2014-01-0 11:11 without min/max
PASS datetime-local input value set to 2014-01-01 11:1 without min/max
PASS invalid datetime-local input value 1
@@ -12,8 +12,8 @@
PASS invalid datetime-local input value 4
PASS invalid datetime-local input value 5
PASS invalid datetime-local input value 6
-FAIL Value >= min attribute assert_equals: expected "2014-01-01T11:12" but got ""
-FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got ""
-FAIL Value <= max attribute assert_equals: expected "2014-01-01T11:10" but got ""
-FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got ""
+PASS Value >= min attribute
+FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:10"
+PASS Value <= max attribute
+FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:12"
Modified: trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt (286868 => 286869)
--- trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -5,7 +5,7 @@
PASS Valid value: value should be 00:00:00.0
PASS Valid value: value should be 00:00:00.00
PASS Valid value: value should be 00:00:00.000
-FAIL Invalid value: fraction should have one, two or three ASCII digits. Value should be empty assert_equals: expected "" but got "00:00:00.0000"
+PASS Invalid value: fraction should have one, two or three ASCII digits. Value should be empty
PASS Invalid value: hour should have two ASCII digits. Value should be empty
PASS Invalid value: minutes should have two ASCII digits. Value should be empty
PASS Invalid value: seconds should have two ASCII digits. Value should be empty
Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt (286868 => 286869)
--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/constraints/form-validation-validity-valueMissing-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -19,12 +19,12 @@
PASS [INPUT in PASSWORD status] The value is empty and required is true
PASS [INPUT in DATETIME-LOCAL status] The required attribute is not set
PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10T12:00:00)
-FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00) assert_false: The validity.valueMissing should be false. expected false got true
+PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(2000-12-10 12:00)
PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14T12:00:00.001)
PASS [INPUT in DATETIME-LOCAL status] The value attribute is a number(1234567)
PASS [INPUT in DATETIME-LOCAL status] The value attribute is a Date object
PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(1979-10-99 99:99)
-FAIL [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00) assert_false: The validity.valueMissing should be false. expected false got true
+PASS [INPUT in DATETIME-LOCAL status] Valid local date and time string(1979-10-14 12:00:00)
PASS [INPUT in DATETIME-LOCAL status] Invalid local date and time string(2001-12-21 12:00)-two white space
PASS [INPUT in DATETIME-LOCAL status] the value attribute is a string(abc)
PASS [INPUT in DATETIME-LOCAL status] The value attribute is empty string
Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt (286868 => 286869)
--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -1,9 +1,9 @@
PASS empty value
PASS datetime-local input value set to 2014-01-01T11:11:11.111 without min/max
-FAIL datetime-local input value set to 2014-01-01 11:11:11.111 without min/max assert_equals: expected "2014-01-01T11:11:11.111" but got ""
-FAIL datetime-local input value set to 2014-01-01 11:11 without min/max assert_equals: expected "2014-01-01T11:11" but got ""
-FAIL datetime-local input value set to 2014-01-01 00:00:00.000 without min/max assert_equals: expected "2014-01-01T00:00" but got ""
+PASS datetime-local input value set to 2014-01-01 11:11:11.111 without min/max
+PASS datetime-local input value set to 2014-01-01 11:11 without min/max
+PASS datetime-local input value set to 2014-01-01 00:00:00.000 without min/max
PASS datetime-local input value set to 2014-01-0 11:11 without min/max
PASS datetime-local input value set to 2014-01-01 11:1 without min/max
PASS invalid datetime-local input value 1
@@ -12,8 +12,8 @@
PASS invalid datetime-local input value 4
PASS invalid datetime-local input value 5
PASS invalid datetime-local input value 6
-FAIL Value >= min attribute assert_equals: expected "2014-01-01T11:12" but got ""
-FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got ""
-FAIL Value <= max attribute assert_equals: expected "2014-01-01T11:10" but got ""
-FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got ""
+PASS Value >= min attribute
+FAIL Value < min attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:10"
+PASS Value <= max attribute
+FAIL Value > max attribute assert_equals: expected "2014-01-01T11:11" but got "2014-01-01T11:12"
Modified: trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt (286868 => 286869)
--- trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/LayoutTests/platform/mac-wk2/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/time-2-expected.txt 2021-12-10 20:37:40 UTC (rev 286869)
@@ -5,7 +5,7 @@
PASS Valid value: value should be 00:00:00.0
PASS Valid value: value should be 00:00:00.00
PASS Valid value: value should be 00:00:00.000
-FAIL Invalid value: fraction should have one, two or three ASCII digits. Value should be empty assert_equals: expected "" but got "00:00:00.0000"
+PASS Invalid value: fraction should have one, two or three ASCII digits. Value should be empty
PASS Invalid value: hour should have two ASCII digits. Value should be empty
PASS Invalid value: minutes should have two ASCII digits. Value should be empty
PASS Invalid value: seconds should have two ASCII digits. Value should be empty
Modified: trunk/Source/WebCore/ChangeLog (286868 => 286869)
--- trunk/Source/WebCore/ChangeLog 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/Source/WebCore/ChangeLog 2021-12-10 20:37:40 UTC (rev 286869)
@@ -1,3 +1,42 @@
+2021-12-10 Chris Dumez <cdu...@apple.com>
+
+ Improve <type="datetime-local"> value parsing and sanitization
+ https://bugs.webkit.org/show_bug.cgi?id=234039
+
+ Reviewed by Darin Adler.
+
+ Improve <type="datetime-local"> value parsing and sanitization.
+
+ Test: fast/forms/datetimelocal/datetime-local-value-sanitization.html
+
+ * html/BaseDateAndTimeInputType.h:
+ * html/DateTimeLocalInputType.cpp:
+ (WebCore::DateTimeLocalInputType::sanitizeValue const):
+ Implement value sanitization for <type="datetime-local"> so that:
+ - if the input uses a space as date / time separator, the sanitized value will use a 'T' instead.
+ - The output will use the shortest possible string, omitting seconds or milliseconds when 0, as per
+ https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-normalised-local-date-and-time-string
+
+ * html/DateTimeLocalInputType.h:
+ * platform/DateComponents.cpp:
+ (WebCore::DateComponents::parseTime):
+ Fix bug where we would allow more than 3 digits for the millisecond part of the time (we
+ would silently ignore follow-up digits instead of failing parsing). This is as per:
+ - https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-time-string
+ This was covered by one of the subtests in imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/datetime-local.html
+
+ (WebCore::isDateTimeLocalSeparator):
+ (WebCore::DateComponents::parseDateTimeLocal):
+ Allow using a space as date / time separator in <type="datetime-local">, instead of simply allowing a 'T'.
+ This would align our behavior with Gecko and the specification:
+ - https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-local-date-and-time-string
+ Note that Blink still seems to only allow 'T' as separator.
+
+
+ (WebCore::DateComponents::toStringForTime const):
+ The output will use the shortest possible string, omitting seconds or milliseconds when 0, as per
+ https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-normalised-local-date-and-time-string
+
2021-12-10 Alex Christensen <achristen...@webkit.org>
Move if-domain and unless-domain conversion to WKContentRuleList parsing
Modified: trunk/Source/WebCore/html/BaseDateAndTimeInputType.h (286868 => 286869)
--- trunk/Source/WebCore/html/BaseDateAndTimeInputType.h 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/Source/WebCore/html/BaseDateAndTimeInputType.h 2021-12-10 20:37:40 UTC (rev 286869)
@@ -100,7 +100,7 @@
// InputType functions:
String visibleValue() const final;
- String sanitizeValue(const String&) const final;
+ String sanitizeValue(const String&) const override;
void setValue(const String&, bool valueChanged, TextFieldEventBehavior) final;
WallTime valueAsDate() const override;
ExceptionOr<void> setValueAsDate(WallTime) const override;
Modified: trunk/Source/WebCore/html/DateTimeLocalInputType.cpp (286868 => 286869)
--- trunk/Source/WebCore/html/DateTimeLocalInputType.cpp 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/Source/WebCore/html/DateTimeLocalInputType.cpp 2021-12-10 20:37:40 UTC (rev 286869)
@@ -99,6 +99,15 @@
return results.containsAll({ DateTimeFormatValidationResults::HasYear, DateTimeFormatValidationResults::HasMonth, DateTimeFormatValidationResults::HasDay, DateTimeFormatValidationResults::HasHour, DateTimeFormatValidationResults::HasMinute, DateTimeFormatValidationResults::HasMeridiem });
}
+String DateTimeLocalInputType::sanitizeValue(const String& proposedValue) const
+{
+ if (proposedValue.isEmpty())
+ return proposedValue;
+
+ auto components = DateComponents::fromParsingDateTimeLocal(proposedValue);
+ return components ? components->toString() : emptyString();
+}
+
String DateTimeLocalInputType::formatDateTimeFieldsState(const DateTimeFieldsState& state) const
{
if (!state.year || !state.month || !state.dayOfMonth || !state.hour || !state.minute || !state.meridiem)
Modified: trunk/Source/WebCore/html/DateTimeLocalInputType.h (286868 => 286869)
--- trunk/Source/WebCore/html/DateTimeLocalInputType.h 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/Source/WebCore/html/DateTimeLocalInputType.h 2021-12-10 20:37:40 UTC (rev 286869)
@@ -52,6 +52,7 @@
StepRange createStepRange(AnyStepHandling) const final;
std::optional<DateComponents> parseToDateComponents(StringView) const final;
std::optional<DateComponents> setMillisecondToDateComponents(double) const final;
+ String sanitizeValue(const String&) const final;
bool isValidFormat(OptionSet<DateTimeFormatValidationResults>) const final;
String formatDateTimeFieldsState(const DateTimeFieldsState&) const final;
Modified: trunk/Source/WebCore/platform/DateComponents.cpp (286868 => 286869)
--- trunk/Source/WebCore/platform/DateComponents.cpp 2021-12-10 20:23:01 UTC (rev 286868)
+++ trunk/Source/WebCore/platform/DateComponents.cpp 2021-12-10 20:37:40 UTC (rev 286869)
@@ -477,12 +477,10 @@
} else if (digitsLength == 2) {
millisecond = parseInt(temporaryBuffer, 2);
*millisecond *= 10;
- } else {
- // Regardless of the number of digits, we only ever parse at most 3. All other
- // digits after that are ignored, but the buffer is incremented as if they were
- // all parsed.
+ } else if (digitsLength == 3)
millisecond = parseInt(temporaryBuffer, 3);
- }
+ else
+ return false;
// Due to the countDigits above, the parseInt calls should all be successful.
ASSERT(millisecond);
@@ -502,6 +500,13 @@
return true;
}
+// Gecko allows both 'T' and a space as datetime-local separator (see https://github.com/whatwg/html/issues/2276).
+// WPT tests also expect this behavior.
+template<typename CharacterType> static bool isDateTimeLocalSeparator(CharacterType c)
+{
+ return c == 'T' || c == ' ';
+}
+
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#local-dates-and-times
template<typename CharacterType> bool DateComponents::parseDateTimeLocal(StringParsingBuffer<CharacterType>& buffer)
{
@@ -508,7 +513,7 @@
if (!parseDate(buffer))
return false;
- if (!skipExactly(buffer, 'T'))
+ if (!skipExactly<isDateTimeLocalSeparator>(buffer))
return false;
if (!parseTime(buffer))
@@ -760,9 +765,15 @@
return makeString(pad('0', 2, m_hour), ':', pad('0', 2, m_minute));
case SecondFormat::Second:
return makeString(pad('0', 2, m_hour), ':', pad('0', 2, m_minute), ':', pad('0', 2, m_second));
- case SecondFormat::Millisecond:
- return makeString(pad('0', 2, m_hour), ':', pad('0', 2, m_minute), ':', pad('0', 2, m_second), '.', pad('0', 3, m_millisecond));
+ case SecondFormat::Millisecond: {
+ auto resultWithoutMilliseconds = makeString(pad('0', 2, m_hour), ':', pad('0', 2, m_minute), ':', pad('0', 2, m_second), '.');
+ if (!(m_millisecond % 100))
+ return makeString(resultWithoutMilliseconds, m_millisecond / 100);
+ if (!(m_millisecond % 10))
+ return makeString(resultWithoutMilliseconds, pad('0', 2, m_millisecond / 10));
+ return makeString(resultWithoutMilliseconds, pad('0', 3, m_millisecond));
}
+ }
}
String DateComponents::toString(SecondFormat format) const