Skip to content

Commit bece336

Browse files
committed
fix(appsec): guard Jetty 8 getParts against repeated calls; disable filename tests in async suite
1. Add _multiPartInputStream == null guard to GetFilenamesAdvice.before() so that repeated getParts() calls on the same request (which Jetty caches) do not re-fire requestFilesFilenames/requestBodyProcessed WAF callbacks. The field is null before the first multipart parse and non-null on all subsequent cached calls, matching the pattern used in the 9.4/11.0 advice (_multiParts guard). 2. JettyAsyncHandlerTest already disabled testBodyFilenames() but neglected to disable testBodyFilenamesCalledOnce() and testBodyFilenamesCalledOnceCombined(), which are now enabled in the Jetty11Test parent. Override both to false in the async handler suite to prevent spurious test failures.
1 parent 1508fef commit bece336

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

dd-java-agent/instrumentation/jetty/jetty-appsec/jetty-appsec-8.1.3/src/main/java/datadog/trace/instrumentation/jetty8/RequestGetPartsInstrumentation.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.function.BiFunction;
2828
import javax.servlet.http.Part;
2929
import net.bytebuddy.asm.Advice;
30+
import net.bytebuddy.implementation.bytecode.assign.Assigner;
3031
import net.bytebuddy.jar.asm.ClassReader;
3132
import net.bytebuddy.jar.asm.ClassVisitor;
3233
import net.bytebuddy.jar.asm.FieldVisitor;
@@ -129,8 +130,12 @@ public void visitMethodInsn(
129130
@RequiresRequestContext(RequestContextSlot.APPSEC)
130131
public static class GetFilenamesAdvice {
131132
@Advice.OnMethodEnter(suppress = Throwable.class)
132-
static boolean before() {
133-
return CallDepthThreadLocalMap.incrementCallDepth(Collection.class) == 0;
133+
static boolean before(
134+
@Advice.FieldValue(value = "_multiPartInputStream", typing = Assigner.Typing.DYNAMIC)
135+
final Object multiPartInputStream) {
136+
final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(Collection.class);
137+
// _multiPartInputStream is null before the first parse; non-null on cached repeat calls.
138+
return callDepth == 0 && multiPartInputStream == null;
134139
}
135140

136141
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)

dd-java-agent/instrumentation/jetty/jetty-server/jetty-server-11.0/src/test/groovy/JettyAsyncHandlerTest.groovy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ class JettyAsyncHandlerTest extends Jetty11Test implements TestingGenericHttpNam
3030
false
3131
}
3232

33+
@Override
34+
boolean testBodyFilenamesCalledOnce() {
35+
false
36+
}
37+
38+
@Override
39+
boolean testBodyFilenamesCalledOnceCombined() {
40+
false
41+
}
42+
3343
static class ContinuationTestHandler implements Handler {
3444
@Delegate
3545
private final Handler delegate

0 commit comments

Comments
 (0)