summaryrefslogtreecommitdiff
path: root/ext/oci8/oci8_statement.c
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/oci8/oci8_statement.c
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/oci8/oci8_statement.c')
-rw-r--r--ext/oci8/oci8_statement.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c
index 4face29e4a..91f6223373 100644
--- a/ext/oci8/oci8_statement.c
+++ b/ext/oci8/oci8_statement.c
@@ -1189,7 +1189,9 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
return 1;
}
if (Z_TYPE_P(param) != IS_NULL) {
- convert_to_string(param);
+ if (!try_convert_to_string(param)) {
+ return 1;
+ }
}
if ((maxlength == -1) || (maxlength == 0)) {
if (type == SQLT_LNG) {
@@ -1390,8 +1392,10 @@ sb4 php_oci_bind_in_callback(
*alenp = -1;
*indpp = (dvoid *)&phpbind->indicator;
} else if ((phpbind->descriptor == 0) && (phpbind->statement == 0)) {
- /* "normal string bind */
- convert_to_string(val);
+ /* "normal" string bind */
+ if (!try_convert_to_string(val)) {
+ return OCI_ERROR;
+ }
*bufpp = Z_STRVAL_P(val);
*alenp = (ub4) Z_STRLEN_P(val);
@@ -1483,7 +1487,6 @@ sb4 php_oci_bind_out_callback(
*indpp = &phpbind->indicator;
retval = OCI_CONTINUE;
} else {
- convert_to_string(val);
zval_ptr_dtor(val);
{
@@ -1741,7 +1744,9 @@ php_oci_bind *php_oci_bind_array_helper_string(zval *var, zend_long max_table_le
if (maxlength == -1) {
zend_hash_internal_pointer_reset(hash);
while ((entry = zend_hash_get_current_data(hash)) != NULL) {
- convert_to_string_ex(entry);
+ if (!try_convert_to_string(entry)) {
+ return NULL;
+ }
if (maxlength == -1 || Z_STRLEN_P(entry) > (size_t) maxlength) {
maxlength = Z_STRLEN_P(entry) + 1;
@@ -1767,7 +1772,14 @@ php_oci_bind *php_oci_bind_array_helper_string(zval *var, zend_long max_table_le
for (i = 0; i < bind->array.current_length; i++) {
if ((entry = zend_hash_get_current_data(hash)) != NULL) {
- convert_to_string_ex(entry);
+ if (!try_convert_to_string(entry)) {
+ efree(bind->array.elements);
+ efree(bind->array.element_lengths);
+ efree(bind->array.indicators);
+ efree(bind);
+ return NULL;
+ }
+
bind->array.element_lengths[i] = (ub2) Z_STRLEN_P(entry);
if (Z_STRLEN_P(entry) == 0) {
bind->array.indicators[i] = -1;
@@ -1782,8 +1794,14 @@ php_oci_bind *php_oci_bind_array_helper_string(zval *var, zend_long max_table_le
for (i = 0; i < max_table_length; i++) {
if ((i < bind->array.current_length) && (entry = zend_hash_get_current_data(hash)) != NULL) {
int element_length;
+ if (!try_convert_to_string(entry)) {
+ efree(bind->array.elements);
+ efree(bind->array.element_lengths);
+ efree(bind->array.indicators);
+ efree(bind);
+ return NULL;
+ }
- convert_to_string_ex(entry);
element_length = ((size_t) maxlength > Z_STRLEN_P(entry)) ? (int) Z_STRLEN_P(entry) : (int) maxlength;
memcpy((text *)bind->array.elements + i*maxlength, Z_STRVAL_P(entry), element_length);
@@ -1912,9 +1930,16 @@ php_oci_bind *php_oci_bind_array_helper_date(zval *var, zend_long max_table_leng
bind->array.element_lengths[i] = sizeof(OCIDate);
}
if ((i < bind->array.current_length) && (entry = zend_hash_get_current_data(hash)) != NULL) {
+ zend_string *entry_str = zval_get_string(entry);
+ if (EG(exception)) {
+ efree(bind->array.element_lengths);
+ efree(bind->array.elements);
+ efree(bind);
+ return NULL;
+ }
- convert_to_string_ex(entry);
- PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)Z_STRVAL_P(entry), (ub4) Z_STRLEN_P(entry), NULL, 0, NULL, 0, &oci_date));
+ PHP_OCI_CALL_RETURN(errstatus, OCIDateFromText, (connection->err, (CONST text *)ZSTR_VAL(entry_str), (ub4) ZSTR_LEN(entry_str), NULL, 0, NULL, 0, &oci_date));
+ zend_string_release(entry_str);
if (errstatus != OCI_SUCCESS) {
/* failed to convert string to date */