diff --git a/src/input/shared.rs b/src/input/shared.rs index 95b9912a5..0c81c1cfe 100644 --- a/src/input/shared.rs +++ b/src/input/shared.rs @@ -122,6 +122,22 @@ fn clean_int_str(mut s: &str) -> Option> { s = suffix; } + // Remember if the number is negative + // the `strip_leading_zeros` function will not strip leading zeros for negative numbers + // therefore we simply "take away" the unary minus sign temporarily and add it back before + // returning. This allows consistent handling of leading zeros for both positive and negative numbers. + let mut is_negative = false; + if let Some(suffix) = s.strip_prefix('-') { + // Invalidate "--" and "-+" as an integer prefix by returning None + if suffix.starts_with('-') | suffix.starts_with('+') { + return None; + } + + is_negative = true; + // Continue as usual without the unary minus sign + s = suffix; + } + // strip loading zeros s = strip_leading_zeros(s)?; @@ -136,13 +152,20 @@ fn clean_int_str(mut s: &str) -> Option> { // remove underscores if let Some(str_stripped) = strip_underscores(s) { - Some(str_stripped.into()) - } else { - match len_before == s.len() { - true => None, - false => Some(s.into()), + match is_negative { + true => return Some(("-".to_string() + &str_stripped).into()), + false => return Some(str_stripped.into()), } } + + if len_before == s.len() { + return None; + } + + match is_negative { + true => Some(("-".to_string() + s).into()), + false => Some(s.into()), + } } /// strip leading zeros from a string, we can't simple use `s.trim_start_matches('0')`, because: diff --git a/tests/validators/test_int.py b/tests/validators/test_int.py index f93919f17..47944126a 100644 --- a/tests/validators/test_int.py +++ b/tests/validators/test_int.py @@ -52,6 +52,12 @@ ('++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')), + ('--0001', Err('Input should be a valid integer, unable to parse string as an integer')), + ('-+0001', Err('Input should be a valid integer, unable to parse string as an integer')), + ('-0-001', Err('Input should be a valid integer, unable to parse string as an integer')), + ('-0+001', Err('Input should be a valid integer, unable to parse string as an integer')), + ('-00001', -1), + ('-00042_000', -42000), ('4_2', 42), ('0_42', 42), ('4_2.0', 42),