Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
### Changes

### version 3.33 on August 23, 2026

* API changes suggested by `@waydeshi` and `@lucianjohnhouse`

* GitHub PR #523

### version 3.32 on June 21, 2026

* API change suggested by Wayde Shi (GitHub: `@waydeshi`).

* Excludes javassist.tools.{reflect,rmi,web}. They are now included in ./examples/src/main.

* Disables javassist.runtime.Desc.useContextClassLoader
Expand Down
2 changes: 1 addition & 1 deletion build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<project name="javassist" default="jar" basedir=".">

<property name="dist-version" value="javassist-3.32.0-GA"/>
<property name="dist-version" value="javassist-3.33.0-GA"/>

<property environment="env"/>
<property name="target.jar" value="javassist.jar"/>
Expand Down
Binary file modified javassist.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.32.0-GA</version>
<version>3.33.0-GA</version>
<packaging>bundle</packaging>
<name>Javassist</name>
<description>
Expand Down
2 changes: 1 addition & 1 deletion src/main/javassist/CtClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public abstract class CtClass {
/**
* The version number of this release.
*/
public static final String version = "3.32.0-GA";
public static final String version = "3.33.0-GA";

private int linesCount = 0;

Expand Down
32 changes: 28 additions & 4 deletions src/main/javassist/bytecode/AttributeInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,37 @@ protected AttributeInfo(ConstPool cp, int n, DataInputStream in)
constPool = cp;
name = n;
int len = in.readInt();
info = allocateBytes(len);
if (len > 0)
in.readFully(info);
}

private static volatile int maxAttributeLength = 0x7FFFFFFD;

/**
* Sets the maximum length of an attribute.
* The default value is 0x7FFFFFFD.
* The value must be greater than or equal to 0xFFFF.
*
* @param n
* @since 3.33.0
*/
public static void setMaxAttributeLength(int n) {
if (n < 0xffff)
throw new IllegalArgumentException("invalid limit: " + n);
else
maxAttributeLength = n;
}

protected static byte[] allocateBytes(int len) throws IOException {
if (len < 0 || len > maxAttributeLength)
throw new IOException("Bad attribute length: " + len);

try {
info = new byte[len];
return new byte[len];
} catch (Throwable e) {
throw new IOException("Error reading attribute info for " + n + " with size " + len, e);
throw new IOException("fail to allocate a byte array: " + len, e);
}
if (len > 0)
in.readFully(info);
}

static AttributeInfo read(ConstPool cp, DataInputStream in)
Expand Down
3 changes: 3 additions & 0 deletions src/main/javassist/bytecode/CodeAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ private CodeAttribute(ConstPool cp, CodeAttribute src, Map<String,String> classn
maxLocals = in.readUnsignedShort();

int code_len = in.readInt();
if (code_len <= 0 || 0xffff < code_len) // JVM specification 4.7.3
throw new IOException("bad code attribute length: " + code_len);

info = new byte[code_len];
in.readFully(info);

Expand Down
2 changes: 1 addition & 1 deletion src/main/javassist/bytecode/RecordAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public RecordAttribute(ConstPool cp, int nameIndex, DataInputStream in) throws I
pos += 2;
int attrLength = ByteArray.read32bit(info, pos);
pos += 4;
byte[] attrInfo = new byte[attrLength];
byte[] attrInfo = allocateBytes(attrLength);
System.arraycopy(info, pos, attrInfo, 0, attrLength);
pos += attrLength;

Expand Down
50 changes: 50 additions & 0 deletions src/test/javassist/bytecode/BytecodeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,56 @@ public void testInvokeDynamicWithCopy() throws Exception {
assertEquals("hello", destObj.getClass().getMethod("getString").invoke(destObj));
}

public void testLargeAttributeInfo() throws Exception {
int attrLen = 0x7fffffff;
try {
new ClassFile(buildBrokenClassfile(attrLen));
fail("Attribute length " + attrLen + " should throw an exception");
}
catch (IOException e) {
assertEquals("Bad attribute length: " + attrLen, e.getMessage());
}

try {
AttributeInfo.setMaxAttributeLength(0xfffe);
}
catch (IllegalArgumentException e) {
assertTrue(e.getMessage().startsWith("invalid limit:"));
}

AttributeInfo.setMaxAttributeLength(0x7FFFFFFF);
try {
new ClassFile(buildBrokenClassfile(attrLen));
fail("Attribute length " + attrLen + " should throw an exception");
}
catch (IOException e) {
assertTrue(e.getMessage().startsWith("fail to allocate a byte array"));
}
}

static DataInputStream buildBrokenClassfile(int attrLen) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(0xCAFEBABE);
dos.writeShort(0);
dos.writeShort(52);
dos.writeShort(6);
dos.writeByte(1); dos.writeUTF("TestClass");
dos.writeByte(7); dos.writeShort(1);
dos.writeByte(1); dos.writeUTF("java/lang/Object");
dos.writeByte(7); dos.writeShort(3);
dos.writeByte(1); dos.writeUTF("EvilAttr");
dos.writeShort(0x0001);
dos.writeShort(2);
dos.writeShort(4);
dos.writeShort(0); dos.writeShort(0); dos.writeShort(0);
dos.writeShort(1);
dos.writeShort(5);
dos.writeInt(attrLen);
dos.flush();
return new DataInputStream(new ByteArrayInputStream(baos.toByteArray()));
}

public static Test suite() {
TestSuite suite = new TestSuite("Bytecode Tests");
suite.addTestSuite(BytecodeTest.class);
Expand Down