Skip to content

Commit 7522c49

Browse files
authored
ext/sqlite3: reject NUL bytes in SQLite3::escapeString() (#22774)
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 0a10f6d (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
1 parent 3dcdb98 commit 7522c49

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

ext/sqlite3/sqlite3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ PHP_METHOD(SQLite3, escapeString)
469469
zend_string *sql;
470470
char *ret;
471471

472-
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) {
472+
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "P", &sql)) {
473473
RETURN_THROWS();
474474
}
475475

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
SQLite3::escapeString() rejects strings with embedded NUL bytes
3+
--EXTENSIONS--
4+
sqlite3
5+
--FILE--
6+
<?php
7+
8+
$cases = [
9+
"\0",
10+
"a\0b",
11+
"secret\0x",
12+
"foo\0\0bar",
13+
];
14+
15+
foreach ($cases as $in) {
16+
try {
17+
SQLite3::escapeString($in);
18+
echo "FAIL: no exception for ", bin2hex($in), "\n";
19+
} catch (ValueError $e) {
20+
echo "ValueError: ", $e->getMessage(), "\n";
21+
}
22+
}
23+
24+
echo "ok: ", SQLite3::escapeString("ok"), "\n";
25+
echo "quote: ", SQLite3::escapeString("test''%"), "\n";
26+
echo "empty: ", var_export(SQLite3::escapeString(""), true), "\n";
27+
?>
28+
--EXPECT--
29+
ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes
30+
ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes
31+
ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes
32+
ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes
33+
ok: ok
34+
quote: test''''%
35+
empty: ''

0 commit comments

Comments
 (0)