Skip to content

Commit a36ff44

Browse files
authored
Merge branch 'master' into alejandro.gonzalez/APPSEC-61875-file-upload-content
2 parents 31aa005 + c99e05c commit a36ff44

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

buildSrc/call-site-instrumentation-plugin/src/main/java/datadog/trace/plugin/csi/impl/AdviceGeneratorImpl.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,6 @@ private static void writeStackOperations(final AdviceSpecification advice, final
266266
final List<Expression> parameterIndicesValues =
267267
advice
268268
.getArguments()
269-
.sorted()
270269
.map(argSpec -> intLiteral(argSpec.getIndex()))
271270
.collect(Collectors.toList());
272271
final VariableDeclarator parameterIndices =

buildSrc/call-site-instrumentation-plugin/src/test/java/datadog/trace/plugin/csi/impl/AdviceGeneratorTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,71 @@ void partialArgumentsWithBeforeAdvice() {
426426
});
427427
}
428428

429+
/**
430+
* Captures two of three arguments positionally. Before the fix, Stream.sorted() without a
431+
* comparator threw ClassCastException (ArgumentSpecification is not Comparable). The parameters
432+
* TreeMap is keyed by advice-parameter index, so the stream is already in the correct order —
433+
* sorted() must not be called. The reversed case verifies that parameterIndices follows the
434+
* advice signature order, not the pointcut index order.
435+
*/
436+
@CallSite(spi = CallSites.class)
437+
public static class MultiplePartialArgumentsBeforeAdvice {
438+
/** Captures args 0 and 1 in the same order as the pointcut. */
439+
@CallSite.Before(
440+
"java.lang.String java.lang.String.format(java.util.Locale, java.lang.String, java.lang.Object[])")
441+
public static void before(
442+
@CallSite.Argument(0) java.util.Locale locale, @CallSite.Argument(1) String format) {}
443+
444+
/**
445+
* Captures the same two args but with their advice positions reversed. parameterIndices must be
446+
* {1, 0} (advice order), not {0, 1} (pointcut index order).
447+
*/
448+
@CallSite.Before(
449+
"java.lang.String java.lang.String.format(java.util.Locale, java.lang.String, java.lang.Object[])")
450+
public static void beforeReversed(
451+
@CallSite.Argument(1) String format, @CallSite.Argument(0) java.util.Locale locale) {}
452+
}
453+
454+
@Test
455+
void multiplePartialArgumentsWithBeforeAdvice() {
456+
CallSiteSpecification spec =
457+
buildClassSpecification(MultiplePartialArgumentsBeforeAdvice.class);
458+
AdviceGenerator generator = buildAdviceGenerator(buildDir);
459+
460+
CallSiteResult result = generator.generate(spec);
461+
462+
assertNoErrors(result);
463+
CallSiteAssert asserter = assertCallSites(result.getFile());
464+
// In-order capture: {0, 1} matches both advice and pointcut order
465+
asserter.advices(
466+
0,
467+
advice -> {
468+
advice.pointcut(
469+
"java/lang/String",
470+
"format",
471+
"(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
472+
advice.statements(
473+
"int[] parameterIndices = new int[] { 0, 1 };",
474+
"handler.dupParameters(descriptor, parameterIndices, null);",
475+
"handler.advice(\"datadog/trace/plugin/csi/impl/AdviceGeneratorTest$MultiplePartialArgumentsBeforeAdvice\", \"before\", \"(Ljava/util/Locale;Ljava/lang/String;)V\");",
476+
"handler.method(opcode, owner, name, descriptor, isInterface);");
477+
});
478+
// Reversed capture: {1, 0} follows the advice signature, not the pointcut index order {0, 1}
479+
asserter.advices(
480+
1,
481+
advice -> {
482+
advice.pointcut(
483+
"java/lang/String",
484+
"format",
485+
"(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
486+
advice.statements(
487+
"int[] parameterIndices = new int[] { 1, 0 };",
488+
"handler.dupParameters(descriptor, parameterIndices, null);",
489+
"handler.advice(\"datadog/trace/plugin/csi/impl/AdviceGeneratorTest$MultiplePartialArgumentsBeforeAdvice\", \"beforeReversed\", \"(Ljava/lang/String;Ljava/util/Locale;)V\");",
490+
"handler.method(opcode, owner, name, descriptor, isInterface);");
491+
});
492+
}
493+
429494
@CallSite(spi = CallSites.class)
430495
public static class SuperTypeReturnAdvice {
431496
@CallSite.After("void java.lang.StringBuilder.<init>(java.lang.String)")

0 commit comments

Comments
 (0)