summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-02-26 15:32:18 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-06-05 14:25:07 +0200
commita31f46421d7bf6f55dd9ac5876b8e2eacf7e0708 (patch)
tree24ffd7c5ae5e321c3994048fdd0fd9f68ae7457c /ext/pdo_sqlite
parent528aa7932a839fc6319979c34aa372805d8dc41c (diff)
downloadphp-git-a31f46421d7bf6f55dd9ac5876b8e2eacf7e0708.tar.gz
Allow exceptions in __toString()
RFC: https://wiki.php.net/rfc/tostring_exceptions And convert some object to string conversion related recoverable fatal errors into Error exceptions. Improve exception safety of internal code performing string conversions.
Diffstat (limited to 'ext/pdo_sqlite')
-rw-r--r--ext/pdo_sqlite/sqlite_driver.c5
-rw-r--r--ext/pdo_sqlite/sqlite_statement.c8
-rw-r--r--ext/pdo_sqlite/tests/pdo_sqlite_tostring_exception.phpt45
3 files changed, 55 insertions, 3 deletions
diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c
index 02342e9fe4..9e86a82323 100644
--- a/ext/pdo_sqlite/sqlite_driver.c
+++ b/ext/pdo_sqlite/sqlite_driver.c
@@ -411,7 +411,10 @@ static int do_callback(struct pdo_sqlite_fci *fc, zval *cb,
break;
default:
- convert_to_string_ex(&retval);
+ if (!try_convert_to_string(&retval)) {
+ ret = FAILURE;
+ break;
+ }
sqlite3_result_text(context, Z_STRVAL(retval), Z_STRLEN(retval), SQLITE_TRANSIENT);
break;
}
diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c
index 186bf182b1..d8a68efb05 100644
--- a/ext/pdo_sqlite/sqlite_statement.c
+++ b/ext/pdo_sqlite/sqlite_statement.c
@@ -153,7 +153,9 @@ static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_d
pdo_sqlite_error_stmt(stmt);
return 0;
} else {
- convert_to_string(parameter);
+ if (!try_convert_to_string(parameter)) {
+ return 0;
+ }
}
if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
@@ -176,7 +178,9 @@ static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_d
return 1;
}
} else {
- convert_to_string(parameter);
+ if (!try_convert_to_string(parameter)) {
+ return 0;
+ }
if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
Z_STRVAL_P(parameter),
Z_STRLEN_P(parameter),
diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_tostring_exception.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_tostring_exception.phpt
new file mode 100644
index 0000000000..b1cd78eee7
--- /dev/null
+++ b/ext/pdo_sqlite/tests/pdo_sqlite_tostring_exception.phpt
@@ -0,0 +1,45 @@
+--TEST--
+__toString() exception during PDO Sqlite parameter binding
+--SKIPIF--
+<?php if (!extension_loaded('pdo_sqlite')) print 'skip not loaded'; ?>
+--FILE--
+<?php
+
+class throws {
+ function __toString() {
+ throw new Exception("Sorry");
+ }
+}
+
+$db = new PDO('sqlite::memory:');
+$db->exec('CREATE TABLE t(id int, v varchar(255))');
+
+$stmt = $db->prepare('INSERT INTO t VALUES(:i, :v)');
+$param1 = 1234;
+$stmt->bindValue('i', $param1);
+$param2 = "foo";
+$stmt->bindParam('v', $param2);
+
+$param2 = new throws;
+
+try {
+ $stmt->execute();
+} catch (Exception $e) {
+ echo "Exception thrown ...\n";
+}
+
+try {
+ $stmt->execute();
+} catch (Exception $e) {
+ echo "Exception thrown ...\n";
+}
+
+$query = $db->query("SELECT * FROM t");
+while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
+ print_r($row);
+}
+
+?>
+--EXPECT--
+Exception thrown ...
+Exception thrown ...