Skip to content

Commit f3267cb

Browse files
authored
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
1 parent 51406ff commit f3267cb

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

src/main/java/org/apache/bcel/classfile/ConstantPool.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,15 @@ public ConstantPool copy() {
230230
* @throws IOException if problem in writeShort or dump
231231
*/
232232
public void dump(final DataOutputStream file) throws IOException {
233-
file.writeShort(constantPool.length);
234-
for (int i = 1; i < constantPool.length; i++) {
233+
/*
234+
* Constants over the size of the constant pool shall not be written out.
235+
* This is a redundant measure as the ConstantPoolGen should have already
236+
* reported an error back in the situation.
237+
*/
238+
final int size = Math.min(constantPool.length, Const.MAX_CP_ENTRIES);
239+
240+
file.writeShort(size);
241+
for (int i = 1; i < size; i++) {
235242
if (constantPool[i] != null) {
236243
constantPool[i].dump(file);
237244
}

src/main/java/org/apache/bcel/generic/ConstantPoolGen.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public ConstantPoolGen() {
109109
public ConstantPoolGen(final Constant[] cs) {
110110
final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE);
111111

112-
size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64);
112+
size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64), Const.MAX_CP_ENTRIES + 1);
113113
constants = new Constant[size];
114114

115115
System.arraycopy(cs, 0, constants, 0, cs.length);
@@ -561,9 +561,18 @@ public int addUtf8(final String n) {
561561
* Resize internal array of constants.
562562
*/
563563
protected void adjustSize() {
564+
// 3 extra spaces are needed as some entries may take 3 slots
565+
if (index + 3 >= Const.MAX_CP_ENTRIES + 1) {
566+
throw new IllegalStateException("The number of constants " + (index + 3)
567+
+ " is over the size of the constant pool: "
568+
+ Const.MAX_CP_ENTRIES);
569+
}
570+
564571
if (index + 3 >= size) {
565572
final Constant[] cs = constants;
566573
size *= 2;
574+
// the constant array shall not exceed the size of the constant pool
575+
size = Math.min(size, Const.MAX_CP_ENTRIES + 1);
567576
constants = new Constant[size];
568577
System.arraycopy(cs, 0, constants, 0, index);
569578
}

src/test/java/org/apache/bcel/classfile/ConstantPoolTestCase.java

+15
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
package org.apache.bcel.classfile;
1919

2020
import static org.junit.jupiter.api.Assertions.assertNotNull;
21+
import static org.junit.jupiter.api.Assertions.assertThrows;
2122

2223
import org.apache.bcel.AbstractTestCase;
24+
import org.apache.bcel.Const;
2325
import org.apache.bcel.generic.ConstantPoolGen;
2426
import org.apache.bcel.generic.InstructionHandle;
2527
import org.apache.bcel.generic.InstructionList;
@@ -52,4 +54,17 @@ public void testConstantToString() throws ClassNotFoundException {
5254
}
5355
}
5456
}
57+
58+
@Test
59+
public void testTooManyConstants() throws ClassNotFoundException {
60+
final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME + ".data.SimpleClassWithDefaultConstructor");
61+
final ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
62+
63+
int i = cp.getSize();
64+
while (i < Const.MAX_CP_ENTRIES - 1) {
65+
cp.addLong(i);
66+
i = cp.getSize(); // i += 2
67+
}
68+
assertThrows(IllegalStateException.class, () -> cp.addLong(0));
69+
}
5570
}

0 commit comments

Comments
 (0)