From 216bac7f16f0a6b99a11a231bd85cbd2205febe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Vidal=20Dom=C3=ADnguez?= Date: Wed, 27 Nov 2024 14:38:08 +0100 Subject: [PATCH 1/2] Add support for stringbuilder subsequence --- .../java/lang/StringBuilderCallSite.java | 17 +++++++++++++++++ .../java/lang/StringBuilderCallSiteTest.groovy | 17 +++++++++-------- .../java/foo/bar/TestStringBuilderSuite.java | 7 +++++++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringBuilderCallSite.java b/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringBuilderCallSite.java index 80feb171f2a..4fa3ff9e017 100644 --- a/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringBuilderCallSite.java +++ b/dd-java-agent/instrumentation/java-lang/src/main/java/datadog/trace/instrumentation/java/lang/StringBuilderCallSite.java @@ -139,4 +139,21 @@ public static String afterSubstring( } return result; } + + @CallSite.After("java.lang.CharSequence java.lang.StringBuilder.subSequence(int, int)") + public static CharSequence afterSubSequence( + @CallSite.This final CharSequence self, + @CallSite.Argument final int beginIndex, + @CallSite.Argument final int endIndex, + @CallSite.Return final CharSequence result) { + final StringModule module = InstrumentationBridge.STRING; + if (module != null) { + try { + module.onStringSubSequence(self, beginIndex, endIndex, result); + } catch (final Throwable e) { + module.onUnexpectedException("afterSubSequence threw", e); + } + } + return result; + } } diff --git a/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy b/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy index a9680db938f..fcdee12bfe9 100644 --- a/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy @@ -210,13 +210,13 @@ class StringBuilderCallSiteTest extends AgentTestRunner { sbf('012345') | 1 | '12345' } - def 'test string builder substring with endIndex call site'() { + def 'test string builder/buffer #method with endIndex call site'() { setup: final iastModule = Mock(StringModule) InstrumentationBridge.registerIastModule(iastModule) when: - final result = TestStringBuilderSuite.substring(param, beginIndex, endIndex) + final result = suite."$method"(param, beginIndex, endIndex) then: result == expected @@ -224,17 +224,18 @@ class StringBuilderCallSiteTest extends AgentTestRunner { 0 * _ where: - param | beginIndex | endIndex | expected - sb('012345') | 1 | 5 | '1234' + suite | method | param | beginIndex | endIndex | expected + new TestStringBuilderSuite() | "substring" | sb('012345') | 1 | 5 | '1234' + new TestStringBufferSuite() | "substring" | sbf('012345') | 1 | 5 | '1234' } - def 'test string buffer substring with endIndex call site'() { + def 'test string builder/buffer #method with endIndex call site'() { setup: final iastModule = Mock(StringModule) InstrumentationBridge.registerIastModule(iastModule) when: - final result = TestStringBufferSuite.substring(param, beginIndex, endIndex) + final result = suite."$method"(param, beginIndex, endIndex) then: result == expected @@ -242,8 +243,8 @@ class StringBuilderCallSiteTest extends AgentTestRunner { 0 * _ where: - param | beginIndex | endIndex | expected - sbf('012345') | 1 | 5 | '1234' + suite | method | param | beginIndex | endIndex | expected + new TestStringBuilderSuite() | "subSequence" | sb('012345') | 1 | 5 | '1234' } private static class BrokenToString { diff --git a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java index 1edd8b1500b..b01f88d76cd 100644 --- a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java +++ b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java @@ -90,4 +90,11 @@ public static String substring(StringBuilder self, int beginIndex) { LOGGER.debug("After string builder substring {}", result); return result; } + + public static CharSequence subSequence(StringBuilder self, int beginIndex, int endIndex) { + LOGGER.debug("Before string builder subSequence {} from {} to {}", self, beginIndex, endIndex); + final CharSequence result = self.subSequence(beginIndex, endIndex); + LOGGER.debug("After string builder subSequence {}", result); + return result; + } } From f617c2812393ac2285567ae696955f423fda5b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Vidal=20Dom=C3=ADnguez?= Date: Wed, 27 Nov 2024 15:11:16 +0100 Subject: [PATCH 2/2] Refactor tests --- .../lang/StringBuilderCallSiteTest.groovy | 45 ++++++------------- .../bar/TestAbstractStringBuilderSuite.java | 6 +++ .../java/foo/bar/TestStringBufferSuite.java | 15 ++++++- .../java/foo/bar/TestStringBuilderSuite.java | 10 +++-- 4 files changed, 40 insertions(+), 36 deletions(-) diff --git a/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy b/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy index fcdee12bfe9..4d5de890f0a 100644 --- a/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy +++ b/dd-java-agent/instrumentation/java-lang/src/test/groovy/datadog/trace/instrumentation/java/lang/StringBuilderCallSiteTest.groovy @@ -174,13 +174,13 @@ class StringBuilderCallSiteTest extends AgentTestRunner { ex.stackTrace.find { it.className == StringBuilderCallSite.name } == null } - def 'test string builder substring call site'() { + def 'test string #type substring call site'() { setup: final iastModule = Mock(StringModule) InstrumentationBridge.registerIastModule(iastModule) when: - final result = TestStringBuilderSuite.substring(param, beginIndex) + final result = suite.substring(param, beginIndex) then: result == expected @@ -188,35 +188,18 @@ class StringBuilderCallSiteTest extends AgentTestRunner { 0 * _ where: - param | beginIndex | expected - sb('012345') | 1 | '12345' + type | suite | param | beginIndex | expected + "builder" | new TestStringBuilderSuite() | sb('012345') | 1 | '12345' + "buffer" | new TestStringBufferSuite() | sbf('012345') | 1 | '12345' } - def 'test string buffer substring call site'() { + def 'test string #type substring with endIndex call site'() { setup: final iastModule = Mock(StringModule) InstrumentationBridge.registerIastModule(iastModule) when: - final result = TestStringBufferSuite.substring(param, beginIndex) - - then: - result == expected - 1 * iastModule.onStringSubSequence(param, beginIndex, param.length(), expected) - 0 * _ - - where: - param | beginIndex | expected - sbf('012345') | 1 | '12345' - } - - def 'test string builder/buffer #method with endIndex call site'() { - setup: - final iastModule = Mock(StringModule) - InstrumentationBridge.registerIastModule(iastModule) - - when: - final result = suite."$method"(param, beginIndex, endIndex) + final result = suite.substring(param, beginIndex, endIndex) then: result == expected @@ -224,18 +207,18 @@ class StringBuilderCallSiteTest extends AgentTestRunner { 0 * _ where: - suite | method | param | beginIndex | endIndex | expected - new TestStringBuilderSuite() | "substring" | sb('012345') | 1 | 5 | '1234' - new TestStringBufferSuite() | "substring" | sbf('012345') | 1 | 5 | '1234' + type | suite | param | beginIndex | endIndex | expected + "builder" | new TestStringBuilderSuite() | sb('012345') | 1 | 5 | '1234' + "buffer" | new TestStringBufferSuite() | sbf('012345') | 1 | 5 | '1234' } - def 'test string builder/buffer #method with endIndex call site'() { + def 'test string #type subSequence with endIndex call site'() { setup: final iastModule = Mock(StringModule) InstrumentationBridge.registerIastModule(iastModule) when: - final result = suite."$method"(param, beginIndex, endIndex) + final result = suite.subSequence(param, beginIndex, endIndex) then: result == expected @@ -243,8 +226,8 @@ class StringBuilderCallSiteTest extends AgentTestRunner { 0 * _ where: - suite | method | param | beginIndex | endIndex | expected - new TestStringBuilderSuite() | "subSequence" | sb('012345') | 1 | 5 | '1234' + type | suite | param | beginIndex | endIndex | expected + "builder" | new TestStringBuilderSuite() | sb('012345') | 1 | 5 | '1234' } private static class BrokenToString { diff --git a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestAbstractStringBuilderSuite.java b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestAbstractStringBuilderSuite.java index 9fbf35809d4..9a3dbaab202 100644 --- a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestAbstractStringBuilderSuite.java +++ b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestAbstractStringBuilderSuite.java @@ -12,5 +12,11 @@ public interface TestAbstractStringBuilderSuite { void append(final E target, final Object param); + String substring(final E self, final int beginIndex, final int endIndex); + + String substring(final E self, final int beginIndex); + + CharSequence subSequence(final E self, final int beginIndex, final int endIndex); + String toString(final E target); } diff --git a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBufferSuite.java b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBufferSuite.java index 94b7f04e732..7f9f488870a 100644 --- a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBufferSuite.java +++ b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBufferSuite.java @@ -52,17 +52,28 @@ public String toString(final StringBuffer buffer) { return result; } - public static String substring(StringBuffer self, int beginIndex, int endIndex) { + @Override + public String substring(final StringBuffer self, final int beginIndex, final int endIndex) { LOGGER.debug("Before string buffer substring {} from {} to {}", self, beginIndex, endIndex); final String result = self.substring(beginIndex, endIndex); LOGGER.debug("After string buffer substring {}", result); return result; } - public static String substring(StringBuffer self, int beginIndex) { + @Override + public String substring(final StringBuffer self, final int beginIndex) { LOGGER.debug("Before string buffer substring {} from {}", self, beginIndex); final String result = self.substring(beginIndex); LOGGER.debug("After string buffer substring {}", result); return result; } + + @Override + public CharSequence subSequence( + final StringBuffer self, final int beginIndex, final int endIndex) { + LOGGER.debug("Before string builder subSequence {} from {} to {}", self, beginIndex, endIndex); + final CharSequence result = self.subSequence(beginIndex, endIndex); + LOGGER.debug("After string builder subSequence {}", result); + return result; + } } diff --git a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java index b01f88d76cd..a613773a3a4 100644 --- a/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java +++ b/dd-java-agent/instrumentation/java-lang/src/test/java/foo/bar/TestStringBuilderSuite.java @@ -77,21 +77,25 @@ public String plus(final Object... items) { return result; } - public static String substring(StringBuilder self, int beginIndex, int endIndex) { + @Override + public String substring(final StringBuilder self, final int beginIndex, final int endIndex) { LOGGER.debug("Before string builder substring {} from {} to {}", self, beginIndex, endIndex); final String result = self.substring(beginIndex, endIndex); LOGGER.debug("After string builder substring {}", result); return result; } - public static String substring(StringBuilder self, int beginIndex) { + @Override + public String substring(final StringBuilder self, final int beginIndex) { LOGGER.debug("Before string builder substring {} from {}", self, beginIndex); final String result = self.substring(beginIndex); LOGGER.debug("After string builder substring {}", result); return result; } - public static CharSequence subSequence(StringBuilder self, int beginIndex, int endIndex) { + @Override + public CharSequence subSequence( + final StringBuilder self, final int beginIndex, final int endIndex) { LOGGER.debug("Before string builder subSequence {} from {} to {}", self, beginIndex, endIndex); final CharSequence result = self.subSequence(beginIndex, endIndex); LOGGER.debug("After string builder subSequence {}", result);