mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-02 07:20:55 +00:00
parser: str lit must not be followed by suffix#
Resolves <https://issues.oss-fuzz.com/issues/426509683>.
This commit is contained in:
parent
2e510b0862
commit
76b26cd5fa
@ -12,8 +12,8 @@ use winnow::token::take_until;
|
|||||||
use crate::node::CondTest;
|
use crate::node::CondTest;
|
||||||
use crate::{
|
use crate::{
|
||||||
CharLit, ErrorContext, Level, Num, ParseErr, ParseResult, PathOrIdentifier, Span, StrLit,
|
CharLit, ErrorContext, Level, Num, ParseErr, ParseResult, PathOrIdentifier, Span, StrLit,
|
||||||
StrPrefix, WithSpan, char_lit, filter, identifier, keyword, num_lit, path_or_identifier,
|
StrPrefix, WithSpan, char_lit, filter, identifier, keyword, not_suffix_with_hash, num_lit,
|
||||||
skip_ws0, skip_ws1, str_lit, ws,
|
path_or_identifier, skip_ws0, skip_ws1, str_lit, ws,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! expr_prec_layer {
|
macro_rules! expr_prec_layer {
|
||||||
@ -774,9 +774,9 @@ impl<'a> Suffix<'a> {
|
|||||||
// <https://doc.rust-lang.org/reference/tokens.html>
|
// <https://doc.rust-lang.org/reference/tokens.html>
|
||||||
let some_other = alt((
|
let some_other = alt((
|
||||||
// literals
|
// literals
|
||||||
Expr::char.value(Token::SomeOther),
|
char_lit.value(Token::SomeOther),
|
||||||
Expr::str.value(Token::SomeOther),
|
str_lit.value(Token::SomeOther),
|
||||||
Expr::num.value(Token::SomeOther),
|
num_lit.value(Token::SomeOther),
|
||||||
// keywords + (raw) identifiers + raw strings
|
// keywords + (raw) identifiers + raw strings
|
||||||
identifier_or_prefixed_string.value(Token::SomeOther),
|
identifier_or_prefixed_string.value(Token::SomeOther),
|
||||||
// lifetimes
|
// lifetimes
|
||||||
@ -886,6 +886,7 @@ impl<'a> Suffix<'a> {
|
|||||||
return Err(winnow::error::ErrMode::Cut(ErrorContext::new(msg, prefix)));
|
return Err(winnow::error::ErrMode::Cut(ErrorContext::new(msg, prefix)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_suffix_with_hash(i)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if hashes == 0 {
|
} else if hashes == 0 {
|
||||||
// a simple identifier
|
// a simple identifier
|
||||||
|
@ -680,9 +680,20 @@ fn str_lit<'a>(i: &mut &'a str) -> ParseResult<'a, StrLit<'a>> {
|
|||||||
return Err(winnow::error::ErrMode::Cut(ErrorContext::new(msg, start)));
|
return Err(winnow::error::ErrMode::Cut(ErrorContext::new(msg, start)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_suffix_with_hash(i)?;
|
||||||
Ok(lit)
|
Ok(lit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn not_suffix_with_hash<'a>(i: &mut &'a str) -> ParseResult<'a, ()> {
|
||||||
|
if let Some(suffix) = opt((identifier, '#').take()).parse_next(i)? {
|
||||||
|
return Err(winnow::error::ErrMode::Cut(ErrorContext::new(
|
||||||
|
"you are missing a space to separate two string literals",
|
||||||
|
suffix,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn str_lit_without_prefix<'a>(i: &mut &'a str) -> ParseResult<'a> {
|
fn str_lit_without_prefix<'a>(i: &mut &'a str) -> ParseResult<'a> {
|
||||||
let start = *i;
|
let start = *i;
|
||||||
let lit = str_lit.parse_next(i)?;
|
let lit = str_lit.parse_next(i)?;
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
˙˙˙ {{ l ! { """" "" ""r#" """"""#"""""""""" }}} ˙ }o Ë
|
@ -105,4 +105,19 @@ struct MacroCallReservedPrefix2;
|
|||||||
#[template(path = "macro-call-raw-string-many-hashes.html")]
|
#[template(path = "macro-call-raw-string-many-hashes.html")]
|
||||||
struct MacroCallManyHashes;
|
struct MacroCallManyHashes;
|
||||||
|
|
||||||
|
// Need a space between (guarded) string literal and next prefixed string literal.
|
||||||
|
// Regression test for <https://issues.oss-fuzz.com/issues/426509683>.
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(source = r##"{{ z!(r""r#""#) }}"##, ext = "txt")]
|
||||||
|
struct UnseparatedPrefixedStrings1;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(source = r##"{{ z!(r#""#x#"") }}"##, ext = "txt")]
|
||||||
|
struct UnseparatedPrefixedStrings2;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(source = r##"{{ z!(c""r#""#) }}"##, ext = "txt")]
|
||||||
|
struct UnseparatedPrefixedStrings3;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -109,3 +109,27 @@ error: a maximum of 255 hashes `#` are allowed with raw strings
|
|||||||
|
|
|
|
||||||
105 | #[template(path = "macro-call-raw-string-many-hashes.html")]
|
105 | #[template(path = "macro-call-raw-string-many-hashes.html")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: you are missing a space to separate two string literals
|
||||||
|
--> <source attribute>:1:9
|
||||||
|
"r#\"\"#) }}"
|
||||||
|
--> tests/ui/raw-prefix.rs:112:21
|
||||||
|
|
|
||||||
|
112 | #[template(source = r##"{{ z!(r""r#""#) }}"##, ext = "txt")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: you are missing a space to separate two string literals
|
||||||
|
--> <source attribute>:1:11
|
||||||
|
"x#\"\") }}"
|
||||||
|
--> tests/ui/raw-prefix.rs:116:21
|
||||||
|
|
|
||||||
|
116 | #[template(source = r##"{{ z!(r#""#x#"") }}"##, ext = "txt")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: you are missing a space to separate two string literals
|
||||||
|
--> <source attribute>:1:9
|
||||||
|
"r#\"\"#) }}"
|
||||||
|
--> tests/ui/raw-prefix.rs:120:21
|
||||||
|
|
|
||||||
|
120 | #[template(source = r##"{{ z!(c""r#""#) }}"##, ext = "txt")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Loading…
x
Reference in New Issue
Block a user