diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParser.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParser.java index 1cea5ffb864..798f1ffa005 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParser.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParser.java @@ -7,7 +7,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; -import net.bytebuddy.ClassFileVersion; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.jar.asm.AnnotationVisitor; import net.bytebuddy.jar.asm.ClassReader; @@ -34,17 +33,11 @@ public TypeDescription parse(Class loadedType) { TypeOutline typeOutline = new TypeOutline( - ClassFileVersion.ofThisVm().getMinorMajorVersion(), loadedType.getModifiers(), loadedType.getName(), null != superClass ? superClass.getName() : null, extractTypeNames(loadedType.getInterfaces())); - Class declaringClass = loadedType.getDeclaringClass(); - if (null != declaringClass) { - typeOutline.declaredBy(declaringClass.getName()); - } - for (Annotation a : loadedType.getDeclaredAnnotations()) { typeOutline.declare(annotationOutline(Type.getDescriptor(a.annotationType()))); } @@ -91,7 +84,6 @@ static final class OutlineTypeExtractor extends ClassVisitor { TypeOutline typeOutline; FieldOutline fieldOutline; MethodOutline methodOutline; - boolean selfContained = true; OutlineTypeExtractor() { super(OpenedClassReader.ASM_API); @@ -105,23 +97,7 @@ public void visit( String signature, String superName, String[] interfaces) { - typeOutline = new TypeOutline(version, access, name, superName, interfaces); - } - - @Override - public void visitOuterClass(String owner, String name, String descriptor) { - selfContained = false; - } - - @Override - public void visitInnerClass(String name, String outerName, String innerName, int access) { - if (typeOutline.getInternalName().equals(name)) { - if (null != outerName) { - typeOutline.declaredBy(outerName); - } else if (null == innerName && !selfContained) { - typeOutline.anonymousType(); - } - } + typeOutline = new TypeOutline(access, name, superName, interfaces); } @Override diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeFactory.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeFactory.java index 222ff7e3a91..ba9b29438af 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeFactory.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeFactory.java @@ -383,11 +383,6 @@ public TypeList.Generic getInterfaces() { return outline().getInterfaces(); } - @Override - public TypeDescription getDeclaringType() { - return outline().getDeclaringType(); - } - @Override public boolean isPublic() { return isPublicFilter.contains(name) || super.isPublic(); diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeOutline.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeOutline.java index de47e15a055..f49cad267a1 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeOutline.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeOutline.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; -import net.bytebuddy.ClassFileVersion; import net.bytebuddy.description.annotation.AnnotationDescription; import net.bytebuddy.description.annotation.AnnotationList; import net.bytebuddy.description.field.FieldDescription; @@ -27,21 +26,17 @@ final class TypeOutline extends WithName { private static final MethodList NO_METHODS = new MethodList.Empty<>(); - private final int classFileVersion; private final int modifiers; private final String superName; private final String[] interfaces; - private String declaringName; - private boolean anonymousType; private List declaredAnnotations; private final List declaredFields = new ArrayList<>(); private final List declaredMethods = new ArrayList<>(); - TypeOutline(int version, int access, String internalName, String superName, String[] interfaces) { + TypeOutline(int access, String internalName, String superName, String[] interfaces) { super(internalName.replace('/', '.')); - this.classFileVersion = version; this.modifiers = access & ALLOWED_TYPE_MODIFIERS; this.superName = superName; this.interfaces = interfaces; @@ -72,19 +67,6 @@ public TypeList.Generic getInterfaces() { return new TypeList.Generic.Explicit(outlines); } - @Override - public TypeDescription getDeclaringType() { - if (null != declaringName) { - return findType(declaringName.replace('/', '.')); - } - return null; - } - - @Override - public TypeDescription getEnclosingType() { - return getDeclaringType(); // equivalent for outline purposes - } - @Override public int getModifiers() { return modifiers; @@ -114,11 +96,6 @@ private boolean matchesMask(int mask) { return (this.getModifiers() & mask) == mask; } - @Override - public ClassFileVersion getClassFileVersion() { - return ClassFileVersion.ofMinorMajor(classFileVersion); - } - @Override public AnnotationList getDeclaredAnnotations() { return null == declaredAnnotations @@ -136,15 +113,6 @@ public MethodList getDeclaredMethods() { return declaredMethods.isEmpty() ? NO_METHODS : new MethodList.Explicit<>(declaredMethods); } - @Override - public boolean isAnonymousType() { - return anonymousType; - } - - void declaredBy(String declaringName) { - this.declaringName = declaringName; - } - void declare(AnnotationDescription annotation) { if (null != annotation) { if (null == declaredAnnotations) { @@ -165,8 +133,4 @@ void declare(MethodDescription.InDefinedShape method) { declaredMethods.add(method); } } - - void anonymousType() { - anonymousType = true; - } } diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParserTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParserTest.groovy index 9a74729b884..77f8345f72d 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParserTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParserTest.groovy @@ -5,7 +5,7 @@ import spock.lang.Specification class OutlineTypeParserTest extends Specification { - void 'test modifiers are correct and anonymous classes are detected'() { + void 'test modifiers are correct'() { setup: final parser = new OutlineTypeParser() final locator = ClassFileLocators.classFileLocator(Thread.currentThread().contextClassLoader) @@ -15,12 +15,13 @@ class OutlineTypeParserTest extends Specification { final outline = parser.parse(bytes) then: - outline.anonymousType == anonymous outline.interface == isinterface outline.abstract == isabstract outline.annotation == annotation outline.enum == isenum + // isAnonymousType is no longer supported in outlines for performance reasons + where: clazz | anonymous | isinterface | isabstract | annotation | isenum 'datadog.trace.agent.test.EnclosedClasses' | false | false | false | false | false diff --git a/dd-java-agent/instrumentation/iast-instrumenter/src/main/java/datadog/trace/instrumentation/iastinstrumenter/IastInstrumentation.java b/dd-java-agent/instrumentation/iast-instrumenter/src/main/java/datadog/trace/instrumentation/iastinstrumenter/IastInstrumentation.java index c77ebe90dbb..12174161bec 100644 --- a/dd-java-agent/instrumentation/iast-instrumenter/src/main/java/datadog/trace/instrumentation/iastinstrumenter/IastInstrumentation.java +++ b/dd-java-agent/instrumentation/iast-instrumenter/src/main/java/datadog/trace/instrumentation/iastinstrumenter/IastInstrumentation.java @@ -76,11 +76,30 @@ protected boolean doMatch(TypeDescription target) { } }; + // this deliberately only considers anonymous types following the Java naming convention + private static final ElementMatcher.Junction ANONYMOUS_TYPE_MATCHER = + new ElementMatcher.Junction.ForNonNullValues() { + @Override + protected boolean doMatch(TypeDescription target) { + String name = target.getName(); + // search the name in reverse until we find a $ or non-digit + for (int end = name.length() - 1, i = end; i > 0; i--) { + char c = name.charAt(i); + if (c == '$' && i < end) { + return true; // only seen digits so far, assume anonymous + } else if (c < '0' || c > '9') { + break; // non-digit character found, assume not anonymous + } + } + return false; + } + }; + static { if (Config.get().isIastAnonymousClassesEnabled()) { INSTANCE = TRIE_MATCHER; } else { - INSTANCE = TRIE_MATCHER.and(not(TypeDescription::isAnonymousType)); + INSTANCE = TRIE_MATCHER.and(not(ANONYMOUS_TYPE_MATCHER)); } } }