Skip to content

classfile: decode CONSTANT_Utf8 as modified UTF-8 - #208

Merged
dlunch merged 1 commit into
dlunch:mainfrom
Jun025:classfile-modified-utf8-decode
Sep 28, 2026
Merged

dlunch merged 1 commit into
dlunch:mainfrom
Jun025:classfile-modified-utf8-decode

Conversation

@Jun025

@Jun025 Jun025 commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

CONSTANT_Utf8 entries are modified UTF-8 (JVMS §4.4.7), but parse_utf8 decodes them with String::from_utf8. Two encodings javac emits are rejected:

  • NUL is written as C0 80
  • a supplementary character is written as its UTF-16 surrogate pair, each half as a 3-byte sequence (ED A0..AF xx ED B0..BF xx)

Any class with "\0" or, for example, U+1F40D in a string constant fails to parse, and loading it throws ClassFormatError.

Repro: compile class A { String s = "MTR\0"; } with javac and parse the resulting class file.

Fix: decode_modified_utf8 keeps the str::from_utf8 fast path for input that is already valid UTF-8. Otherwise it decodes 1–4 byte sequences into UTF-16 units and pairs them with char::decode_utf16. So the change only widens what is accepted:

  • standard 4-byte UTF-8 still decodes, as it did before
  • a lone surrogate, which is legal in Java but cannot be stored in a Rust String, becomes U+FFFD
  • truncated sequences, stray continuation bytes and invalid lead bytes still fail

Tests: four unit tests in constant_pool.rs:

  • C0 80
  • a surrogate pair
  • ASCII and non-ASCII BMP text unchanged
  • edge cases of the wider decoder

With String::from_utf8 restored, three of the four fail. cargo test --workspace, cargo fmt --check and cargo clippy -p classfile --all-targets -D warnings pass.

🤖 Generated with Claude Code

CONSTANT_Utf8 is modified UTF-8 (JVMS 4.4.7): NUL is C0 80 and a
supplementary character is a surrogate pair of two 3-byte sequences.
String::from_utf8 rejects both, so a class with "\0" or e.g. U+1F40D
in any constant fails to parse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@dlunch dlunch left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dlunch dlunch left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@dlunch
dlunch enabled auto-merge (squash) September 28, 2026 07:11
@dlunch
dlunch merged commit 67eb81b into dlunch:main Sep 28, 2026
7 checks passed
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