AjAttributeReadLimitsTest.java
/* *******************************************************************
* Copyright (c) 2026 Contributors
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* SPDX-License-Identifier: EPL-2.0
* ******************************************************************/
package org.aspectj.weaver;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.aspectj.weaver.AjAttribute.AdviceAttribute;
import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
import org.aspectj.weaver.patterns.Pointcut;
import junit.framework.TestCase;
/**
* Checks that a forged length in an Around advice attribute is reported as a malformed attribute rather than crashing.
*/
public class AjAttributeReadLimitsTest extends TestCase {
private static final String ADVICE = AdviceAttribute.AttributeName;
/** Ends with an int (length of the boolean array) followed by a short (length of the declared exceptions array), both zero. */
private static byte[] aroundAdvice() throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CompressingDataOutputStream out = new CompressingDataOutputStream(bos, null);
new AdviceAttribute(AdviceKind.Around, Pointcut.makeMatchesNothing(Pointcut.RESOLVED), 0, 0, 0, null, false,
new ResolvedMember[0], new boolean[0], UnresolvedType.NONE).write(out);
out.flush();
return bos.toByteArray();
}
private static AjAttribute read(byte[] bytes) {
return AjAttribute.read(new WeaverVersionInfo(), ADVICE, bytes, null, null, null);
}
private static void assertMalformed(byte[] bytes) {
try {
read(bytes);
fail("expected the attribute to be rejected");
} catch (BCException expected) {
assertTrue(expected.getMessage(), expected.getMessage().contains("malformed " + ADVICE));
}
}
public void testGenuineAroundAdviceStillReads() throws IOException {
assertTrue(read(aroundAdvice()) instanceof AdviceAttribute);
}
public void testHugeBooleanArrayLengthIsReportedAsMalformed() throws IOException {
byte[] bytes = aroundAdvice();
int at = bytes.length - 6;
assertEquals(0, bytes[at] | bytes[at + 1] | bytes[at + 2] | bytes[at + 3]);
bytes[at] = 0x7f;
bytes[at + 1] = bytes[at + 2] = bytes[at + 3] = (byte) 0xff;
assertMalformed(bytes);
}
public void testNegativeDeclaredExceptionsLengthIsReportedAsMalformed() throws IOException {
byte[] bytes = aroundAdvice();
bytes[bytes.length - 2] = bytes[bytes.length - 1] = (byte) 0xff;
assertMalformed(bytes);
}
}