Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ See **Development Phases** below for the planned roadmap of features not yet imp

- Indirect offsets are fully implemented (parsing + evaluation) with specifiers: `.b/.B` (byte), `.s/.S` (short), `.l/.L` (long), `.q/.Q` (quad); lowercase = little-endian, uppercase = big-endian (GNU `file` semantics); pointer types signed by default. Adjustment is accepted both **inside** the parens (canonical magic(5): `(base.type+N)`, `(base.type-N)`, `(base.type*N)`, `(base.type/N)`, `(base.type%N)`, `(base.type&N)`, `(base.type|N)`, `(base.type^N)`) and **after** the closing paren as a legacy form (`(base.type)+N`, `(base.type)-N` only). Only one form per rule. Anchor-relative variants are supported via `base_relative` (the `(&N.X)` form -- pointer-read base is `anchor + N`) and `result_relative` (the `&(N.X)` wrapper -- final offset is added to the anchor) on `OffsetSpec::Indirect`.
- **Pre-comparison value transforms**: `type+N`, `type-N`, `type*N`, `type/N`, `type%N`, `type|N`, `type^N` between the type keyword and the operator. The transform runs on the read value before the comparison and before printf-style format substitution. Stored on `MagicRule::value_transform` as `ValueTransform { op, operand }` (default: `None`). magic(5) usage: `lelong+1 x volume %d`, `ulequad/1073741824 x size %lluGB`. Bitwise AND (`&MASK`) is *not* part of `ValueTransformOp` -- it predates this enum and is encoded at the operator layer via `Operator::BitwiseAndMask`.
- Relative offsets are fully evaluated against the GNU `file` previous-match anchor: the engine tracks `EvaluationContext::last_match_end()`, advancing it after each successful match by the bytes consumed (variable-width types include c-string NUL terminators and pstring length prefixes). Top-level relative offsets resolve from anchor 0. Magic-file `&+N`/`&-N` *parsing* is still TODO -- relative offsets are exercised programmatically through the AST.
- Relative offsets are fully evaluated against the GNU `file` previous-match anchor: the engine tracks `EvaluationContext::last_match_end()`, advancing it after each successful match by the bytes consumed (variable-width types include c-string NUL terminators and pstring length prefixes). Top-level relative offsets resolve from anchor 0. Magic-file `&N`, `&+N`, and `&-N` parsing is implemented (decimal and `0x` hex forms supported; bare `&` is rejected). See `parse_offset_relative` in `src/parser/grammar/tests/mod.rs` for the parse-side coverage.

### Magic File Syntax

Expand Down
2 changes: 1 addition & 1 deletion GOTCHAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Inside a `MetaType::Use` subroutine body, `OffsetSpec::Absolute(n)` with `n >= 0

### 3.11 `parse_text_magic_file` is Fail-Fast, Not Skip-on-Error

`build_rule_hierarchy` propagates any `parse_magic_rule_line` error immediately, so a single unparseable rule (e.g., a child using unsupported `&+N` relative-offset syntax or an unquoted `$VAR` string value -- see S3.6) causes the **entire file load** to fail with `ParseError::InvalidSyntax`. There is no skip-and-continue mode. When writing corpus tests against third_party `.magic` files that mix supported and unsupported syntax, bypass the parser and build the equivalent `MagicRule` tree programmatically via the AST; the runtime evaluator can still be exercised end-to-end against the real testfile buffer. See `tests/evaluator_tests.rs::test_regex_eol_corpus` for a worked example.
`build_rule_hierarchy` propagates any `parse_magic_rule_line` error immediately, so a single unparseable rule (e.g., a string value using unquoted `$VAR` substitution on a non-string-family type -- see S3.6) causes the **entire file load** to fail with `ParseError::InvalidSyntax`. There is no skip-and-continue mode. When writing corpus tests against third_party `.magic` files that mix supported and unsupported syntax, bypass the parser and build the equivalent `MagicRule` tree programmatically via the AST; the runtime evaluator can still be exercised end-to-end against the real testfile buffer. See `tests/evaluator_tests.rs::test_regex_eol_corpus` for a worked example.

### 3.10 `parse_text_magic_file` Returns `ParsedMagic`, Not `Vec<MagicRule>`

Expand Down
Loading