This is an automated email from the ASF dual-hosted git repository.

ggregory 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 f3267cbc BCEL-363 Enforce MAX_CP_ENTRIES in ConstantPoolGen and 
ConstantPool.dump (#147)
f3267cbc is described below

commit f3267cbcc900f80851d561bdd16b239d936947f5
Author: Richard Atkins <rjatkins...@gmail.com>
AuthorDate: Wed Sep 21 23:18:58 2022 +1000

    BCEL-363 Enforce MAX_CP_ENTRIES in ConstantPoolGen and ConstantPool.dump 
(#147)
    
    * BCEL-363 Enforce MAX_CP_ENTRIES in ConstantPoolGen and ConstantPool.dump
    
    * BCEL-363 Add test coverage for enforced size limit
    
    * BCEL-363 Throw IllegalStateException instead of RuntimeException
    
    * BCEL-363 Use final
---
 src/main/java/org/apache/bcel/classfile/ConstantPool.java | 11 +++++++++--
 .../java/org/apache/bcel/generic/ConstantPoolGen.java     | 11 ++++++++++-
 .../org/apache/bcel/classfile/ConstantPoolTestCase.java   | 15 +++++++++++++++
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/bcel/classfile/ConstantPool.java 
b/src/main/java/org/apache/bcel/classfile/ConstantPool.java
index 0a9ab79a..8e8fddf7 100644
--- a/src/main/java/org/apache/bcel/classfile/ConstantPool.java
+++ b/src/main/java/org/apache/bcel/classfile/ConstantPool.java
@@ -230,8 +230,15 @@ public class ConstantPool implements Cloneable, Node {
      * @throws IOException if problem in writeShort or dump
      */
     public void dump(final DataOutputStream file) throws IOException {
-        file.writeShort(constantPool.length);
-        for (int i = 1; i < constantPool.length; i++) {
+        /*
+         * Constants over the size of the constant pool shall not be written 
out.
+         * This is a redundant measure as the ConstantPoolGen should have 
already
+         * reported an error back in the situation.
+        */
+        final int size = Math.min(constantPool.length, Const.MAX_CP_ENTRIES);
+
+        file.writeShort(size);
+        for (int i = 1; i < size; i++) {
             if (constantPool[i] != null) {
                 constantPool[i].dump(file);
             }
diff --git a/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java 
b/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
index 3d91b416..d55f3218 100644
--- a/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
+++ b/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java
@@ -109,7 +109,7 @@ public class ConstantPoolGen {
     public ConstantPoolGen(final Constant[] cs) {
         final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE);
 
-        size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64);
+        size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64), 
Const.MAX_CP_ENTRIES + 1);
         constants = new Constant[size];
 
         System.arraycopy(cs, 0, constants, 0, cs.length);
@@ -561,9 +561,18 @@ public class ConstantPoolGen {
      * Resize internal array of constants.
      */
     protected void adjustSize() {
+        // 3 extra spaces are needed as some entries may take 3 slots
+        if (index + 3 >= Const.MAX_CP_ENTRIES + 1) {
+            throw new IllegalStateException("The number of constants " + 
(index + 3)
+                    + " is over the size of the constant pool: "
+                    + Const.MAX_CP_ENTRIES);
+        }
+
         if (index + 3 >= size) {
             final Constant[] cs = constants;
             size *= 2;
+            // the constant array shall not exceed the size of the constant 
pool
+            size = Math.min(size, Const.MAX_CP_ENTRIES + 1);
             constants = new Constant[size];
             System.arraycopy(cs, 0, constants, 0, index);
         }
diff --git a/src/test/java/org/apache/bcel/classfile/ConstantPoolTestCase.java 
b/src/test/java/org/apache/bcel/classfile/ConstantPoolTestCase.java
index fae5bcf7..5e479983 100644
--- a/src/test/java/org/apache/bcel/classfile/ConstantPoolTestCase.java
+++ b/src/test/java/org/apache/bcel/classfile/ConstantPoolTestCase.java
@@ -18,8 +18,10 @@
 package org.apache.bcel.classfile;
 
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import org.apache.bcel.AbstractTestCase;
+import org.apache.bcel.Const;
 import org.apache.bcel.generic.ConstantPoolGen;
 import org.apache.bcel.generic.InstructionHandle;
 import org.apache.bcel.generic.InstructionList;
@@ -52,4 +54,17 @@ public class ConstantPoolTestCase extends AbstractTestCase {
             }
         }
     }
+
+    @Test
+    public void testTooManyConstants() throws ClassNotFoundException {
+        final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME + 
".data.SimpleClassWithDefaultConstructor");
+        final ConstantPoolGen cp = new 
ConstantPoolGen(clazz.getConstantPool());
+
+        int i = cp.getSize();
+        while (i < Const.MAX_CP_ENTRIES - 1) {
+            cp.addLong(i);
+            i = cp.getSize(); // i += 2
+        }
+        assertThrows(IllegalStateException.class, () -> cp.addLong(0));
+    }
 }

Reply via email to