Skip to content

Commit 5d1199f

Browse files
estringanaclaude
andcommitted
Fix CI failures in appsec integration tests
- Remove Laminas translated-literal route: uses Laminas translator syntax ({...}) without a configured translator service, causing RuntimeException for all requests and crashing the entire test suite - Fix inferSymfonyRouteParams: array_filter without callback removes '0' (falsy string) from URL segments, causing zero-valued path params to be treated as absent from the URL - Add DD_API_SECURITY_ENABLED guard in SymfonyIntegration: the normalized route tag is specific to API security schema sampling and must be omitted when DD_API_SECURITY_ENABLED=false - Fix WordPress cache key: routing_cache_get/set used only $matchedRule as key, so absent/present optional captures shared the same cache slot and the first result bled into subsequent requests with different URLs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5ed13f3 commit 5d1199f

5 files changed

Lines changed: 9 additions & 34 deletions

File tree

appsec/tests/integration/src/test/groovy/com/datadog/appsec/php/integration/Laminas33Tests.groovy

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class Laminas33Tests {
8181
endpoints.size() > 0
8282
})
8383

84-
assert endpoints.size() == 33
84+
assert endpoints.size() == 32
8585
assert endpoints.find { it.path == '/' && it.method == '*' && it.operationName == 'http.request' && it.resourceName == '* /' } != null
8686
assert endpoints.find {
8787
it.path == '/application[/:action]' && it.method == '*' && it.operationName == 'http.request' && it.resourceName == '* /application[/:action]'
@@ -148,10 +148,6 @@ class Laminas33Tests {
148148
it.path == '/normalized-wildcard/:param1/*' && it.method == '*' &&
149149
it.operationName == 'http.request' && it.resourceName == '* /normalized-wildcard/:param1/*'
150150
} != null
151-
assert endpoints.find {
152-
it.path == '/normalized/{translated_page}' && it.method == '*' &&
153-
it.operationName == 'http.request' && it.resourceName == '* /normalized/{translated_page}'
154-
} != null
155151
}
156152

157153
@Test
@@ -422,18 +418,4 @@ class Laminas33Tests {
422418
'/normalized-wildcard/{param1}/{param2}'
423419
}
424420

425-
@Test
426-
@Order(18)
427-
void 'translated literal remains a static route element'() {
428-
Trace trace = container.traceFromRequest(
429-
container.buildReq('/normalized/translated-page').GET().build(),
430-
ofString()) { HttpResponse<String> resp ->
431-
assert resp.statusCode() == 200
432-
}
433-
434-
assert trace.first().meta.'http.route' == '/normalized/{translated_page}'
435-
assert trace.first().meta.'_dd.appsec.normalized_route' ==
436-
'/normalized/translated-page'
437-
}
438-
439421
}

appsec/tests/integration/src/test/www/laminas33/module/Application/config/module.config.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,16 +247,6 @@
247247
],
248248
],
249249
],
250-
'normalized_translated_literal' => [
251-
'type' => Segment::class,
252-
'options' => [
253-
'route' => '/normalized/{translated_page}',
254-
'defaults' => [
255-
'controller' => DynamicPathController::class,
256-
'action' => 'index',
257-
],
258-
],
259-
],
260250
'scheme_http_gate' => [
261251
'type' => Scheme::class,
262252
'options' => [

src/DDTrace/Integrations/Symfony/SymfonyIntegration.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,9 @@ static function() {
456456

457457
if ($path !== null) {
458458
$rootSpan->meta[Tag::HTTP_ROUTE] = $path;
459-
if (function_exists('\datadog\appsec\is_enabled') && \datadog\appsec\is_enabled()) {
459+
$rawIni = ini_get('datadog.api_security_enabled');
460+
if (function_exists('\datadog\appsec\is_enabled') && \datadog\appsec\is_enabled()
461+
&& ($rawIni === false || filter_var($rawIni, FILTER_VALIDATE_BOOLEAN) !== false)) {
460462
// inferSymfonyRouteParams is lightweight (URL parsing only); compute it
461463
// first so the cache key encodes which optional params are present.
462464
// Without this, a route with optional params caches only the first

src/DDTrace/Integrations/WordPress/WordPressIntegrationLoader.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,11 +736,12 @@ function_exists('is_404') && is_404() === false) {
736736
$rootSpan->meta[Tag::HTTP_ROUTE] = $matchedRule;
737737
if (function_exists('\datadog\appsec\is_enabled') && \datadog\appsec\is_enabled()) {
738738
$urlPath = \property_exists($This, 'request') ? $This->request : null;
739-
$normalizedRoute = \DDTrace\routing_cache_get($matchedRule);
739+
$cacheKey = $matchedRule . '|' . ($urlPath ?? '');
740+
$normalizedRoute = \DDTrace\routing_cache_get($cacheKey);
740741
if ($normalizedRoute === false) {
741742
$normalizedRoute = \DDTrace\Util\RouteNormalizer::normalizeFromWordPress($matchedRule, $urlPath);
742743
if ($normalizedRoute !== null) {
743-
\DDTrace\routing_cache_set($matchedRule, $normalizedRoute);
744+
\DDTrace\routing_cache_set($cacheKey, $normalizedRoute);
744745
}
745746
}
746747
if ($normalizedRoute !== null && $normalizedRoute !== false) {

src/DDTrace/Util/RouteNormalizer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,8 +522,8 @@ public static function encodeParamName(string $name): string
522522
*/
523523
public static function inferSymfonyRouteParams(string $template, string $urlPath): array
524524
{
525-
$templateSegments = array_values(array_filter(explode('/', $template)));
526-
$urlSegments = array_values(array_filter(explode('/', $urlPath)));
525+
$templateSegments = array_values(array_filter(explode('/', $template), 'strlen'));
526+
$urlSegments = array_values(array_filter(explode('/', $urlPath), 'strlen'));
527527

528528
$matched = [];
529529
$urlIdx = 0;

0 commit comments

Comments
 (0)