You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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?
Do you see similar signed vs. unsigned issues in other implementations of org.apache.bcel.generic.Instruction.initFromFile(ByteSequence, boolean)?
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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MULTIANEWARRAY.initFromFilereads thedimensionsoperand withbytes.readByte(), but per the JVM spec it is an unsigned byte (1-255), so a method whosemultianewarrayhasdimensions >= 128parses into theshortfield as a sign-extended negative (200 reads back as -56), and that value then flows intogetDimensions()andconsumeStack(), throwing offMethodGen.getMaxStack. found it by comparing againstUtility.codeToString, which already reads the same operand viareadUnsignedByte; this mirrors that.mvn; that'smvnon the command line by itself.