Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement range input sanitization #19761

Merged
merged 1 commit into from Jan 17, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

implement range input sanitization

  • Loading branch information
tigercosmos committed Jan 17, 2018
commit b29230bd76ea30ab42fab724fe72a18c396d5e49
@@ -286,31 +286,37 @@ impl DOMString {
/// YYYY must be four or more digits, MM and DD both must be two digits
/// https://html.spec.whatwg.org/multipage/#valid-date-string
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"
/// YYYY must be four or more digits, MM both must be two digits
/// https://html.spec.whatwg.org/multipage/#valid-month-string
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"
/// YYYY must be four or more digits, WW both must be two digits
/// https://html.spec.whatwg.org/multipage/#valid-week-string
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
pub fn is_valid_number_string(&self) -> bool {
let input = &self.0;
input.parse::<f64>().ok().map_or(false, |val| {
!(val.is_infinite() || val.is_nan() || input.ends_with(".") || input.starts_with("+"))
})
pub fn is_valid_floating_point_number_string(&self) -> bool {
// for the case that `parse_floating_point_number` cannot handle
if self.0.contains(" ") {
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}"
@@ -617,7 +623,7 @@ fn parse_time_component(value: &str) -> Result<(u32, u32, f32), ()> {
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)), ()> {
// Step 1, 2, 4
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 {
match Utc.ymd(year as i32, 1, 1).weekday() {
Weekday::Thu => 53,
@@ -671,3 +677,18 @@ fn max_week_in_year(year: u32) -> u32 {
fn is_leap_year(year: u32) -> bool {
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 => {
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();
}
}
// 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();

This comment has been minimized.

@nox

nox Jan 15, 2018

Member

Please add a spec link for this.

This comment has been minimized.

@tigercosmos

tigercosmos Jan 15, 2018

Author Collaborator

sure

}
_ => ()
}
}
"testharness"
],
"html/semantics/forms/the-input-element/range.html": [
"dd51c517a149c51e939a30dcad5e93f196e35cff",
"e992526fb5f117456a870e52c84eab5a7f4b14ab",
"testharness"
],
"html/semantics/forms/the-input-element/required_attribute.html": [
@@ -9,6 +9,6 @@
[range input value equals 100]
expected: FAIL

[range input value equals 2]
[range input value set to an integer]

This comment has been minimized.

@nox

nox Jan 15, 2018

Member

Why does this test now fail?

This comment has been minimized.

@tigercosmos

tigercosmos Jan 15, 2018

Author Collaborator

Originally pass because of accident, in other words, it is lucky.
Origin code doesn't do anything, but we now add logic.

This comment has been minimized.

@KiChjang

KiChjang Jan 16, 2018

Member

Can you elaborate on what this accident is about? Is it a case of where two negatives makes a positive?

This comment has been minimized.

@tigercosmos

tigercosmos Jan 16, 2018

Author Collaborator

there is no function to check the value originally, so the output is still as same as input, which made it passed. But the new code do some checking, and without step inside, the checking is not completed. That's why here is a test become to failed.

range input value equals 2 test:
the divisor is 1 as default, so 4.6 will turn to 5
but when step is 0.1, 4.6 is still 4.6, and 4.67 will turn to be 4.7

expected: FAIL

@@ -21,9 +21,6 @@
[default value when both min and max attributes are given, while min > max]
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 ]
expected: FAIL

@@ -34,6 +34,9 @@ <h1>Input Range</h1>
<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_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 id="log">
@@ -280,6 +283,35 @@ <h1>Input Range</h1>
}
);

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>

</body>
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.