Skip to content

Commit 6e1990d

Browse files
committed
Don't accept objects instead of arrays in curl
This properly addresses the issue from bug #79741. Silently interpreting objects as mangled property tables is almost always a bad idea. Closes GH-5773.
1 parent 75a04ea commit 6e1990d

File tree

4 files changed

+19
-16
lines changed

4 files changed

+19
-16
lines changed

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ PHP 8.0 UPGRADE NOTES
201201
com.autoregister_casesensitive may no longer be disabled; case-insensitive
202202
markers in com.typelib_file are ignored.
203203

204+
- Curl:
205+
. CURLOPT_POSTFIELDS no longer accepts objects as arrays. To interpret an
206+
object as an array, perform an explicit (array) cast. The same applies to
207+
other options accepting arrays as well.
208+
204209
- Date:
205210
. mktime() and gmmktime() now require at least one argument. time() can be
206211
used to get the current timestamp.

ext/curl/interface.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,9 +2016,9 @@ static void free_cb(void *arg) /* {{{ */
20162016

20172017
static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields) /* {{{ */
20182018
{
2019+
HashTable *postfields = Z_ARRVAL_P(zpostfields);
20192020
CURLcode error = CURLE_OK;
20202021
zval *current;
2021-
HashTable *postfields;
20222022
zend_string *string_key;
20232023
zend_ulong num_key;
20242024
#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
20312031
CURLFORMcode form_error;
20322032
#endif
20332033

2034-
postfields = HASH_OF(zpostfields);
2035-
if (!postfields) {
2036-
php_error_docref(NULL, E_WARNING, "Couldn't get HashTable in CURLOPT_POSTFIELDS");
2037-
return FAILURE;
2038-
}
2039-
20402034
#if LIBCURL_VERSION_NUM >= 0x073800 /* 7.56.0 */
20412035
if (zend_hash_num_elements(postfields) > 0) {
20422036
mime = curl_mime_init(ch->cp);
@@ -2046,7 +2040,7 @@ static inline int build_mime_structure_from_hash(php_curl *ch, zval *zpostfields
20462040
}
20472041
#endif
20482042

2049-
ZEND_HASH_FOREACH_KEY_VAL_IND(postfields, num_key, string_key, current) {
2043+
ZEND_HASH_FOREACH_KEY_VAL(postfields, num_key, string_key, current) {
20502044
zend_string *postval, *tmp_postval;
20512045
/* Pretend we have a string_key here */
20522046
if (!string_key) {
@@ -2659,8 +2653,7 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
26592653
zend_string *val, *tmp_val;
26602654
struct curl_slist *slist = NULL;
26612655

2662-
ph = HASH_OF(zvalue);
2663-
if (!ph) {
2656+
if (Z_TYPE_P(zvalue) != IS_ARRAY) {
26642657
char *name = NULL;
26652658
switch (option) {
26662659
case CURLOPT_HTTPHEADER:
@@ -2698,11 +2691,12 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
26982691
break;
26992692
#endif
27002693
}
2701-
php_error_docref(NULL, E_WARNING, "You must pass either an object or an array with the %s argument", name);
2694+
php_error_docref(NULL, E_WARNING, "You must pass an array with the %s argument", name);
27022695
return FAILURE;
27032696
}
27042697

2705-
ZEND_HASH_FOREACH_VAL_IND(ph, current) {
2698+
ph = Z_ARRVAL_P(zvalue);
2699+
ZEND_HASH_FOREACH_VAL(ph, current) {
27062700
ZVAL_DEREF(current);
27072701
val = zval_get_tmp_string(current, &tmp_val);
27082702
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) /* {{{
27452739
break;
27462740

27472741
case CURLOPT_POSTFIELDS:
2748-
if (Z_TYPE_P(zvalue) == IS_ARRAY || Z_TYPE_P(zvalue) == IS_OBJECT) {
2742+
if (Z_TYPE_P(zvalue) == IS_ARRAY) {
27492743
return build_mime_structure_from_hash(ch, zvalue);
27502744
} else {
27512745
zend_string *tmp_str;

ext/curl/tests/bug79741.phpt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,9 @@ curl_setopt($ch, CURLOPT_POSTFIELDS, new Test);
1212

1313
?>
1414
===DONE===
15-
--EXPECT--
16-
===DONE===
15+
--EXPECTF--
16+
Fatal error: Uncaught Error: Object of class Test could not be converted to string in %s:%d
17+
Stack trace:
18+
#0 %s(%d): curl_setopt(Object(CurlHandle), %d, Object(Test))
19+
#1 {main}
20+
thrown in %s on line %d

ext/curl/tests/curl_setopt_basic003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ var_dump( $curl_content );
3939
--EXPECTF--
4040
*** curl_setopt() call with CURLOPT_HTTPHEADER
4141

42-
Warning: curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER argument in %s on line %d
42+
Warning: curl_setopt(): You must pass an array with the CURLOPT_HTTPHEADER argument in %s on line %d
4343
bool(false)
4444
bool(true)

0 commit comments

Comments
 (0)