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));
+    }
+}

Reply via email to