From f3267cbcc900f80851d561bdd16b239d936947f5 Mon Sep 17 00:00:00 2001
From: Richard Atkins <rjatkins359@gmail.com>
Date: Wed, 21 Sep 2022 23:18:58 +1000
Subject: [PATCH] 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
---
 .../org/apache/bcel/classfile/ConstantPool.java   | 11 +++++++++--
 .../org/apache/bcel/generic/ConstantPoolGen.java  | 11 ++++++++++-
 .../bcel/classfile/ConstantPoolTestCase.java      | 15 +++++++++++++++
 3 files changed, 34 insertions(+), 3 deletions(-)

Index: bcel-5.1/src/java/org/apache/bcel/classfile/ConstantPool.java
===================================================================
--- bcel-5.1.orig/src/java/org/apache/bcel/classfile/ConstantPool.java
+++ bcel-5.1/src/java/org/apache/bcel/classfile/ConstantPool.java
@@ -223,11 +223,19 @@ public class ConstantPool implements Clo
    */
   public void dump(DataOutputStream file) throws IOException
   {
-    file.writeShort(constant_pool_count);
+    /*
+     * 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(constant_pool.length, Constants.MAX_CP_ENTRIES);
 
-    for(int i=1; i < constant_pool_count; i++)
-      if(constant_pool[i] != null)
-	constant_pool[i].dump(file);
+    file.writeShort(size);
+    for (int i = 1; i < size; i++) {
+      if (constant_pool[i] != null) {
+        constant_pool[i].dump(file);
+      }
+    }
   }
 
   /**
Index: bcel-5.1/src/java/org/apache/bcel/generic/ConstantPoolGen.java
===================================================================
--- bcel-5.1.orig/src/java/org/apache/bcel/generic/ConstantPoolGen.java
+++ bcel-5.1/src/java/org/apache/bcel/generic/ConstantPoolGen.java
@@ -73,15 +73,17 @@ import java.util.HashMap;
  * @see Constant
  */
 public class ConstantPoolGen implements java.io.Serializable {
-  protected int        size      = 1024; // Inital size, sufficient in most cases
-  protected Constant[] constants = new Constant[size];
-  protected int        index     = 1; // First entry (0) used by JVM
 
+  private static final int DEFAULT_BUFFER_SIZE = 256;
   private static final String METHODREF_DELIM  = ":";
   private static final String IMETHODREF_DELIM = "#";
   private static final String FIELDREF_DELIM   = "&";
   private static final String NAT_DELIM        = "%";
 
+  protected int        size      = DEFAULT_BUFFER_SIZE;
+  protected Constant[] constants = new Constant[size];
+  protected int        index     = 1; // First entry (0) used by JVM
+
   private static class Index implements java.io.Serializable {
     int index;
     Index(int i) { index = i; }
@@ -93,6 +95,8 @@ public class ConstantPoolGen implements
    * @param c array of given constants, new ones will be appended
    */
   public ConstantPoolGen(Constant[] cs) {
+
+    size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64), Constants.MAX_CP_ENTRIES + 1);
     if(cs.length > size) {
       size      = cs.length;
       constants = new Constant[size];
@@ -167,9 +171,17 @@ public class ConstantPoolGen implements
   /** Resize internal array of constants.
    */
   protected void adjustSize() {
+    // 3 extra spaces are needed as some entries may take 3 slots
+    if (index + 3 >= Constants.MAX_CP_ENTRIES + 1) {
+      throw new IllegalStateException("The number of constants " + (index + 3)
+              + " is over the size of the constant pool: "
+              + Constants.MAX_CP_ENTRIES);
+    }
+
     if(index + 3 >= size) {
       Constant[] cs = constants;
-
+      // the constant array shall not exceed the size of the constant pool
+      size = Math.min(size, Constants.MAX_CP_ENTRIES + 1);
       size      *= 2;
       constants  = new Constant[size];
       System.arraycopy(cs, 0, constants, 0, index);
