summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--UPGRADING7
-rw-r--r--ext/pdo_sqlite/sqlite_driver.c9
-rw-r--r--ext/pdo_sqlite/tests/open_basedir.phpt31
-rw-r--r--ext/pdo_sqlite/tests/pdo_sqlite_filename_uri.phpt37
4 files changed, 84 insertions, 0 deletions
diff --git a/UPGRADING b/UPGRADING
index facdf30377..29701c3714 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -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