mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-01 23:10:54 +00:00
Fix wrong parsing of number if digit does not match base
This commit is contained in:
parent
56f9288eda
commit
f021599064
@ -528,6 +528,35 @@ pub enum Num<'a> {
|
|||||||
Float(&'a str, Option<FloatKind>),
|
Float(&'a str, Option<FloatKind>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_base_digits<'a>(digits: &'a str, base: u32, span: Range<usize>) -> ParseResult<'a, ()> {
|
||||||
|
let allowed_digits: &[char] = match base {
|
||||||
|
2 => &['0', '1'],
|
||||||
|
8 => &['0', '1', '2', '3', '4', '5', '6', '7'],
|
||||||
|
16 => &[
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||||
|
],
|
||||||
|
_ => panic!("unsupported base `{base}`"),
|
||||||
|
};
|
||||||
|
|
||||||
|
for digit in digits.chars() {
|
||||||
|
let lower = digit.to_ascii_lowercase();
|
||||||
|
if lower != '_' && !allowed_digits.iter().any(|c| *c == digit || *c == lower) {
|
||||||
|
let allowed = allowed_digits.iter().collect::<String>();
|
||||||
|
let base = match base {
|
||||||
|
2 => 'b',
|
||||||
|
8 => 'o',
|
||||||
|
16 => 'x',
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
return cut_error!(
|
||||||
|
format!("only expected `{allowed}` digits for `0{base}` integers, found `{digit}`"),
|
||||||
|
span,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn num_lit<'a: 'l, 'l>(i: &mut InputStream<'a, 'l>) -> ParseResult<'a, Num<'a>> {
|
fn num_lit<'a: 'l, 'l>(i: &mut InputStream<'a, 'l>) -> ParseResult<'a, Num<'a>> {
|
||||||
fn num_lit_suffix<'a: 'l, 'l, T: Copy>(
|
fn num_lit_suffix<'a: 'l, 'l, T: Copy>(
|
||||||
kind: &'a str,
|
kind: &'a str,
|
||||||
@ -552,8 +581,8 @@ fn num_lit<'a: 'l, 'l>(i: &mut InputStream<'a, 'l>) -> ParseResult<'a, Num<'a>>
|
|||||||
.with_taken()
|
.with_taken()
|
||||||
.with_span()
|
.with_span()
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
match opt(separated_digits(base, false)).parse_next(i)? {
|
match opt(separated_digits(if base == 16 { base } else { 10 }, false)).parse_next(i)? {
|
||||||
Some(_) => Ok(()),
|
Some(digits) => check_base_digits(digits, base, span),
|
||||||
None => cut_error!(format!("expected digits after `{kind}`"), span),
|
None => cut_error!(format!("expected digits after `{kind}`"), span),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1812,4 +1841,17 @@ mod test {
|
|||||||
assert!(!is_rust_keyword("supeeeer"));
|
assert!(!is_rust_keyword("supeeeer"));
|
||||||
assert!(!is_rust_keyword("sur"));
|
assert!(!is_rust_keyword("sur"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_check_base_digits() {
|
||||||
|
assert!(check_base_digits("10", 2, 0..1).is_ok());
|
||||||
|
assert!(check_base_digits("13", 2, 0..1).is_err());
|
||||||
|
assert!(check_base_digits("13", 8, 0..1).is_ok());
|
||||||
|
assert!(check_base_digits("79", 8, 0..1).is_err());
|
||||||
|
// Checking that it's case insensitive.
|
||||||
|
assert!(check_base_digits("13F", 16, 0..1).is_ok());
|
||||||
|
assert!(check_base_digits("13f", 16, 0..1).is_ok());
|
||||||
|
// Checking that `_` is allowed.
|
||||||
|
assert!(check_base_digits("13_f", 16, 0..1).is_ok());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user