diff --git a/NEWS b/NEWS index c24f6d5c877..a3eeeafb3f7 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,12 @@ PHP NEWS . Fixed bug GH-9033 (Loading blacklist file can fail due to negative length). (cmb) +- PDO_SQLite: + . Fixed bug GH-9032 (SQLite3 authorizer crashes on NULL values). (cmb) + +- SQLite3: + . Fixed bug GH-9032 (SQLite3 authorizer crashes on NULL values). (cmb) + 04 Aug 2022, PHP 8.1.9 - CLI: diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index bdad23a581d..fc59066ce62 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -738,6 +738,9 @@ static const struct pdo_dbh_methods sqlite_methods = { static char *make_filename_safe(const char *filename) { + if (!filename) { + return NULL; + } if (*filename && strncasecmp(filename, "file:", 5) == 0) { if (PG(open_basedir) && *PG(open_basedir)) { return NULL; @@ -766,7 +769,7 @@ static int authorizer(void *autharg, int access_type, const char *arg3, const ch char *filename; switch (access_type) { case SQLITE_COPY: { - filename = make_filename_safe(arg4); + filename = make_filename_safe(arg4); if (!filename) { return SQLITE_DENY; } @@ -775,7 +778,7 @@ static int authorizer(void *autharg, int access_type, const char *arg3, const ch } case SQLITE_ATTACH: { - filename = make_filename_safe(arg3); + filename = make_filename_safe(arg3); if (!filename) { return SQLITE_DENY; } diff --git a/ext/pdo_sqlite/tests/gh9032.phpt b/ext/pdo_sqlite/tests/gh9032.phpt new file mode 100644 index 00000000000..332190484cf --- /dev/null +++ b/ext/pdo_sqlite/tests/gh9032.phpt @@ -0,0 +1,24 @@ +--TEST-- +SQLite3 authorizer crashes on NULL values +--EXTENSIONS-- +pdo_sqlite +--INI-- +open_basedir=. +--FILE-- + PDO::ERRMODE_EXCEPTION]); + +$db->exec('attach database \':memory:\' AS "db1"'); +var_dump($db->exec('create table db1.r (id int)')); + +try { +$st = $db->prepare('attach database :a AS "db2"'); +$st->execute([':a' => ':memory:']); +var_dump($db->exec('create table db2.r (id int)')); +} catch (PDOException $ex) { + echo $ex->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +int(0) +SQLSTATE[HY000]: General error: 23 not authorized diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 007eef7a744..b0924d5857e 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -2034,6 +2034,9 @@ static int php_sqlite3_authorizer(void *autharg, int action, const char *arg1, c /* Check open_basedir restrictions first */ if (PG(open_basedir) && *PG(open_basedir)) { if (action == SQLITE_ATTACH) { + if (!arg1) { + return SQLITE_DENY; + } if (memcmp(arg1, ":memory:", sizeof(":memory:")) && *arg1) { if (strncmp(arg1, "file:", 5) == 0) { /* starts with "file:" */ diff --git a/ext/sqlite3/tests/gh9032.phpt b/ext/sqlite3/tests/gh9032.phpt new file mode 100644 index 00000000000..069e0804064 --- /dev/null +++ b/ext/sqlite3/tests/gh9032.phpt @@ -0,0 +1,26 @@ +--TEST-- +SQLite3 authorizer crashes on NULL values +--EXTENSIONS-- +sqlite3 +--INI-- +open_basedir=. +--FILE-- +enableExceptions(true); + +$db->exec('attach database \':memory:\' AS "db1"'); +var_dump($db->exec('create table db1.r (id int)')); + +try { + $st = $db->prepare('attach database :a AS "db2"'); + $st->bindValue("a", ":memory:"); + $st->execute(); + var_dump($db->exec('create table db2.r (id int)')); +} catch (Exception $ex) { + echo $ex->getMessage(), PHP_EOL; +} +?> +--EXPECT-- +bool(true) +Unable to prepare statement: 23, not authorized