Skip to content

Read multianewarray dimensions as unsigned byte#504

Merged
garydgregory merged 1 commit into
apache:masterfrom
rootvector2:multianewarray-unsigned-dimensions
Jun 17, 2026
Merged

Read multianewarray dimensions as unsigned byte#504
garydgregory merged 1 commit into
apache:masterfrom
rootvector2:multianewarray-unsigned-dimensions

Conversation

@rootvector2

Copy link
Copy Markdown
Contributor

MULTIANEWARRAY.initFromFile reads the dimensions operand with bytes.readByte(), but per the JVM spec it is an unsigned byte (1-255), so a method whose multianewarray has dimensions >= 128 parses into the short field as a sign-extended negative (200 reads back as -56), and that value then flows into getDimensions() and consumeStack(), throwing off MethodGen.getMaxStack. found it by comparing against Utility.codeToString, which already reads the same operand via readUnsignedByte; this mirrors that.

  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance if you use Artificial Intelligence (AI).
  • I used AI to create any part of, or all of, this pull request. Which AI tool was used to create this pull request, and to what extent did it contribute?
  • Run a successful build using the default Maven goal with mvn; that's mvn on the command line by itself.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.

@garydgregory garydgregory changed the title read multianewarray dimensions as unsigned byte Read multianewarray dimensions as unsigned byte Jun 17, 2026
@garydgregory

Copy link
Copy Markdown
Member

Hello @rootvector2

Thank you for your PR. LGTM.

  1. The JVM spec here states "The dimensions operand of each multianewarray instruction must not be zero." Would you please check the byte code verifier for this constraint?
  2. Do you see similar signed vs. unsigned issues in other implementations of org.apache.bcel.generic.Instruction.initFromFile(ByteSequence, boolean)?

Thank you!

@garydgregory garydgregory merged commit 68628e6 into apache:master Jun 17, 2026
19 checks passed
@rootvector2

Copy link
Copy Markdown
Contributor Author

both already in good shape:

  1. the verifier enforces it. Pass3aVerifier.visitMULTIANEWARRAY rejects getDimensions() < 1 with "Number of dimensions to create must be greater than zero." worth noting that before this fix that check misfired the other way: a valid dimensions >= 128 read back negative and tripped the < 1 branch, flagging legit bytecode. so the unsigned read also keeps that constraint honest. no extra code needed there.

  2. went through the other initFromFile overrides. the only other unsigned-byte operand still read with readByte() is NEWARRAY (atype), but the valid atype codes are 4-11 so it never sign-extends in practice, and it's stored in a byte field anyway. the remaining readByte() calls (BIPUSH operand, IINC increment) read operands the spec defines as signed, so those are correct. multianewarray was the odd one out: an unsigned operand widened into a larger signed field.

@garydgregory

Copy link
Copy Markdown
Member

@rootvector2

Thanks for checking.

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