]> granicus.if.org Git - php/commitdiff
Catch potential exceptions during to string conversion
authorChristoph M. Becker <cmbecker69@gmx.de>
Tue, 25 Aug 2020 13:40:17 +0000 (15:40 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Thu, 27 Aug 2020 08:23:18 +0000 (10:23 +0200)
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
ext/com_dotnet/com_handlers.c
ext/com_dotnet/com_saproxy.c

index b61cb265e330dcc4fcf2b1d20d838eb4d3b513d0..ce4bca9d871e2ac4155c1584a1a34507a86cd6c8 100644 (file)
@@ -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);
        }
 
index d42e7453f863383b02f3ab5f958abbb4d80a861c..2a1740e01e6c0a77f84bf427a15c2a5886c01c06 100644 (file)
@@ -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;
index 8369a4bcdde2a4927598dc1a703d7006a483a550..eec6e2998e03f2d66ded140438db9dc812b36118 100644 (file)
@@ -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,