From ce248312d533ec4ef5a9ca0661c3bf9224acec13 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Sat, 29 Aug 2026 11:29:58 -0400 Subject: [PATCH] fix(playground): emit PHP escapes instead of raw control characters query-recorder.ts builds PHP source inside a JavaScript template literal. The whitespace list " \t\n\r\0\x0B" was written with single backslashes, so JavaScript resolved each sequence at evaluation time and the generated PHP carried actual tab, newline, carriage return, NUL and vertical tab bytes rather than PHP's own escape sequences. PHP parses either form to the same string, so behaviour is unchanged, but the raw NUL makes the generated source unpassable as a process argument: Node rejects argv entries containing null bytes. Any harness invoking 'php -r' with this code fails before PHP runs. That blocked three tests, which is why they sat unmaintained since June and were excluded when discovery landed in #2406: tests/rest-request-query-params.test.ts tests/wordpress-crud-contracts.test.ts tests/performance-observation-contracts.test.ts Escape the backslashes so PHP receives the escape text. Generated output now contains zero raw NUL or vertical tab characters, the three tests pass, and they return to discovery. Exclusions drop from 15 to 12. Verified unchanged: bench-command-step-behavior, agent-task-contracts, playground-fuzz-suite-public, nested-fuzz-suite-recipe-command, and php-fuzz-suite-runner-smoke all still pass. Full aggregate green at 341 commands in 7m59s. --- packages/runtime-playground/src/query-recorder.ts | 2 +- scripts/smoke-discovery.ts | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/runtime-playground/src/query-recorder.ts b/packages/runtime-playground/src/query-recorder.ts index aac1510e9..03286d03b 100644 --- a/packages/runtime-playground/src/query-recorder.ts +++ b/packages/runtime-playground/src/query-recorder.ts @@ -77,7 +77,7 @@ export function wordpressQueryRecorderPhp(): string { } function wp_codebox_query_recorder_operation( $fingerprint ) { - $operation = strtolower( strtok( trim( (string) $fingerprint ), " \t\n\r\0\x0B" ) ?: '' ); + $operation = strtolower( strtok( trim( (string) $fingerprint ), " \\t\\n\\r\\0\\x0B" ) ?: '' ); return in_array( $operation, array( 'select', 'insert', 'update', 'delete', 'replace', 'create', 'alter', 'drop', 'truncate' ), true ) ? $operation : 'other'; } diff --git a/scripts/smoke-discovery.ts b/scripts/smoke-discovery.ts index 5da09bde3..6d55f7d1f 100644 --- a/scripts/smoke-discovery.ts +++ b/scripts/smoke-discovery.ts @@ -37,9 +37,6 @@ export const DISCOVERY_EXCLUSIONS: readonly Exclusion[] = [ { file: "tests/browser-blueprint-ref-permission.test.ts", reason: "failing and unmaintained; pending triage" }, { file: "tests/command-diagnostics.test.ts", reason: "failing and unmaintained; pending triage" }, { file: "tests/docs-boundary-language.test.ts", reason: "failing and unmaintained; pending triage" }, - { file: "tests/performance-observation-contracts.test.ts", reason: "blocked on raw NUL in generated PHP; pending triage" }, - { file: "tests/rest-request-query-params.test.ts", reason: "blocked on raw NUL in generated PHP; pending triage" }, - { file: "tests/wordpress-crud-contracts.test.ts", reason: "blocked on raw NUL in generated PHP; pending triage" }, { file: "tests/temp-runtime-cleanup.test.ts", reason: "failing and unmaintained; pending triage" }, { file: "tests/wordpress-runtime-discovery-coverage-plan.test.ts", reason: "failing and unmaintained; pending triage" }, { file: "scripts/agent-runtime-task-ability-smoke.ts", reason: "failing and unmaintained; pending triage" },