]> granicus.if.org Git - php/commitdiff
Don't accept objects instead of arrays in curl
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 26 Jun 2020 10:35:52 +0000 (12:35 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 29 Jun 2020 13:56:22 +0000 (15:56 +0200)
This properly addresses the issue from bug #79741. Silently
interpreting objects as mangled property tables is almost
always a bad idea.

Closes GH-5773.

UPGRADING
ext/curl/interface.c
ext/curl/tests/bug79741.phpt
ext/curl/tests/curl_setopt_basic003.phpt

index ef9764f324cb50075441c89257654f86ae492b3b..de0eebd055832ce367aec0dd473b359f12c2457c 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -201,6 +201,11 @@ PHP 8.0 UPGRADE NOTES
     com.autoregister_casesensitive may no longer be disabled; case-insensitive
     markers in com.typelib_file are ignored.
 
+- Curl:
+  . CURLOPT_POSTFIELDS no longer accepts objects as arrays. To interpret an
+    object as an array, perform an explicit (array) cast. The same applies to
+    other options accepting arrays as well.
+
 - Date:
   . mktime() and gmmktime() now require at least one argument. time() can be
     used to get the current timestamp.
index 7b16cc861e93ef5dd66c1e0437348cb3ad836fec..e17bfebc5999c1e774b5fb2fbba36c2151b477b5 100644 (file)
@@ -2016,9 +2016,9 @@ static void free_cb(void *arg) /* {{{ */
 
 static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields) /* {{{ */
 {
+       HashTable *postfields = Z_ARRVAL_P(zpostfields);
        CURLcode error = CURLE_OK;
        zval *current;
-       HashTable *postfields;
        zend_string *string_key;
        zend_ulong num_key;
 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
@@ -2031,12 +2031,6 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
        CURLFORMcode form_error;
 #endif
 
-       postfields = HASH_OF(zpostfields);
-       if (!postfields) {
-               php_error_docref(NULL, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS");
-               return FAILURE;
-       }
-
 #if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
        if (zend_hash_num_elements(postfields) > 0) {
                mime = curl_mime_init(ch->cp);
@@ -2046,7 +2040,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
        }
 #endif
 
-       ZEND_HASH_FOREACH_KEY_VAL_IND(postfields, num_key, string_key, current) {
+       ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) {
                zend_string *postval, *tmp_postval;
                /* Pretend we have a string_key here */
                if (!string_key) {
@@ -2659,8 +2653,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
                        zend_string *val, *tmp_val;
                        struct curl_slist *slist = NULL;
 
-                       ph = HASH_OF(zvalue);
-                       if (!ph) {
+                       if (Z_TYPE_P(zvalue) != IS_ARRAY) {
                                char *name = NULL;
                                switch (option) {
                                        case CURLOPT_HTTPHEADER:
@@ -2698,11 +2691,12 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
                                                break;
 #endif
                                }
-                               php_error_docref(NULL, E_WARNING, "You must pass either an object or an array with the %s argument", name);
+                               php_error_docref(NULL, E_WARNING, "You must pass an array with the %s argument", name);
                                return FAILURE;
                        }
 
-                       ZEND_HASH_FOREACH_VAL_IND(ph, current) {
+                       ph = Z_ARRVAL_P(zvalue);
+                       ZEND_HASH_FOREACH_VAL(ph, current) {
                                ZVAL_DEREF(current);
                                val = zval_get_tmp_string(current, &tmp_val);
                                slist = curl_slist_append(slist, ZSTR_VAL(val));
@@ -2745,7 +2739,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
                        break;
 
                case CURLOPT_POSTFIELDS:
-                       if (Z_TYPE_P(zvalue) == IS_ARRAY || Z_TYPE_P(zvalue) == IS_OBJECT) {
+                       if (Z_TYPE_P(zvalue) == IS_ARRAY) {
                                return build_mime_structure_from_hash(ch, zvalue);
                        } else {
                                zend_string *tmp_str;
index 17c3f57e049cca129bcb8bb8281c1118e1416d91..3f5a4801b19c2bd306c09c39c5138b1262c0577d 100644 (file)
@@ -12,5 +12,9 @@ curl_setopt($ch, CURLOPT_POSTFIELDS, new Test);
 
 ?>
 ===DONE===
---EXPECT--
-===DONE===
+--EXPECTF--
+Fatal error: Uncaught Error: Object of class Test could not be converted to string in %s:%d
+Stack trace:
+#0 %s(%d): curl_setopt(Object(CurlHandle), %d, Object(Test))
+#1 {main}
+  thrown in %s on line %d
index 246b83b4186d331f0b081d680f7eb25dbd4be3cf..6fbbbca47a86f6b089fd64f2cca49c69e9d8321d 100644 (file)
@@ -39,6 +39,6 @@ var_dump( $curl_content );
 --EXPECTF--
 *** curl_setopt() call with CURLOPT_HTTPHEADER
 
-Warning: curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER argument in %s on line %d
+Warning: curl_setopt(): You must pass an array with the CURLOPT_HTTPHEADER argument in %s on line %d
 bool(false)
 bool(true)