From 38ad37ad435511391e16983794022a8d1e7d6a14 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 15 Jan 2021 14:01:40 +0100 Subject: Fix #80595: Resetting POSTFIELDS to empty array breaks request This is mainly to work around https://github.com/curl/curl/issues/6455, but not building the mime structure for empty hashtables is a general performance optimization, so we do not restrict it to affected cURL versions (7.56.0 to 7.75.0). The minor change to bug79033.phpt is unexpected, but should not matter in practice. Closes GH-6606. --- NEWS | 3 +++ ext/curl/interface.c | 9 ++++++++- ext/curl/tests/bug79033.phpt | 3 ++- ext/curl/tests/bug80595.phpt | 30 ++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 ext/curl/tests/bug80595.phpt diff --git a/NEWS b/NEWS index ba530c5632..24eaddce3e 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ PHP NEWS . Fixed bug #80384 (filter buffers entire read until file closed). (Adam Seitz, cmb) +- Curl: + . Fixed bug #80595 (Resetting POSTFIELDS to empty array breaks request). (cmb) + - Date: . Fixed bug #80376 (last day of the month causes runway cpu usage. (Derick) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 01742ba3e5..7faf439ce1 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -2969,7 +2969,14 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ case CURLOPT_POSTFIELDS: if (Z_TYPE_P(zvalue) == IS_ARRAY || Z_TYPE_P(zvalue) == IS_OBJECT) { - return build_mime_structure_from_hash(ch, zvalue); + if (zend_hash_num_elements(HASH_OF(zvalue)) == 0) { + /* no need to build the mime structure for empty hashtables; + also works around https://github.com/curl/curl/issues/6455 */ + curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDS, ""); + error = curl_easy_setopt(ch->cp, CURLOPT_POSTFIELDSIZE, 0); + } else { + return build_mime_structure_from_hash(ch, zvalue); + } } else { #if LIBCURL_VERSION_NUM >= 0x071101 zend_string *tmp_str; diff --git a/ext/curl/tests/bug79033.phpt b/ext/curl/tests/bug79033.phpt index 98a97ed7a4..7021385c98 100644 --- a/ext/curl/tests/bug79033.phpt +++ b/ext/curl/tests/bug79033.phpt @@ -21,9 +21,10 @@ var_dump(curl_getinfo($ch)["request_header"]); string(%d) "array(0) { } " -string(90) "POST /get.inc?test=post HTTP/1.1 +string(%d) "POST /get.inc?test=post HTTP/1.1 Host: localhost:%d Accept: */* Content-Length: 0 +Content-Type: application/x-www-form-urlencoded " diff --git a/ext/curl/tests/bug80595.phpt b/ext/curl/tests/bug80595.phpt new file mode 100644 index 0000000000..48137db4e6 --- /dev/null +++ b/ext/curl/tests/bug80595.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #80595 (Resetting POSTFIELDS to empty array breaks request) +--SKIPIF-- + +--FILE-- + true, + CURLOPT_POST => true, + CURLOPT_URL => "{$host}/get.inc?test=post", +]); + +curl_setopt($ch, CURLOPT_POSTFIELDS, ['foo' => 'bar']); +var_dump(curl_exec($ch)); + +curl_setopt($ch, CURLOPT_POSTFIELDS, []); +var_dump(curl_exec($ch)); +?> +--EXPECT-- +string(43) "array(1) { + ["foo"]=> + string(3) "bar" +} +" +string(13) "array(0) { +} +" -- cgit v1.2.1