From d3f88b39601b13cad04cb1618ad7d598ff0f1241 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Thu, 16 Jul 2026 13:01:33 -0400 Subject: [PATCH] ext/sqlite3: reject NUL bytes in SQLite3::escapeString() escapeString() used sqlite3_mprintf("%q"), which stops at the first C NUL. PHP strings are length-aware and may embed NULs, so values such as "a\0b" were silently truncated to "a" when interpolated into SQL. Prepared binds pass an explicit length and are unaffected. ext/pdo_sqlite rejected the same inputs for PDO::quote in 0a10f6db268 (GH-13952), on 8.5 and up. That check consults the connection's error mode; escapeString() is static and has no connection, so it throws instead. Closes GH-22774 --- ext/sqlite3/sqlite3.c | 2 +- .../tests/gh_sqlite3_escapestring_nul.phpt | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 67ff850cadd0..b81a0677a6c2 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -469,7 +469,7 @@ PHP_METHOD(SQLite3, escapeString) zend_string *sql; char *ret; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) { + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "P", &sql)) { RETURN_THROWS(); } diff --git a/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt b/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt new file mode 100644 index 000000000000..49d66a1accf5 --- /dev/null +++ b/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt @@ -0,0 +1,35 @@ +--TEST-- +SQLite3::escapeString() rejects strings with embedded NUL bytes +--EXTENSIONS-- +sqlite3 +--FILE-- +getMessage(), "\n"; + } +} + +echo "ok: ", SQLite3::escapeString("ok"), "\n"; +echo "quote: ", SQLite3::escapeString("test''%"), "\n"; +echo "empty: ", var_export(SQLite3::escapeString(""), true), "\n"; +?> +--EXPECT-- +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ok: ok +quote: test''''% +empty: ''