From 1cbf4e3158fd3f1a62b321685240ddc7642db806 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 10 May 2023 15:16:55 +0000 Subject: [PATCH] Merge pull request #577 from nickvollmar/single-quote-parameters Fix parameter passing for single-quoted string literals --- src/template.rs | 28 +++++++++++++++++++++++++--- tests/escape.rs | 25 +++++++++++++++++++++++++ tests/helper_macro.rs | 20 ++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/template.rs b/src/template.rs index f01016722..4bde14859 100644 --- a/src/template.rs +++ b/src/template.rs @@ -288,11 +288,33 @@ impl Template { Parameter::Path(Path::new(param_span.as_str(), path_segs)) } Rule::literal => { - let s = param_span.as_str(); - if let Ok(json) = Json::from_str(s) { + // Parse the parameter as a JSON literal + let param_literal = it.next().unwrap(); + let json_result = match param_literal.as_rule() { + Rule::string_literal + if it.peek().unwrap().as_rule() == Rule::string_inner_single_quote => + { + // ...unless the parameter is a single-quoted string. + // In that case, transform it to a double-quoted string + // and then parse it as a JSON literal. + let string_inner_single_quote = it.next().unwrap(); + let double_quoted = format!( + "\"{}\"", + string_inner_single_quote + .as_str() + .replace("\\'", "'") + .replace('"', "\\\"") + ); + Json::from_str(&double_quoted) + } + _ => Json::from_str(param_span.as_str()), + }; + if let Ok(json) = json_result { Parameter::Literal(json) } else { - Parameter::Name(s.to_owned()) + return Err(TemplateError::of(TemplateErrorReason::InvalidParam( + param_span.as_str().to_owned(), + ))); } } Rule::subexpression => { diff --git a/tests/escape.rs b/tests/escape.rs index 4a737f5ce..2b9512290 100644 --- a/tests/escape.rs +++ b/tests/escape.rs @@ -27,19 +27,44 @@ fn test_string_no_escape_422() { handlebars_helper!(replace: |input: str, from: str, to: str| { input.replace(from, to) }); + handlebars_helper!(echo: |input: str| { + input + }); hbs.register_helper("replace", Box::new(replace)); + hbs.register_helper("echo", Box::new(echo)); assert_eq!( r#"some\ path"#, hbs.render_template(r#"{{replace "some/path" "/" "\\ " }}"#, &()) .unwrap() ); + assert_eq!( + r#"some\ path"#, + hbs.render_template(r#"{{replace 'some/path' '/' '\\ ' }}"#, &()) + .unwrap() + ); assert_eq!( r#"some\path"#, hbs.render_template(r#"{{replace "some/path" "/" "\\" }}"#, &()) .unwrap() ); + assert_eq!( + r#"some\path"#, + hbs.render_template(r#"{{replace 'some/path' '/' '\\' }}"#, &()) + .unwrap() + ); + + assert_eq!( + r#"double-quoted \ 'with' "nesting""#, + hbs.render_template(r#"{{echo "double-quoted \\ 'with' \"nesting\""}}"#, &()) + .unwrap() + ); + assert_eq!( + r#"single-quoted \ 'with' "nesting""#, + hbs.render_template(r#"{{echo 'single-quoted \\ \'with\' "nesting"'}}"#, &()) + .unwrap() + ); } #[test] diff --git a/tests/helper_macro.rs b/tests/helper_macro.rs index cc5ed914b..f40ab778a 100644 --- a/tests/helper_macro.rs +++ b/tests/helper_macro.rs @@ -86,4 +86,24 @@ fn test_macro_helper() { .unwrap(), "2015-02-18" ); + + assert_eq!( + hbs.render_template("{{eq image.link null}}", &json!({"image": {"link": null}})) + .unwrap(), + "true" + ); + + assert_eq!( + hbs.render_template( + "{{eq image.link null}}", + &json!({"image": {"link": "https://url"}}) + ) + .unwrap(), + "false" + ); + + assert_eq!( + hbs.render_template("{{tag 'html'}}", &()).unwrap(), + "<html>" + ); }