summaryrefslogtreecommitdiff
path: root/ext/pdo
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
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')
-rw-r--r--ext/pdo/pdo_sql_parser.re3
-rw-r--r--ext/pdo/pdo_stmt.c25
-rw-r--r--ext/pdo/php_pdo_driver.h2
3 files changed, 22 insertions, 8 deletions
diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re
index 5950cdc38e..b04e2fb928 100644
--- a/ext/pdo/pdo_sql_parser.re
+++ b/ext/pdo/pdo_sql_parser.re
@@ -269,7 +269,8 @@ safe:
default:
buf = zval_get_string(parameter);
- if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf),
+ if (EG(exception) ||
+ !stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf),
ZSTR_LEN(buf), &plc->quoted, &plc->qlen,
param_type)) {
/* bork */
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 92e594c76b..bd93ca3cb2 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -307,7 +307,9 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s
ZVAL_STRINGL(parameter, p, len);
efree(p);
} else {
- convert_to_string(parameter);
+ if (!try_convert_to_string(parameter)) {
+ return 0;
+ }
}
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE)) {
convert_to_long(parameter);
@@ -911,7 +913,9 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_
fetch_value(stmt, &val, i++, NULL);
if (Z_TYPE(val) != IS_NULL) {
- convert_to_string(&val);
+ if (!try_convert_to_string(&val)) {
+ return 0;
+ }
if ((cep = zend_lookup_class(Z_STR(val))) == NULL) {
stmt->fetch.cls.ce = ZEND_STANDARD_CLASS_DEF_PTR;
} else {
@@ -2180,7 +2184,9 @@ static zval *dbstmt_prop_write(zval *object, zval *member, zval *value, void **c
{
pdo_stmt_t *stmt = Z_PDO_STMT_P(object);
- convert_to_string(member);
+ if (!try_convert_to_string(member)) {
+ return value;
+ }
if (strcmp(Z_STRVAL_P(member), "queryString") == 0) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "property queryString is read only");
@@ -2194,7 +2200,9 @@ static void dbstmt_prop_delete(zval *object, zval *member, void **cache_slot)
{
pdo_stmt_t *stmt = Z_PDO_STMT_P(object);
- convert_to_string(member);
+ if (!try_convert_to_string(member)) {
+ return;
+ }
if (strcmp(Z_STRVAL_P(member), "queryString") == 0) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "property queryString is read only");
@@ -2459,7 +2467,10 @@ static zval *row_prop_read(zval *object, zval *member, int type, void **cache_sl
fetch_value(stmt, rv, lval, NULL);
}
} else {
- convert_to_string(member);
+ if (!try_convert_to_string(member)) {
+ return &EG(uninitialized_zval);
+ }
+
/* TODO: replace this with a hash of available column names to column
* numbers */
for (colno = 0; colno < stmt->column_count; colno++) {
@@ -2511,7 +2522,9 @@ static int row_prop_exists(zval *object, zval *member, int check_empty, void **c
return lval >=0 && lval < stmt->column_count;
}
} else {
- convert_to_string(member);
+ if (!try_convert_to_string(member)) {
+ return 0;
+ }
}
/* TODO: replace this with a hash of available column names to column
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index d17b168c2d..d057857fa6 100644
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -215,7 +215,7 @@ static inline zend_string *pdo_attr_strval(zval *options, enum pdo_attribute_typ
zval *v;
if (options && (v = zend_hash_index_find(Z_ARRVAL_P(options), option_name))) {
- return zval_get_string(v);
+ return zval_try_get_string(v);
}
return defval ? zend_string_copy(defval) : NULL;
}