MCPcopy Create free account
hub / github.com/block/buzz / evaluate_condition

Function evaluate_condition

crates/buzz-workflow/src/executor.rs:364–399  ·  view source on GitHub ↗

Evaluate a boolean `if:` expression against the current execution context. Returns `true` if the step should run, `false` if it should be skipped. The evaluation is wrapped in a [`tokio::time::timeout`] to prevent a malicious or pathological expression from blocking a Tokio worker thread.

(
    expr: &str,
    trigger_ctx: &TriggerContext,
    step_outputs: &HashMap<String, JsonValue>,
)

Source from the content-addressed store, hash-verified

362/// The evaluation is wrapped in a [`tokio::time::timeout`] to prevent a
363/// malicious or pathological expression from blocking a Tokio worker thread.
364pub async fn evaluate_condition(
365 expr: &str,
366 trigger_ctx: &TriggerContext,
367 step_outputs: &HashMap<String, JsonValue>,
368) -> Result<bool, WorkflowError> {
369 let ctx = build_eval_context(trigger_ctx, step_outputs)?;
370 let expr_owned = expr.to_owned();
371
372 // Bound expression complexity to prevent pathological evaluation times.
373 // The spawn_blocking thread cannot be cancelled by tokio::time::timeout —
374 // it will run to completion even after timeout. Length-limiting the expression
375 // prevents worst-case O(2^n) evaluation paths.
376 const MAX_EXPR_LEN: usize = 4096;
377 if expr_owned.len() > MAX_EXPR_LEN {
378 return Err(WorkflowError::ConditionError(format!(
379 "condition expression exceeds {} byte limit",
380 MAX_EXPR_LEN
381 )));
382 }
383
384 let result = tokio::time::timeout(
385 EVAL_TIMEOUT,
386 tokio::task::spawn_blocking(move || evalexpr::eval_boolean_with_context(&expr_owned, &ctx)),
387 )
388 .await
389 .map_err(|_| {
390 WorkflowError::ConditionError(format!(
391 "'{expr}': evaluation timed out after {}ms",
392 EVAL_TIMEOUT.as_millis()
393 ))
394 })?
395 .map_err(|e| WorkflowError::ConditionError(format!("'{expr}': eval task panicked: {e}")))?
396 .map_err(|e| WorkflowError::ConditionError(format!("'{expr}': {e}")))?;
397
398 Ok(result)
399}
400
401/// Resolve all template variables in a step's action fields.
402///

Calls 1

build_eval_contextFunction · 0.70

Tested by

no test coverage detected