Skip to content

Commit b15b7af

Browse files
committed
FIX
1 parent 8db72c0 commit b15b7af

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

dd-java-agent/appsec/src/main/java/com/datadog/appsec/gateway/AppSecRequestContext.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -646,9 +646,15 @@ public void close() {
646646
closeWafContext();
647647
}
648648
collectedCookies = null;
649-
requestHeaders.clear();
650-
responseHeaders.clear();
651-
persistentData.clear();
649+
if (requestHeaders != null) {
650+
requestHeaders.clear();
651+
}
652+
if (responseHeaders != null) {
653+
responseHeaders.clear();
654+
}
655+
if (persistentData != null) {
656+
persistentData.clear();
657+
}
652658
if (derivatives != null) {
653659
derivatives.clear();
654660
derivatives = null;

dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/gateway/AppSecRequestContextSpecification.groovy

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,44 @@ class AppSecRequestContextSpecification extends DDSpecification {
451451
assert context.isHttpClientRequestSampled(requestId) == sampled
452452
}
453453
}
454+
455+
void 'close is idempotent and can be called multiple times'() {
456+
given:
457+
def ctx = new AppSecRequestContext()
458+
ctx.addRequestHeader('test', 'value')
459+
ctx.addResponseHeader('content-type', 'text/plain')
460+
461+
when:
462+
ctx.close()
463+
ctx.close()
464+
ctx.close()
465+
466+
then:
467+
notThrown(Exception)
468+
}
469+
470+
void 'close handles null internal fields gracefully'() {
471+
given:
472+
def ctx = new AppSecRequestContext()
473+
474+
// Use reflection to simulate the scenario where fields might be null
475+
// (e.g., due to bytecode instrumentation or unusual initialization)
476+
def requestHeadersField = AppSecRequestContext.getDeclaredField('requestHeaders')
477+
requestHeadersField.setAccessible(true)
478+
requestHeadersField.set(ctx, null)
479+
480+
def responseHeadersField = AppSecRequestContext.getDeclaredField('responseHeaders')
481+
responseHeadersField.setAccessible(true)
482+
responseHeadersField.set(ctx, null)
483+
484+
def persistentDataField = AppSecRequestContext.getDeclaredField('persistentData')
485+
persistentDataField.setAccessible(true)
486+
persistentDataField.set(ctx, null)
487+
488+
when:
489+
ctx.close()
490+
491+
then:
492+
notThrown(Exception)
493+
}
454494
}

0 commit comments

Comments
 (0)