Skip to content

Reject word sizes struct cannot express - #364

Open
zardus wants to merge 1 commit into
masterfrom
feature/fix-word-width
Open

Reject word sizes struct cannot express#364
zardus wants to merge 1 commit into
masterfrom
feature/fix-word-width

Conversation

@zardus

@zardus zardus commented Aug 9, 2026

Copy link
Copy Markdown
Member

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Arch.struct_fmt() returned "Z" for a three-byte word, so every 24-bit p-code architecture — the PIC, HCS-12 and extended AVR languages among them — handed its callers a format string that raises "bad char in struct format" as soon as anything uses it.

struct has integer format characters for one, two, four and eight bytes and no way to name a three-byte integer, so the size really is invalid and this function should say so rather than invent a character for it.

The regression checks that ArchPcode("HCS-12:BE:24:default").struct_fmt() raises, and that every size struct can express still round-trips through calcsize.

angr/cle#721 is the other half of this. Validation: #364 (comment).

struct_fmt() returned "Z" for a 3-byte word. That is not a struct format
character, so every 24-bit architecture handed its callers a format string
that raises "bad char in struct format" on use. struct has integer format
characters for 1, 2, 4 and 8 bytes only and no way to describe a 3-byte
integer, so report the size as invalid instead of inventing a character for
it; such a word has to be assembled from bytes by the caller.
@zardus

zardus commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Validation record for head 6faa1ee404c78c908317aac60868f35955b2ea02 against baseline da171ca0dd8eec1e16dd9c4f04576b2c958e2aea.

  • Reproducer: python -c "import archinfo, struct; print(archinfo.ArchPcode('HCS-12:BE:24:default').struct_fmt())" — prints >Z on baseline, and struct.calcsize('>Z') then raises bad char in struct format; raises ValueError on head
  • Regression: python -m pytest tests/test_pcode.py::TestArchPcode::test_struct_fmt_24bit tests/test_struct_fmt.py — both fail on baseline (struct_fmt() returns a format character instead of raising), pass on head
  • Full suite: python -m pytest tests/ — 20 passed
  • Lint/type: pylint and pyright scored per changed file against the merge base, the way the hosted jobs score them — archinfo/arch.py 9.70 -> 9.70, tests/test_pcode.py 10.00 -> 10.00, tests/test_struct_fmt.py new file 10.00; pyright badness 0.2227 -> 0.2222, 0.0 -> 0.0, 0.0 -> 0.0
  • Pre-commit: pre-commit run --all-files — every hook passes, no rewrites
  • Workspace gate: archinfo and cle suites, hooks and workspace checks under Python 3.12 — exit 0 twice on this exact state

Scope: 14 of the 183 p-code languages pypcode 4.0.1.dev0 exposes report a three-byte word — HCS-12, HCS12, HCS-12X, PIC-18, PIC-24E/F/H, dsPIC30F, dsPIC33C/E/F and the three extended AVR languages. All returned Z on baseline, regardless of input. It surfaced in a corpus sweep running CFGFast, out of Clemory.unpack_word (angr/cle#721).

Caveats: test_struct_fmt_24bit lives in TestArchPcode, which skips without pypcode — an optional extra here, so the Windows and macOS uv run pytest jobs skip it. tests/test_struct_fmt.py covers the same contract on ArchAMD64 and runs everywhere.

@angr-bot

angr-bot commented Aug 9, 2026

Copy link
Copy Markdown
Member

Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/archinfo_364

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants