Files
libfreemkv/docs/class-reader.md
T
Matthew Jackson 6e14fc0c0c libfreemkv: 1.7.0 groundwork — sector-recycle soundness + CI hardening
Security
- Remove the unsafe Vec::set_len over recycled sector buffers — UB reachable
  from safe code (GHSA-j8ww-f5fg-9pmh, low). Uses Vec::resize; pooling unchanged.

CI / tooling
- clippy on stable with the MSRV single-sourced from Cargo.toml; cargo-deny
  dependency-audit gate with first-party git sources allowed (#15); audience-based
  comment-guard (#17).

Docs
- README (keydb ownership, BD-J parser count), drive-access transport/reset
  notes, mux timeline module-doc links.
2026-09-02 12:40:55 -07:00

2.2 KiB

labels::class_reader

Hand-rolled JVM .class file reader, tailored to the subset needed for BD-J label extraction (Deluxe / dbp / similar frameworks). Implements JVMS §4 (class file format) and §6 (bytecode) only as far as: constant pool, methods, the Code attribute, and a non-allocating bytecode iterator.

No external deps beyond std. No unsafe. No panics on malformed input — every parse fault is a typed Error. This is shared infrastructure for any label parser that needs structured access to .class files inside a /BDMV/JAR/<x>.jar.

ConstantPool::from_entries

Test-only constructor — builds a constant pool directly from a vector of entries. Real callers go through ClassFile::parse, which builds this from class-file bytes. Used by parser unit tests (e.g. labels::deluxe) that need to exercise bytecode walkers against synthetic class fixtures without hand-rolling valid .class byte buffers.

Caller is responsible for: prepending a CpInfo::Empty at index 0 (the spec-reserved slot), and inserting a CpInfo::Empty after each Long/Double entry (the 2-slot quirk).

decode_modified_utf8

Decodes JVM "modified UTF-8" (JVMS §4.4.7). Practically identical to standard UTF-8 for the BMP-printable subset seen in label strings, but with two notable deviations:

  • U+0000 is encoded as the two-byte sequence 0xC0 0x80, not as 0x00.
  • Supplementary characters (U+10000..) are encoded as a UTF-16 surrogate pair, each surrogate emitted as 3-byte modified UTF-8.

For label data (mostly ASCII / Latin-1 / CJK in BMP), the simple implementation here covers everything we'll encounter. The 0xC0 0x80 → U+0000 case is tolerated explicitly; supplementary characters would need surrogate-pair stitching, but no label-relevant string uses them.

Reader::slice overflow test

Reader::slice takes an attacker-supplied length: a JVMS u4 attribute_length / code_length (§4.7, §4.7.3) or a u2 Utf8 length (§4.4.7). Adding it to pos without a wrap check panics on overflow in debug and, in release, wraps to a small end offset that slips past the bounds check and then panics inside the slice index. Both are panics escaping a parser whose whole input is untrusted disc bytes; the contract is an EOF error.