Skip to main content

evaluate_single_rule

Function evaluate_single_rule 

Source
pub fn evaluate_single_rule(
    rule: &MagicRule,
    buffer: &[u8],
    context: &mut EvaluationContext,
) -> Result<Vec<RuleMatch>, LibmagicError>
Expand description

Evaluate a single magic rule against a file buffer

This is a thin wrapper around evaluate_rules that evaluates exactly one top-level rule (and any of its children) against a buffer, using the caller-provided EvaluationContext to enforce timeout, recursion, and string-size limits. It is a BREAKING API change introduced in pre-1.0: earlier versions took no context and returned Option<(usize, Value)>.

§Arguments

  • rule - The magic rule to evaluate
  • buffer - The file buffer to evaluate against
  • context - Mutable evaluation context that carries the configured safety limits (timeout, max recursion depth, max string length) and the GNU file previous-match anchor used for relative-offset resolution. Callers reusing a context across multiple buffers must call EvaluationContext::reset between calls – see evaluate_rules for details.

§Returns

Returns Ok(Vec<RuleMatch>) containing the parent match (if the rule matched) plus any child matches collected recursively. An empty vector means the rule did not match or was skipped due to a data-dependent evaluation error (buffer overrun, invalid offset, etc.). Only critical failures such as LibmagicError::Timeout or recursion-limit exhaustion are returned as Err.

§Examples

use libmagic_rs::evaluator::{evaluate_single_rule, EvaluationContext};
use libmagic_rs::EvaluationConfig;
use libmagic_rs::parser::ast::{MagicRule, OffsetSpec, TypeKind, Operator, Value};

// Create a rule to check for ELF magic bytes at offset 0
let rule = MagicRule::new(OffsetSpec::Absolute(0), TypeKind::Byte { signed: true }, Operator::Equal, Value::Uint(0x7f), "ELF magic".to_string());

let mut context = EvaluationContext::new(EvaluationConfig::default());
let elf_buffer = &[0x7f, 0x45, 0x4c, 0x46]; // ELF magic bytes
let matches = evaluate_single_rule(&rule, elf_buffer, &mut context).unwrap();
assert_eq!(matches.len(), 1); // Should match

context.reset();
let non_elf_buffer = &[0x50, 0x4b, 0x03, 0x04]; // ZIP magic bytes
let matches = evaluate_single_rule(&rule, non_elf_buffer, &mut context).unwrap();
assert!(matches.is_empty()); // Should not match

§Errors

  • LibmagicError::Timeout - If evaluation exceeds the configured timeout
  • LibmagicError::EvaluationError - For critical failures such as the recursion limit being exceeded. Data-dependent errors (buffer overrun, invalid offset, malformed pstring length) are handled gracefully by evaluate_rules and surface as an empty match vector rather than an error.