mirror of
https://github.com/servo/servo.git
synced 2025-07-16 11:53:39 +01:00
implement range input sanitization
This commit is contained in:
parent
525758ea5e
commit
b29230bd76
6 changed files with 75 additions and 19 deletions
|
@ -286,31 +286,37 @@ impl DOMString {
|
||||||
/// YYYY must be four or more digits, MM and DD both must be two digits
|
/// YYYY must be four or more digits, MM and DD both must be two digits
|
||||||
/// https://html.spec.whatwg.org/multipage/#valid-date-string
|
/// https://html.spec.whatwg.org/multipage/#valid-date-string
|
||||||
pub fn is_valid_date_string(&self) -> bool {
|
pub fn is_valid_date_string(&self) -> bool {
|
||||||
parse_date_string(&*self.0).is_ok()
|
parse_date_string(&self.0).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A valid month string should be "YYYY-MM"
|
/// A valid month string should be "YYYY-MM"
|
||||||
/// YYYY must be four or more digits, MM both must be two digits
|
/// YYYY must be four or more digits, MM both must be two digits
|
||||||
/// https://html.spec.whatwg.org/multipage/#valid-month-string
|
/// https://html.spec.whatwg.org/multipage/#valid-month-string
|
||||||
pub fn is_valid_month_string(&self) -> bool {
|
pub fn is_valid_month_string(&self) -> bool {
|
||||||
parse_month_string(&*self.0).is_ok()
|
parse_month_string(&self.0).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A valid week string should be like {YYYY}-W{WW}, such as "2017-W52"
|
/// A valid week string should be like {YYYY}-W{WW}, such as "2017-W52"
|
||||||
/// YYYY must be four or more digits, WW both must be two digits
|
/// YYYY must be four or more digits, WW both must be two digits
|
||||||
/// https://html.spec.whatwg.org/multipage/#valid-week-string
|
/// https://html.spec.whatwg.org/multipage/#valid-week-string
|
||||||
pub fn is_valid_week_string(&self) -> bool {
|
pub fn is_valid_week_string(&self) -> bool {
|
||||||
parse_week_string(&*self.0).is_ok()
|
parse_week_string(&self.0).is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A valid number is the same as what rust considers to be valid,
|
|
||||||
/// except for +1., NaN, and Infinity.
|
|
||||||
/// https://html.spec.whatwg.org/multipage/#valid-floating-point-number
|
/// https://html.spec.whatwg.org/multipage/#valid-floating-point-number
|
||||||
pub fn is_valid_number_string(&self) -> bool {
|
pub fn is_valid_floating_point_number_string(&self) -> bool {
|
||||||
let input = &self.0;
|
// for the case that `parse_floating_point_number` cannot handle
|
||||||
input.parse::<f64>().ok().map_or(false, |val| {
|
if self.0.contains(" ") {
|
||||||
!(val.is_infinite() || val.is_nan() || input.ends_with(".") || input.starts_with("+"))
|
return false;
|
||||||
})
|
}
|
||||||
|
parse_floating_point_number(&self.0).is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// https://html.spec.whatwg.org/multipage/#best-representation-of-the-number-as-a-floating-point-number
|
||||||
|
pub fn set_best_representation_of_the_floating_point_number(&mut self) {
|
||||||
|
if let Ok(val) = parse_floating_point_number(&self.0) {
|
||||||
|
self.0 = val.to_string();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A valid normalized local date and time string should be "{date}T{time}"
|
/// A valid normalized local date and time string should be "{date}T{time}"
|
||||||
|
@ -617,7 +623,7 @@ fn parse_time_component(value: &str) -> Result<(u32, u32, f32), ()> {
|
||||||
Ok((hour_int, minute_int, second_float))
|
Ok((hour_int, minute_int, second_float))
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#parse-a-local-date-and-time-string
|
/// https://html.spec.whatwg.org/multipage/#parse-a-local-date-and-time-string
|
||||||
fn parse_local_date_and_time_string(value: &str) -> Result<((u32, u32, u32), (u32, u32, f32)), ()> {
|
fn parse_local_date_and_time_string(value: &str) -> Result<((u32, u32, u32), (u32, u32, f32)), ()> {
|
||||||
// Step 1, 2, 4
|
// Step 1, 2, 4
|
||||||
let mut iterator = if value.contains('T') {
|
let mut iterator = if value.contains('T') {
|
||||||
|
@ -658,7 +664,7 @@ fn max_day_in_month(year_num: u32, month_num: u32) -> Result<u32, ()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#week-number-of-the-last-day
|
/// https://html.spec.whatwg.org/multipage/#week-number-of-the-last-day
|
||||||
fn max_week_in_year(year: u32) -> u32 {
|
fn max_week_in_year(year: u32) -> u32 {
|
||||||
match Utc.ymd(year as i32, 1, 1).weekday() {
|
match Utc.ymd(year as i32, 1, 1).weekday() {
|
||||||
Weekday::Thu => 53,
|
Weekday::Thu => 53,
|
||||||
|
@ -671,3 +677,18 @@ fn max_week_in_year(year: u32) -> u32 {
|
||||||
fn is_leap_year(year: u32) -> bool {
|
fn is_leap_year(year: u32) -> bool {
|
||||||
year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)
|
year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-floating-point-number-values
|
||||||
|
fn parse_floating_point_number(input: &str) -> Result<f64, ()> {
|
||||||
|
match input.trim().parse::<f64>() {
|
||||||
|
Ok(val) if !(
|
||||||
|
// A valid number is the same as what rust considers to be valid,
|
||||||
|
// except for +1., NaN, and Infinity.
|
||||||
|
val.is_infinite() || val.is_nan() || input.ends_with(".") || input.starts_with("+")
|
||||||
|
) => {
|
||||||
|
// TODO(#19773): need consider `min`, `max`, `step`, when they are implemented
|
||||||
|
Ok(val.round())
|
||||||
|
},
|
||||||
|
_ => Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1047,11 +1047,17 @@ impl HTMLInputElement {
|
||||||
}
|
}
|
||||||
InputType::Number => {
|
InputType::Number => {
|
||||||
let mut textinput = self.textinput.borrow_mut();
|
let mut textinput = self.textinput.borrow_mut();
|
||||||
if !textinput.single_line_content().is_valid_number_string() {
|
if !textinput.single_line_content().is_valid_floating_point_number_string() {
|
||||||
textinput.single_line_content_mut().clear();
|
textinput.single_line_content_mut().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Implement more value sanitization algorithms for different types of inputs
|
// https://html.spec.whatwg.org/multipage/#range-state-(type=range):value-sanitization-algorithm
|
||||||
|
InputType::Range => {
|
||||||
|
self.textinput
|
||||||
|
.borrow_mut()
|
||||||
|
.single_line_content_mut()
|
||||||
|
.set_best_representation_of_the_floating_point_number();
|
||||||
|
}
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -550473,7 +550473,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"html/semantics/forms/the-input-element/range.html": [
|
"html/semantics/forms/the-input-element/range.html": [
|
||||||
"dd51c517a149c51e939a30dcad5e93f196e35cff",
|
"e992526fb5f117456a870e52c84eab5a7f4b14ab",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"html/semantics/forms/the-input-element/required_attribute.html": [
|
"html/semantics/forms/the-input-element/required_attribute.html": [
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
[range input value equals 100]
|
[range input value equals 100]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[range input value equals 2]
|
[range input value set to an integer]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
[default value when both min and max attributes are given, while min > max]
|
[default value when both min and max attributes are given, while min > max]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[The default step scale factor is 1, unless min attribute has non-integer value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Step scale factor behavior when min attribute has integer value but max attribute is non-integer ]
|
[Step scale factor behavior when min attribute has integer value but max attribute is non-integer ]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,9 @@
|
||||||
<input type="range" id="stepdown_beyond_min" min=3 max=11 value=6 step=3 />
|
<input type="range" id="stepdown_beyond_min" min=3 max=11 value=6 step=3 />
|
||||||
<input type="range" id="illegal_min_and_max" min="ab" max="f" />
|
<input type="range" id="illegal_min_and_max" min="ab" max="f" />
|
||||||
<input type="range" id="illegal_value_and_step" min=0 max=5 value="ppp" step="xyz" />
|
<input type="range" id="illegal_value_and_step" min=0 max=5 value="ppp" step="xyz" />
|
||||||
|
<input type="range" id="should_skip_whitespace" value=" 123"/>
|
||||||
|
<input type="range" id="exponent_value1" value=""/>
|
||||||
|
<input type="range" id="exponent_value2" value=""/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="log">
|
<div id="log">
|
||||||
|
@ -280,6 +283,35 @@
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
function() {
|
||||||
|
var e = document.getElementById('should_skip_whitespace');
|
||||||
|
assert_equals(e.value, "123")
|
||||||
|
}, "Skip ASCII whitespace within input", {
|
||||||
|
"help" : "https://html.spec.whatwg.org/multipage/#best-representation-of-the-number-as-a-floating-point-number"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
function() {
|
||||||
|
var e = document.getElementById('exponent_value1');
|
||||||
|
e.value = 1e2;
|
||||||
|
assert_equals(e.value, "100")
|
||||||
|
}, "Multiply value by ten raised to the exponentth power with `e`", {
|
||||||
|
"help" : "https://html.spec.whatwg.org/multipage/#best-representation-of-the-number-as-a-floating-point-number"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
function() {
|
||||||
|
var e = document.getElementById('exponent_value2');
|
||||||
|
e.value = 1E2;
|
||||||
|
assert_equals(e.value, "100")
|
||||||
|
}, "Multiply value by ten raised to the exponentth power with `E`", {
|
||||||
|
"help" : "https://html.spec.whatwg.org/multipage/#best-representation-of-the-number-as-a-floating-point-number"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue