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

fix validation of ints with leading unary minus #1291

Merged
merged 1 commit into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/input/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,13 @@ fn clean_int_str(mut s: &str) -> Option<Cow<str>> {
// strip leading and trailing whitespace
s = s.trim();

// strip leading unary plus
s = s.strip_prefix('+').unwrap_or(s);
// Check for and remove a leading unary plus and ensure the next character is not a unary minus. e.g.: '+-1'.
if let Some(suffix) = s.strip_prefix('+') {
if suffix.starts_with('-') {
return None;
}
s = suffix;
}

// strip loading zeros
s = strip_leading_zeros(s)?;
Expand Down Expand Up @@ -149,17 +154,17 @@ fn strip_leading_zeros(s: &str) -> Option<&str> {
match char_iter.next() {
// if we get a leading zero we continue
Some((_, '0')) => (),
// if we get another digit we return the whole string
Some((_, c)) if ('1'..='9').contains(&c) => return Some(s),
// if we get another digit or unary minus we return the whole string
Some((_, c)) if ('1'..='9').contains(&c) || c == '-' => return Some(s),
// anything else is invalid, we return None
_ => return None,
};
for (i, c) in char_iter {
match c {
// continue on more leading zeros or if we get an underscore we continue - we're "within the number"
'0' | '_' => (),
// any other digit we return the rest of the string
'1'..='9' => return Some(&s[i..]),
// any other digit or unary minus we return the rest of the string
'1'..='9' | '-' => return Some(&s[i..]),
// if we get a dot we return the rest of the string but include the last zero
'.' => return Some(&s[(i - 1)..]),
// anything else is invalid, we return None
Expand Down
3 changes: 3 additions & 0 deletions tests/validators/test_int.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
('+0_000', 0),
(1, 1),
(' 1 ', 1),
('-1', -1),
('-1.0', -1),
(42, 42),
('42', 42),
(42.0, 42),
Expand All @@ -48,6 +50,7 @@
('+4_2.0', 42),
('+04_2.0', 42),
('++4_2', Err('Input should be a valid integer, unable to parse string as an integer')),
('-+1', Err('Input should be a valid integer, unable to parse string as an integer')),
('+-1', Err('Input should be a valid integer, unable to parse string as an integer')),
('4_2', 42),
('0_42', 42),
Expand Down