1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (c) 2025-2026 the libmagic-rs contributors
// SPDX-License-Identifier: Apache-2.0
//! Graceful-skip logging and child-recursion dispatch shared across the
//! meta-type arms of [`super::evaluate_rules`].
//!
//! Extracted from `engine/mod.rs` as a pure code-motion split (issue #391
//! item 1, Unit U3). `log_pattern_operand_skip` centralizes the debug!/warn!
//! logging for the narrow, allowlisted pattern-operand-skip exception (see
//! GOTCHAS S2.1), and `evaluate_children_or_warn` centralizes the
//! `RecursionGuard` + `evaluate_rules` + error-dispatch pattern that is
//! identical across the `Default`, `Clear`, `Indirect`, `Offset`, and `Use`
//! meta-type arms in `evaluate_rules`.
use evaluate_rules;
use crateLibmagicError;
use crate;
use crateMagicRule;
use ;
/// Logs the graceful skip of a pattern-bearing-type rule whose
/// `TypeReadError` is one of the two narrow allowlisted skip conditions --
/// [`types::TypeReadError::MissingPatternOperand`] or
/// [`types::TypeReadError::RegexCompileError`] (see
/// `TypeReadError::is_pattern_skip` / `is_regex_compile_failure`).
///
/// Shared by all three engine catch sites (`evaluate_children_or_warn`, the
/// top-level dispatch match, and the inline child-recursion match) so a
/// future rewording of the log message only needs one touch point (DRY,
/// AGENTS.md). Split by KTD5 (fix-system-magic-regex-graceful plan): the
/// ordinary missing-pattern case is `debug!`-logged (an expected,
/// low-severity data condition -- e.g. the root-cause parser
/// miscategorization this plan also fixes), while a regex compile failure
/// (which includes the `REGEX_COMPILE_SIZE_LIMIT` CWE-1333 denial-of-service guard) is
/// `warn!`-logged so a malicious or pathological magic file's rejection is
/// not silently invisible, even though the rest of the file's evaluation
/// continues (R1: no fatal abort of the whole evaluation).
pub
/// Evaluate a rule's children under the standard recursion-guard/graceful-skip discipline.
///
/// This helper centralises the `RecursionGuard` + `evaluate_rules` + error-dispatch
/// pattern that is identical across the `Default`, `Indirect`, `Offset`, and `Use`
/// meta-type arms in [`evaluate_rules`]. Extracting it prevents the four copies
/// from drifting apart during future maintenance.
///
/// # Behaviour
///
/// * If `rule.children` is empty the function is a no-op (returns `Ok(())`).
/// * Child matches are appended to `matches` in document order.
/// * `LibmagicError::Timeout` and `LibmagicError::EvaluationError(RecursionLimitExceeded)`
/// propagate immediately as `Err` so the caller can bail out.
/// * Data-dependent errors (`BufferOverrun`, `InvalidOffset`,
/// `InvalidValueTransform`, `TypeReadError::BufferOverrun`,
/// `TypeReadError::InvalidPStringLength`, `IoError`) are logged at `warn!`
/// and swallowed; the parent match
/// already in `matches` is left intact. This mirrors the defensive
/// comment in each arm: the inner `evaluate_rules` already catches and
/// logs individual child failures, so this arm only fires if that
/// strategy changes.
///
/// # Arguments
///
/// * `rule` – The parent rule whose children will be evaluated.
/// * `rule_kind` – A short label for the rule kind used in the `warn!`
/// message (e.g. `"default"`, `"indirect"`, `"offset"`, `"use"`).
/// * `buffer` – The file buffer passed to the recursive call.
/// * `context` – Mutable evaluation context; the recursion depth is
/// incremented on entry and decremented on drop via [`RecursionGuard`].
/// * `matches` – Output vector; child matches are appended here.
pub