mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-08-14 07:32:05 +02:00
Fix nested template function depth tracking (#523)
Co-authored-by: Su <26924933+674019130@users.noreply.github.com>
This commit is contained in:
@@ -135,6 +135,10 @@ async fn render_value<T: TemplateCallback>(
|
||||
opt: &RenderOptions,
|
||||
depth: usize,
|
||||
) -> Result<String> {
|
||||
if depth > MAX_DEPTH {
|
||||
return opt.error_behavior.handle(Err(RenderStackExceededError));
|
||||
}
|
||||
|
||||
let v = match val {
|
||||
Val::Str { text } => {
|
||||
let r = Box::pin(parse_and_render_at_depth(&text, vars, cb, opt, depth)).await?;
|
||||
@@ -154,7 +158,7 @@ async fn render_value<T: TemplateCallback>(
|
||||
Val::Bool { value } => serde_json::Value::Bool(value),
|
||||
Val::Null => serde_json::Value::Null,
|
||||
_ => serde_json::Value::String(
|
||||
Box::pin(render_value(a.value, vars, cb, opt, depth)).await?,
|
||||
Box::pin(render_value(a.value, vars, cb, opt, depth + 1)).await?,
|
||||
),
|
||||
};
|
||||
resolved_args.insert(a.name, v);
|
||||
@@ -498,6 +502,50 @@ mod parse_and_render_tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn rejects_nested_function_args_beyond_max_depth() -> Result<()> {
|
||||
struct CB {}
|
||||
impl TemplateCallback for CB {
|
||||
async fn run(
|
||||
&self,
|
||||
_fn_name: &str,
|
||||
args: HashMap<String, serde_json::Value>,
|
||||
) -> Result<String> {
|
||||
Ok(args["value"].as_str().unwrap_or_default().to_string())
|
||||
}
|
||||
|
||||
fn transform_arg(
|
||||
&self,
|
||||
_fn_name: &str,
|
||||
_arg_name: &str,
|
||||
arg_value: &str,
|
||||
) -> Result<String> {
|
||||
Ok(arg_value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
let nested_beyond_limit = (0..=super::MAX_DEPTH)
|
||||
.fold("'ok'".to_string(), |value, _| format!("identity(value={value})"));
|
||||
let template_beyond_limit = format!("${{[ {nested_beyond_limit} ]}}");
|
||||
let vars = HashMap::new();
|
||||
|
||||
assert_eq!(
|
||||
parse_and_render(&template_beyond_limit, &vars, &CB {}, &RenderOptions::throw()).await,
|
||||
Err(RenderStackExceededError)
|
||||
);
|
||||
assert_eq!(
|
||||
parse_and_render(
|
||||
&template_beyond_limit,
|
||||
&vars,
|
||||
&CB {},
|
||||
&RenderOptions::return_empty(),
|
||||
)
|
||||
.await,
|
||||
Ok(String::new())
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn render_fn_err() -> Result<()> {
|
||||
let vars = HashMap::new();
|
||||
|
||||
Reference in New Issue
Block a user