AtAjAttributesParseFailureTest.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.bcel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
import org.aspectj.apache.bcel.classfile.annotation.NameValuePair;
import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue;
import org.aspectj.apache.bcel.generic.ClassGen;
import org.aspectj.apache.bcel.generic.ObjectType;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageHandler;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.UnresolvedType;
import junit.framework.TestCase;
public class AtAjAttributesParseFailureTest extends TestCase {
/**
* Reads a class carrying @DeclarePrecedence(value) and returns the errors
* reported.
*/
private IMessage[] errorsReadingPrecedence(String value) {
ClassGen cg = new ClassGen("crafted.Probe", "java.lang.Object", "Probe.java", Constants.ACC_PUBLIC, null);
ConstantPool cp = cg.getConstantPool();
List<NameValuePair> pairs = new ArrayList<>();
pairs.add(new NameValuePair("value", new SimpleElementValue(ElementValue.STRING, cp, value), cp));
cg.addAnnotation(
new AnnotationGen(new ObjectType("org.aspectj.lang.annotation.DeclarePrecedence"), pairs, true, cp));
MessageHandler handler = new MessageHandler();
BcelWorld world = new BcelWorld();
world.setMessageHandler(handler);
ReferenceType type = (ReferenceType) world.resolve(UnresolvedType.forName(getClass().getName()));
AtAjAttributes.readAj5ClassAttributes(null, cg.getJavaClass(), type, type.getSourceContext(), handler, false);
return handler.getErrors();
}
public void testValidPrecedenceIsAccepted() {
assertEquals(0, errorsReadingPrecedence("*").length);
}
public void testInvalidPrecedenceIsReportedNotThrown() {
IMessage[] errors = errorsReadingPrecedence("(");
assertEquals(1, errors.length);
assertTrue(errors[0].getMessage(), errors[0].getMessage().contains("Invalid @DeclarePrecedence"));
}
public void testDeeplyNestedPrecedenceIsReportedNotThrown() {
char[] bangs = new char[20000];
Arrays.fill(bangs, '!');
IMessage[] errors = errorsReadingPrecedence(new String(bangs) + "*");
assertEquals(1, errors.length);
assertTrue(errors[0].getMessage(), errors[0].getMessage().contains("Invalid @DeclarePrecedence"));
assertTrue("message must not echo the whole pattern", errors[0].getMessage().length() < 1000);
}
}