This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git
The following commit(s) were added to refs/heads/master by this push:
new 68698bbd bound iinc increment to signed short (#526)
68698bbd is described below
commit 68698bbd87096b9c6836e2cc13501b5d990a3516
Author: Naveed Khan <[email protected]>
AuthorDate: Tue Jul 21 20:00:34 2026 +0000
bound iinc increment to signed short (#526)
`IINC.setIncrement` stored the increment without checking its range, but
`dump` writes the wide-form increment with `writeShort`. A value outside the
signed-short range was accepted and then truncated to a different value on
dump. Reject it in `setIncrement`, which the constructor routes through too.
---
src/main/java/org/apache/bcel/generic/IINC.java | 4 ++
.../java/org/apache/bcel/generic/IINCTest.java | 66 ++++++++++++++++++++++
2 files changed, 70 insertions(+)
diff --git a/src/main/java/org/apache/bcel/generic/IINC.java
b/src/main/java/org/apache/bcel/generic/IINC.java
index 19445dff..9b2c0d34 100644
--- a/src/main/java/org/apache/bcel/generic/IINC.java
+++ b/src/main/java/org/apache/bcel/generic/IINC.java
@@ -124,8 +124,12 @@ public class IINC extends LocalVariableInstruction {
* Sets increment factor.
*
* @param c The increment factor.
+ * @throws ClassGenException if the increment is out of bounds.
*/
public final void setIncrement(final int c) {
+ if (!isValidShort(c)) {
+ throw new ClassGenException("Illegal increment: " + c);
+ }
this.c = c;
setWide();
}
diff --git a/src/test/java/org/apache/bcel/generic/IINCTest.java
b/src/test/java/org/apache/bcel/generic/IINCTest.java
new file mode 100644
index 00000000..63e37f05
--- /dev/null
+++ b/src/test/java/org/apache/bcel/generic/IINCTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.bcel.generic;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.apache.bcel.util.ByteSequence;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests {@link IINC}.
+ */
+class IINCTest {
+
+ /**
+ * The increment of a wide {@code iinc} is a signed short, so a value
inside that range must round-trip through
+ * {@code dump}.
+ */
+ @Test
+ void testWideIncrementRoundTrips() throws Exception {
+ final IINC iinc = new IINC(0, 30000);
+ try (ByteSequence bytes = new ByteSequence(iinc.dumpToByteArray())) {
+ assertEquals(30000, ((IINC)
Instruction.readInstruction(bytes)).getIncrement());
+ }
+ }
+
+ /**
+ * {@code dump} emits the wide-form increment with {@code writeShort}, so
the constructor and {@link IINC#setIncrement}
+ * must reject an increment outside the signed-short range instead of
truncating it to a different value.
+ */
+ @Test
+ void testRejectsIncrementAboveShort() {
+ assertEquals(Short.MAX_VALUE, new IINC(0,
Short.MAX_VALUE).getIncrement());
+ assertThrows(ClassGenException.class, () -> new IINC(0,
Short.MAX_VALUE + 1));
+ }
+
+ @Test
+ void testRejectsIncrementBelowShort() {
+ assertEquals(Short.MIN_VALUE, new IINC(0,
Short.MIN_VALUE).getIncrement());
+ assertThrows(ClassGenException.class, () -> new IINC(0,
Short.MIN_VALUE - 1));
+ }
+
+ @Test
+ void testSetIncrementRejectsOutOfRange() {
+ final IINC iinc = new IINC(0, 1);
+ assertThrows(ClassGenException.class, () -> iinc.setIncrement(40000));
+ }
+}