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