diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-26 15:32:18 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-06-05 14:25:07 +0200 |
commit | a31f46421d7bf6f55dd9ac5876b8e2eacf7e0708 (patch) | |
tree | 24ffd7c5ae5e321c3994048fdd0fd9f68ae7457c /ext/pdo | |
parent | 528aa7932a839fc6319979c34aa372805d8dc41c (diff) | |
download | php-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.re | 3 | ||||
-rw-r--r-- | ext/pdo/pdo_stmt.c | 25 | ||||
-rw-r--r-- | ext/pdo/php_pdo_driver.h | 2 |
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; } |