diff options
-rw-r--r-- | UPGRADING | 7 | ||||
-rw-r--r-- | ext/pdo_sqlite/sqlite_driver.c | 9 | ||||
-rw-r--r-- | ext/pdo_sqlite/tests/open_basedir.phpt | 31 | ||||
-rw-r--r-- | ext/pdo_sqlite/tests/pdo_sqlite_filename_uri.phpt | 37 |
4 files changed, 84 insertions, 0 deletions
@@ -126,6 +126,13 @@ PHP 8.1 UPGRADE NOTES echo $h, "\n"; ``` +- PDO SQLite: + . SQLite's "file:" DSN syntax is now supported, which allows specifying + additional flags. This feature is not available if open_basedir is set. + Example: + + new PDO('sqlite:file:path/to/sqlite.db?mode=ro') + - Posix: . Added POSIX_RLIMIT_KQUEUES and POSIX_RLIMIT_NPTS. These rlimits are only available on FreeBSD. diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index a48c77f9e8..217833f6ad 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -731,6 +731,12 @@ static const struct pdo_dbh_methods sqlite_methods = { static char *make_filename_safe(const char *filename) { + if (*filename && strncasecmp(filename, "file:", 5) == 0) { + if (PG(open_basedir) && *PG(open_basedir)) { + return NULL; + } + return estrdup(filename); + } if (*filename && memcmp(filename, ":memory:", sizeof(":memory:"))) { char *fullpath = expand_filepath(filename, NULL); @@ -803,6 +809,9 @@ static int pdo_sqlite_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{ flags = pdo_attr_lval(driver_options, PDO_SQLITE_ATTR_OPEN_FLAGS, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + if (!(PG(open_basedir) && *PG(open_basedir))) { + flags |= SQLITE_OPEN_URI; + } i = sqlite3_open_v2(filename, &H->db, flags, NULL); efree(filename); diff --git a/ext/pdo_sqlite/tests/open_basedir.phpt b/ext/pdo_sqlite/tests/open_basedir.phpt new file mode 100644 index 0000000000..8041b47407 --- /dev/null +++ b/ext/pdo_sqlite/tests/open_basedir.phpt @@ -0,0 +1,31 @@ +--TEST-- +PDO SQLite open_basedir check +--SKIPIF-- +<?php if (!extension_loaded('pdo_sqlite')) print 'skip not loaded'; ?> +--INI-- +open_basedir=. +--FILE-- +<?php +chdir(__DIR__); + +try { + $db = new PDO('sqlite:../not_in_open_basedir.sqlite'); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + $db = new PDO('sqlite:file:../not_in_open_basedir.sqlite'); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} +try { + $db = new PDO('sqlite:file:../not_in_open_basedir.sqlite?mode=ro'); +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECT-- +open_basedir prohibits opening ../not_in_open_basedir.sqlite +open_basedir prohibits opening file:../not_in_open_basedir.sqlite +open_basedir prohibits opening file:../not_in_open_basedir.sqlite?mode=ro diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_filename_uri.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_filename_uri.phpt new file mode 100644 index 0000000000..7eec264ae2 --- /dev/null +++ b/ext/pdo_sqlite/tests/pdo_sqlite_filename_uri.phpt @@ -0,0 +1,37 @@ +--TEST-- +PDO_sqlite: Testing filename uri +--SKIPIF-- +<?php if (!extension_loaded('pdo_sqlite')) print 'skip not loaded'; ?> +--FILE-- +<?php + +// create with default read-write|create mode +$filename = "file:" . __DIR__ . DIRECTORY_SEPARATOR . "pdo_sqlite_filename_uri.db"; + +$db = new PDO('sqlite:' . $filename); + +var_dump($db->exec('CREATE TABLE test1 (id INT);')); + +// create with readonly mode +$filename = "file:" . __DIR__ . DIRECTORY_SEPARATOR . "pdo_sqlite_filename_uri.db?mode=ro"; + +$db = new PDO('sqlite:' . $filename); + +var_dump($db->exec('CREATE TABLE test2 (id INT);')); + +?> +--CLEAN-- +<?php +$filename = __DIR__ . DIRECTORY_SEPARATOR . "pdo_sqlite_filename_uri.db"; +if (file_exists($filename)) { + unlink($filename); +} +?> +--EXPECTF-- +int(0) + +Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in %s +Stack trace: +%s +#1 {main} + thrown in %s |