From 296030119cec2c1c543b3397dc84977e592a4747 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 25 Aug 2020 15:40:17 +0200 Subject: Catch potential exceptions during to string conversion As of PHP 7.4.0, exceptions are allowed to be thrown from inside `__toString()` methods; we have to cater to that, and catch these exceptions early. Closes GH-6042 --- ext/com_dotnet/com_com.c | 20 +++++++++++++++----- ext/com_dotnet/com_handlers.c | 15 +++++++++++---- ext/com_dotnet/com_saproxy.c | 10 ++++++++-- 3 files changed, 34 insertions(+), 11 deletions(-) (limited to 'ext/com_dotnet') diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index b61cb265e3..ce4bca9d87 100644 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -85,7 +85,9 @@ PHP_FUNCTION(com_create_instance) if (NULL != (tmp = zend_hash_str_find(Z_ARRVAL_P(server_params), "Server", sizeof("Server")-1))) { - convert_to_string_ex(tmp); + if (!try_convert_to_string(tmp)) { + return; + } server_name = Z_STRVAL_P(tmp); server_name_len = Z_STRLEN_P(tmp); ctx = CLSCTX_REMOTE_SERVER; @@ -93,21 +95,27 @@ PHP_FUNCTION(com_create_instance) if (NULL != (tmp = zend_hash_str_find(Z_ARRVAL_P(server_params), "Username", sizeof("Username")-1))) { - convert_to_string_ex(tmp); + if (!try_convert_to_string(tmp)) { + return; + } user_name = Z_STRVAL_P(tmp); user_name_len = Z_STRLEN_P(tmp); } if (NULL != (tmp = zend_hash_str_find(Z_ARRVAL_P(server_params), "Password", sizeof("Password")-1))) { - convert_to_string_ex(tmp); + if (!try_convert_to_string(tmp)) { + return; + } password = Z_STRVAL_P(tmp); password_len = Z_STRLEN_P(tmp); } if (NULL != (tmp = zend_hash_str_find(Z_ARRVAL_P(server_params), "Domain", sizeof("Domain")-1))) { - convert_to_string_ex(tmp); + if (!try_convert_to_string(tmp)) { + return; + } domain_name = Z_STRVAL_P(tmp); domain_name_len = Z_STRLEN_P(tmp); } @@ -720,7 +728,9 @@ PHP_FUNCTION(com_event_sink) if ((tmp = zend_hash_index_find(Z_ARRVAL_P(sink), 1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) dispname = Z_STRVAL_P(tmp); } else if (sink != NULL) { - convert_to_string(sink); + if (!try_convert_to_string(sink)) { + return; + } dispname = Z_STRVAL_P(sink); } diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index d42e7453f8..2a1740e01e 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -38,9 +38,11 @@ static zval *com_property_read(zval *object, zval *member, int type, void **cahc obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { - VariantInit(&v); + if (!try_convert_to_string(member)) { + return rv; + } - convert_to_string_ex(member); + VariantInit(&v); res = php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 0, NULL, 1); @@ -66,9 +68,12 @@ static zval *com_property_write(zval *object, zval *member, zval *value, void ** obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { + if (!try_convert_to_string(member)) { + return value; + } + VariantInit(&v); - convert_to_string_ex(member); if (SUCCESS == php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &v, 1, value, 0)) { VariantClear(&v); @@ -205,7 +210,9 @@ static int com_property_exists(zval *object, zval *member, int check_empty, void obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { - convert_to_string_ex(member); + if (!try_convert_to_string(member)) { + return 0; + } if (SUCCEEDED(php_com_get_id_of_name(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), &dispid))) { /* TODO: distinguish between property and method! */ return 1; diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c index 8369a4bcdd..eec6e2998e 100644 --- a/ext/com_dotnet/com_saproxy.c +++ b/ext/com_dotnet/com_saproxy.c @@ -108,7 +108,10 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type, zval * } ZVAL_COPY_VALUE(&args[i-1], offset); - convert_to_string(&proxy->indices[0]); + if (!try_convert_to_string(&proxy->indices[0])) { + efree(args); + return rv; + } VariantInit(&v); res = php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]), @@ -223,7 +226,10 @@ static void saproxy_write_dimension(zval *object, zval *offset, zval *value) ZVAL_COPY_VALUE(&args[i-1], offset); ZVAL_COPY_VALUE(&args[i], value); - convert_to_string(&proxy->indices[0]); + if (!try_convert_to_string(&proxy->indices[0])) { + efree(args); + return; + } VariantInit(&v); if (SUCCESS == php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]), Z_STRLEN(proxy->indices[0]), DISPATCH_PROPERTYPUT, &v, proxy->dimensions + 1, -- cgit v1.2.1