From f3e167dac3390bcaadba1ed57bbfe68b67590329 Mon Sep 17 00:00:00 2001 From: jean-philippe bempel Date: Fri, 10 Oct 2025 17:58:53 +0200 Subject: [PATCH 1/2] Add support for Guava and FastUtil Consider guava and fastutil collections and maps as safe so they can be treated as regular collections and maps and use in expression and captured as well --- .../debugger/util/WellKnownClasses.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java index de4742a7512..1bd10eafba0 100644 --- a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java +++ b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java @@ -215,6 +215,14 @@ public static boolean isSafe(Collection collection) { // All Collection implementations from Google ProtoBuf are considered as safe return true; } + if (className.startsWith("com.google.common.collect.")) { + // All Collection implementations from Google Guava are considered as safe + return true; + } + if (className.startsWith("it.unimi.dsi.fastutil.")) { + // All Collection implementations from fastutil are considered as safe + return true; + } return false; } @@ -229,6 +237,14 @@ public static boolean isSafe(Map map) { // All Map implementations from Google ProtoBuf are considered as safe return true; } + if (className.startsWith("com.google.common.collect.")) { + // All Map implementations from Google Guava are considered as safe + return true; + } + if (className.startsWith("it.unimi.dsi.fastutil.")) { + // All Map implementations from fastutil are considered as safe + return true; + } return false; } From fd45ccd8a632205a90712da1d37e8cf87cf17f6a Mon Sep 17 00:00:00 2001 From: jean-philippe bempel Date: Tue, 14 Oct 2025 17:50:45 +0200 Subject: [PATCH 2/2] use a list for safe packages --- .../debugger/util/WellKnownClasses.java | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java index 1bd10eafba0..72aa94612a8 100644 --- a/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java +++ b/dd-java-agent/agent-debugger/debugger-bootstrap/src/main/java/datadog/trace/bootstrap/debugger/util/WellKnownClasses.java @@ -14,6 +14,7 @@ import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.OptionalDouble; @@ -187,6 +188,22 @@ public class WellKnownClasses { THROWABLE_SPECIAL_FIELDS.put("cause", ThrowableFields::cause); } + private static final List SAFE_COLLECTION_PACKAGES = + Arrays.asList( + "java.", // JDK base module + "com.google.protobuf.", // Google ProtoBuf + "com.google.common.collect.", // Google Guava + "it.unimi.dsi.fastutil." // fastutil + ); + + private static final List SAFE_MAP_PACKAGES = + Arrays.asList( + "java.", // JDK base module + "com.google.protobuf.", // Google ProtoBuf + "com.google.common.collect.", // Google Guava + "it.unimi.dsi.fastutil." // fastutil + ); + /** * @return true if type is a final class and toString implementation is well known and side effect * free @@ -207,21 +224,10 @@ public static boolean isToStringSafe(String concreteType) { /** @return true if collection implementation is safe to call (only in-memory) */ public static boolean isSafe(Collection collection) { String className = collection.getClass().getTypeName(); - if (className.startsWith("java.")) { - // All Collection implementations from JDK base module are considered as safe - return true; - } - if (className.startsWith("com.google.protobuf.")) { - // All Collection implementations from Google ProtoBuf are considered as safe - return true; - } - if (className.startsWith("com.google.common.collect.")) { - // All Collection implementations from Google Guava are considered as safe - return true; - } - if (className.startsWith("it.unimi.dsi.fastutil.")) { - // All Collection implementations from fastutil are considered as safe - return true; + for (String safePackage : SAFE_COLLECTION_PACKAGES) { + if (className.startsWith(safePackage)) { + return true; + } } return false; } @@ -229,21 +235,10 @@ public static boolean isSafe(Collection collection) { /** @return true if map implementation is safe to call (only in-memory) */ public static boolean isSafe(Map map) { String className = map.getClass().getTypeName(); - if (className.startsWith("java.")) { - // All Map implementations from JDK base module are considered as safe - return true; - } - if (className.startsWith("com.google.protobuf.")) { - // All Map implementations from Google ProtoBuf are considered as safe - return true; - } - if (className.startsWith("com.google.common.collect.")) { - // All Map implementations from Google Guava are considered as safe - return true; - } - if (className.startsWith("it.unimi.dsi.fastutil.")) { - // All Map implementations from fastutil are considered as safe - return true; + for (String safePackage : SAFE_MAP_PACKAGES) { + if (className.startsWith(safePackage)) { + return true; + } } return false; }