From 93221b29055a0f99dbf897f814e94289b1166aab Mon Sep 17 00:00:00 2001 From: Dillard Blom Date: Wed, 30 Sep 2026 17:45:09 +0200 Subject: [PATCH] Also unquote a function name followed by a comment SELECT "pg_read_file" /* x */ ('/etc/passwd') still passed: the check for a following parenthesis only skipped whitespace. Skip comments too. --- lib/Service/SqlGuard.php | 2 +- tests/Unit/Service/SqlGuardTest.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/Service/SqlGuard.php b/lib/Service/SqlGuard.php index e9e5990..271e6ee 100644 --- a/lib/Service/SqlGuard.php +++ b/lib/Service/SqlGuard.php @@ -124,7 +124,7 @@ class SqlGuard $end = self::literalEnd($sql, $i); if ($end !== null) { $literal = substr($sql, $i, $end - $i); - if (preg_match('/^"([A-Za-z_][A-Za-z0-9_$]*)"$/', $literal, $m) && preg_match('/\G\s*\(/', $sql, $unused, 0, $end)) { + if (preg_match('/^"([A-Za-z_][A-Za-z0-9_$]*)"$/', $literal, $m) && preg_match('/\G(?:\s|--[^\n]*(?:\n|$)|\/\*[\s\S]*?\*\/)*\(/', $sql, $unused, 0, $end)) { // A quoted function name ("setval"(...)) calls the same // function as the bare word, so check it as one $result .= $m[1]; diff --git a/tests/Unit/Service/SqlGuardTest.php b/tests/Unit/Service/SqlGuardTest.php index 38da012..d485f6c 100644 --- a/tests/Unit/Service/SqlGuardTest.php +++ b/tests/Unit/Service/SqlGuardTest.php @@ -26,6 +26,8 @@ class SqlGuardTest extends TestCase ["SELECT dblink_exec('host=x', 'DROP TABLE t')"], ["SELECT \"pg_read_file\"('/etc/passwd')"], ["SELECT pg_catalog.\"pg_read_file\"('/etc/passwd')"], + ["SELECT \"pg_read_file\" /* x */ ('/etc/passwd')"], + ["SELECT \"pg_read_file\"-- x\n('/etc/passwd')"], ["SELECT dblink_send_query('c', 'SELECT 1')"], ["SELECT * FROM dblink('host=x', 'SELECT 1') AS t(a int)"], ["SELECT * FROM t INTO OUTFILE '/tmp/x'"], @@ -127,6 +129,7 @@ class SqlGuardTest extends TestCase ["SELECT \"setval\"('seq', 1)"], ["SELECT pg_catalog.\"setval\"('seq', 1)"], ["SELECT pg_catalog.setval('seq', 1)"], + ["SELECT \"setval\" /* x */ ('seq', 1)"], ['MERGE INTO t USING s ON true WHEN MATCHED THEN DELETE'], ['VACUUM'], ['PRAGMA journal_mode = WAL'],