diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-12-04 15:44:58 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-04 15:44:58 -0600 |
commit | eed3adc957fb3c52de24c560112533963572f525 (patch) | |
tree | 75c12b3c2bf9bfb9ad9ec467ef36ed10620a9ddc /components/script/dom/bindings/str.rs | |
parent | 221d72a81ed9300e260d33d2d2d6557b5a118fac (diff) | |
parent | a999239f28672aed053c9c3db001a2e6a26efa7f (diff) | |
download | servo-eed3adc957fb3c52de24c560112533963572f525.tar.gz servo-eed3adc957fb3c52de24c560112533963572f525.zip |
Auto merge of #19379 - SWW13:htmlinput_sanitize_time, r=KiChjang
Implemented sanitize_value for time input
Implemented value sanitization for `<input type=time/>`.
The value has the be valid time string (https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-time-string) or set to empty string.
---
The following test results look expected to me, but I'm not sure:
```
▶ Unexpected subtest result in /html/semantics/forms/the-input-element/type-change-state.html:
│ FAIL [expected PASS] change state from time to text
│ → assert_equals: input.value should be foobar after change of state expected " foobar " but got ""
│ FAIL [expected PASS] change state from time to search
│ → assert_equals: input.value should be foobar after change of state expected " foobar " but got ""
│ FAIL [expected PASS] change state from time to tel
│ → assert_equals: input.value should be foobar after change of state expected " foobar " but got ""
│ FAIL [expected PASS] change state from time to url
│ → assert_equals: input.value should be foobar after change of state expected "foobar" but got ""
│ FAIL [expected PASS] change state from time to password
│ → assert_equals: input.value should be foobar after change of state expected " foobar " but got ""
│
│ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:53:15
│ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1489:20
│ test@http://web-platform.test:8000/resources/testharness.js:511:9
└ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:37:9
▶ Unexpected subtest result in /html/semantics/forms/the-input-element/type-change-state.html:
│ FAIL [expected PASS] change state from color to time
│ → assert_equals: input.value should be #000000 after change of state expected "#000000" but got ""
│
│ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:55:15
│ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1489:20
│ test@http://web-platform.test:8000/resources/testharness.js:511:9
└ @http://web-platform.test:8000/html/semantics/forms/the-input-element/type-change-state.html:37:9
```
All other tests do now `PASS` instead of `FAIL`.
---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix *part of* #19172
- [x] There are tests for these changes
- [x] All tests `PASS`
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19379)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom/bindings/str.rs')
-rw-r--r-- | components/script/dom/bindings/str.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs index 3667dddf92d..6601d8e6856 100644 --- a/components/script/dom/bindings/str.rs +++ b/components/script/dom/bindings/str.rs @@ -208,6 +208,77 @@ impl DOMString { self.0.truncate(last_non_whitespace); let _ = self.0.splice(0..first_non_whitespace, ""); } + + /// Validates this `DOMString` is a time string according to + /// <https://html.spec.whatwg.org/multipage/#valid-time-string>. + pub fn is_valid_time_string(&self) -> bool { + enum State { + HourHigh, + HourLow09, + HourLow03, + MinuteColon, + MinuteHigh, + MinuteLow, + SecondColon, + SecondHigh, + SecondLow, + MilliStop, + MilliHigh, + MilliMiddle, + MilliLow, + Done, + Error, + } + let next_state = |valid: bool, next: State| -> State { if valid { next } else { State::Error } }; + + let state = self.chars().fold(State::HourHigh, |state, c| { + match state { + // Step 1 "HH" + State::HourHigh => { + match c { + '0' | '1' => State::HourLow09, + '2' => State::HourLow03, + _ => State::Error, + } + }, + State::HourLow09 => next_state(c.is_digit(10), State::MinuteColon), + State::HourLow03 => next_state(c.is_digit(4), State::MinuteColon), + + // Step 2 ":" + State::MinuteColon => next_state(c == ':', State::MinuteHigh), + + // Step 3 "mm" + State::MinuteHigh => next_state(c.is_digit(6), State::MinuteLow), + State::MinuteLow => next_state(c.is_digit(10), State::SecondColon), + + // Step 4.1 ":" + State::SecondColon => next_state(c == ':', State::SecondHigh), + // Step 4.2 "ss" + State::SecondHigh => next_state(c.is_digit(6), State::SecondLow), + State::SecondLow => next_state(c.is_digit(10), State::MilliStop), + + // Step 4.3.1 "." + State::MilliStop => next_state(c == '.', State::MilliHigh), + // Step 4.3.2 "SSS" + State::MilliHigh => next_state(c.is_digit(6), State::MilliMiddle), + State::MilliMiddle => next_state(c.is_digit(10), State::MilliLow), + State::MilliLow => next_state(c.is_digit(10), State::Done), + + _ => State::Error, + } + }); + + match state { + State::Done | + // Step 4 (optional) + State::SecondColon | + // Step 4.3 (optional) + State::MilliStop | + // Step 4.3.2 (only 1 digit required) + State::MilliMiddle | State::MilliLow => true, + _ => false + } + } } impl Borrow<str> for DOMString { |