From a3bf80a74119956a1ef4f68eda941ad2ab23934a Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 10:43:43 +0000 Subject: [PATCH 01/17] ext/curl: test curl option CURLOPT_WRITEHEADER --- .../curl_setopt_CURLOPT_WRITEHEADER.phpt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt diff --git a/ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt b/ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt new file mode 100644 index 000000000000..06a80f86a3b1 --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt @@ -0,0 +1,36 @@ +--TEST-- +Curl option CURLOPT_WRITEHEADER +--DESCRIPTION-- +Test writing HTTP response headers to a file using CURLOPT_WRITEHEADER. +--EXTENSIONS-- +curl +--FILE-- + +--EXPECTF-- +HTTP/1.1 200 OK +Host: localhost:%d +Date: %s +Connection: close +X-Powered-By: PHP/%s +Content-Type: text/plain;charset=utf-8 From 7fd26e145f9c5c8f1accd2a155103bcf69f2f619 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 11:50:42 +0000 Subject: [PATCH 02/17] ext/curl: add test for CURLOPT_MAXFILESIZE_LARGE --- ...curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt diff --git a/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt b/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt new file mode 100644 index 000000000000..72064be824f0 --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt @@ -0,0 +1,54 @@ +--TEST-- +Curl option CURLOPT_MAXFILESIZE_LARGE +--DESCRIPTION-- +Test CURLOPT_MAXFILESIZE_LARGE with values that exceed, do not exceed, and +disable the limit, as well as a negative value that triggers an error. +--EXTENSIONS-- +curl +--FILE-- + +--EXPECTF-- +Body larger than CURLOPT_MAXFILESIZE_LARGE +bool(false) +bool(true) +Body smaller than CURLOPT_MAXFILESIZE_LARGE +int(25) +Limit disabled by setting CURLOPT_MAXFILESIZE_LARGE to 0 +int(25) +Negative value for CURLOPT_MAXFILESIZE_LARGE +bool(false) +bool(true) +Negative value not set, CURLOPT_MAXFILESIZE_LARGE is still 0 +int(25) From a1f182f6d4a1c3896dfa02b4d9a26a71d3665304 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 12:45:02 +0000 Subject: [PATCH 03/17] Add test for CURLOPT_POSTREDIR --- .../tests/curl_setopt_CURLOPT_POSTREDIR.phpt | 91 +++++++++++++++++++ ext/curl/tests/responder/get.inc | 2 +- 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt diff --git a/ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt b/ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt new file mode 100644 index 000000000000..686eca698b17 --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt @@ -0,0 +1,91 @@ +--TEST-- +Curl option CURLOPT_POSTREDIR +--DESCRIPTION-- +Verify that CURLOPT_POSTREDIR controls whether POST data is retained on +301, 302, and 303 redirects. By default libcurl turns POST into GET on +301, 302, and 303. Setting the appropriate bit in CURLOPT_POSTREDIR +keeps the POST method and body. +--EXTENSIONS-- +curl +--FILE-- + +--EXPECT-- +default 301: string(0) "" +default 302: string(0) "" +default 303: string(0) "" +301 on, code 301: string(7) "foo=bar" +301 on, code 302: string(0) "" +301 on, code 303: string(0) "" +302 on, code 301: string(0) "" +302 on, code 302: string(7) "foo=bar" +302 on, code 303: string(0) "" +303 on, code 301: string(0) "" +303 on, code 302: string(0) "" +303 on, code 303: string(7) "foo=bar" +ALL on, code 301: string(7) "foo=bar" +ALL on, code 302: string(7) "foo=bar" +ALL on, code 303: string(7) "foo=bar" diff --git a/ext/curl/tests/responder/get.inc b/ext/curl/tests/responder/get.inc index 2ef1e4a89dd3..a62b6f7f172e 100644 --- a/ext/curl/tests/responder/get.inc +++ b/ext/curl/tests/responder/get.inc @@ -49,7 +49,7 @@ case 'redirect': // A 307 preserves the method and body, so libcurl must rewind the upload // (via CURLOPT_SEEKFUNCTION) before resending it to the new location. - header('Location: /get.inc?test=input', true, 307); + header('Location: /get.inc?test=input', true, $_GET['code'] ?? 307); break; default: echo "Hello World!\n"; From bc61c3d416bd1e92aa779636b66cdfaf57516411 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 14:05:13 +0000 Subject: [PATCH 04/17] ext/curl: test CURLOPT_SSH_HOSTKEYFUNCTION --- ...rl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt diff --git a/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt new file mode 100644 index 000000000000..b2564162b635 --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt @@ -0,0 +1,26 @@ +--TEST-- +Curl option CURLOPT_SSH_HOSTKEYFUNCTION +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) +string(49) "SSL peer certificate or SSH remote key was not OK" From 52e7ed4a40417dda593aa7af3df3334a170628dd Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 14:24:32 +0000 Subject: [PATCH 05/17] ext/curl: test CURLOPT_FNMATCH_FUNCTION --- .../curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt diff --git a/ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt new file mode 100644 index 000000000000..94196842160e --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt @@ -0,0 +1,41 @@ +--TEST-- +Curl option CURLOPT_FNMATCH_FUNCTION +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- + +--EXPECT-- +The list of Debian mirror sites is available here: https://www.debian.org/mirror/list +bool(true) +bool(true) From afdeed93945de0c77047ef3704ed0c7c4881cf33 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 17:22:27 +0000 Subject: [PATCH 06/17] ext/curl: test CURLINFO_HEADER_OUT --- .../curl_getinfo_CURLINFO_HEADER_OUT.phpt | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt new file mode 100644 index 000000000000..c50edc219e1d --- /dev/null +++ b/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt @@ -0,0 +1,43 @@ +--TEST-- +curl_getinfo CURLINFO_HEADER_OUT +--DESCRIPTION-- +Verify that CURLINFO_HEADER_OUT returns the request header sent on the +last request, and that toggling it back to 0 returns FALSE. +--EXTENSIONS-- +curl +--FILE-- + +--EXPECTF-- +With CURLINFO_HEADER_OUT=1: +GET /get.inc?test=method HTTP/1.1 +Host: localhost:%d +%s +Request-num: 1 +--- +With CURLINFO_HEADER_OUT=0: +bool(false) From a4014a026efaed5aee6b9384fd7470eb7b8e9264 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 19:26:38 +0000 Subject: [PATCH 07/17] ext/curl: test read_cb by sending a CURLFile twice Allow setting target of redirect in test --- ext/curl/tests/curl_curlfile_seek.phpt | 22 ++++++++++++++++++++++ ext/curl/tests/responder/get.inc | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 ext/curl/tests/curl_curlfile_seek.phpt diff --git a/ext/curl/tests/curl_curlfile_seek.phpt b/ext/curl/tests/curl_curlfile_seek.phpt new file mode 100644 index 000000000000..8ebaab92bc43 --- /dev/null +++ b/ext/curl/tests/curl_curlfile_seek.phpt @@ -0,0 +1,22 @@ +--TEST-- +curl seek within uploaded file +--EXTENSIONS-- +curl +--FILE-- + new CURLFile(__DIR__ . '/curl_testdata1.txt') +]); +curl_exec($ch); + +?> +--EXPECT-- +curl_testdata1.txt|application/octet-stream|6 diff --git a/ext/curl/tests/responder/get.inc b/ext/curl/tests/responder/get.inc index a62b6f7f172e..a2ede2836cc5 100644 --- a/ext/curl/tests/responder/get.inc +++ b/ext/curl/tests/responder/get.inc @@ -49,7 +49,8 @@ case 'redirect': // A 307 preserves the method and body, so libcurl must rewind the upload // (via CURLOPT_SEEKFUNCTION) before resending it to the new location. - header('Location: /get.inc?test=input', true, $_GET['code'] ?? 307); + $target = $_GET['target'] ?? 'input'; + header('Location: /get.inc?test=' . $target, true, $_GET['code'] ?? 307); break; default: echo "Hello World!\n"; From f7f66c347a0f8114a02b9c56a94d3bba534cf762 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 17 Aug 2026 19:43:28 +0000 Subject: [PATCH 08/17] ext/curl: add test for CURLINFO_CERTINFO --- .../tests/curl_getinfo_CURLINFO_CERTINFO.phpt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 ext/curl/tests/curl_getinfo_CURLINFO_CERTINFO.phpt diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_CERTINFO.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_CERTINFO.phpt new file mode 100644 index 000000000000..7ce814717753 --- /dev/null +++ b/ext/curl/tests/curl_getinfo_CURLINFO_CERTINFO.phpt @@ -0,0 +1,26 @@ +--TEST-- +curl_getinfo - CURLINFO_CERTINFO +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pong +bool(false) +bool(true) From 2aa80efcacc776c87712a9beed9487c40be6cffc Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Tue, 18 Aug 2026 08:33:24 +0000 Subject: [PATCH 09/17] Minor fixes --- ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt | 2 +- ext/curl/tests/responder/get.inc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt b/ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt index 06a80f86a3b1..1a372c978548 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt @@ -10,7 +10,7 @@ include 'server.inc'; $host = curl_cli_server_start(); $header_file = tempnam(sys_get_temp_dir(), 'curl-writeheader'); -$fp = fopen($header_file, 'w'); +$fp = fopen($header_file, 'w') or die('failed to open header output file'); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=contenttype"); diff --git a/ext/curl/tests/responder/get.inc b/ext/curl/tests/responder/get.inc index a2ede2836cc5..f84d4b62858f 100644 --- a/ext/curl/tests/responder/get.inc +++ b/ext/curl/tests/responder/get.inc @@ -50,7 +50,8 @@ // A 307 preserves the method and body, so libcurl must rewind the upload // (via CURLOPT_SEEKFUNCTION) before resending it to the new location. $target = $_GET['target'] ?? 'input'; - header('Location: /get.inc?test=' . $target, true, $_GET['code'] ?? 307); + $code = $_GET['code'] ?? 307; + header('Location: /get.inc?test=' . $target, true, $code); break; default: echo "Hello World!\n"; From 035e0b896b165b6b2612fd34d79d53846ccb735f Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Tue, 18 Aug 2026 11:31:21 +0000 Subject: [PATCH 10/17] ext/curl: test CURLE_ error constants --- ext/curl/tests/curl_errors.phpt | 110 ++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 ext/curl/tests/curl_errors.phpt diff --git a/ext/curl/tests/curl_errors.phpt b/ext/curl/tests/curl_errors.phpt new file mode 100644 index 000000000000..aada11b3f60f --- /dev/null +++ b/ext/curl/tests/curl_errors.phpt @@ -0,0 +1,110 @@ +--TEST-- +curl error constants +--EXTENSIONS-- +curl +--FILE-- + Date: Tue, 18 Aug 2026 11:57:07 +0000 Subject: [PATCH 11/17] Improve tests after review comments --- ext/curl/tests/curl_errors.phpt | 2 +- .../curl_getinfo_CURLINFO_HEADER_OUT.phpt | 3 +- .../tests/curl_setopt_CURLOPT_POSTREDIR.phpt | 86 ++++++------------- ...rl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt | 4 + .../curl_setopt_CURLOPT_WRITEHEADER.phpt | 11 +-- 5 files changed, 39 insertions(+), 67 deletions(-) diff --git a/ext/curl/tests/curl_errors.phpt b/ext/curl/tests/curl_errors.phpt index aada11b3f60f..cf3d8c60770a 100644 --- a/ext/curl/tests/curl_errors.phpt +++ b/ext/curl/tests/curl_errors.phpt @@ -57,7 +57,7 @@ $errors = [ foreach ($errors as $error) { $value = defined($error) ? constant($error) : 'undefined'; - echo $error, '=', $value, PHP_EOL; + echo $error, '=', $value, "\n"; } --EXPECT-- diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt index c50edc219e1d..c03bd3bc6033 100644 --- a/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt +++ b/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt @@ -19,8 +19,7 @@ curl_exec($ch); // The header string contains the full request header line(s). $headers = rtrim(curl_getinfo($ch, CURLINFO_HEADER_OUT)); echo "With CURLINFO_HEADER_OUT=1:\n"; -echo $headers; -echo "\n---\n"; +echo $headers, "\n---\n"; // Toggling back to 0 should clear the buffer; next getinfo returns false. curl_setopt($ch, CURLOPT_HTTPHEADER, ['Request-num: 2']); diff --git a/ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt b/ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt index 686eca698b17..ff7cebdb4c15 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt @@ -18,7 +18,7 @@ function do_redirect($code, $postredir_value = null) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=redirect&code={$code}"); curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, 'foo=bar'); + curl_setopt($ch, CURLOPT_POSTFIELDS, 'postdata was kept in redirect'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); if ($postredir_value !== null) { @@ -27,65 +27,33 @@ function do_redirect($code, $postredir_value = null) { return trim(curl_exec($ch)); } -echo "default 301: "; -echo do_redirect(301), PHP_EOL; +$options = [null, CURL_REDIR_POST_301, CURL_REDIR_POST_302, CURL_REDIR_POST_303, CURL_REDIR_POST_ALL, 0]; +$codes = [301, 302, 303]; -echo "default 302: "; -echo do_redirect(302), PHP_EOL; - -echo "default 303: "; -echo do_redirect(303), PHP_EOL; - -echo "301 on, code 301: "; -echo do_redirect(301, CURL_REDIR_POST_301), PHP_EOL; - -echo "301 on, code 302: "; -echo do_redirect(302, CURL_REDIR_POST_301), PHP_EOL; - -echo "301 on, code 303: "; -echo do_redirect(303, CURL_REDIR_POST_301), PHP_EOL; - -echo "302 on, code 301: "; -echo do_redirect(301, CURL_REDIR_POST_302), PHP_EOL; - -echo "302 on, code 302: "; -echo do_redirect(302, CURL_REDIR_POST_302), PHP_EOL; - -echo "302 on, code 303: "; -echo do_redirect(303, CURL_REDIR_POST_302), PHP_EOL; - -echo "303 on, code 301: "; -echo do_redirect(301, CURL_REDIR_POST_303), PHP_EOL; - -echo "303 on, code 302: "; -echo do_redirect(302, CURL_REDIR_POST_303), PHP_EOL; - -echo "303 on, code 303: "; -echo do_redirect(303, CURL_REDIR_POST_303), PHP_EOL; - -echo "ALL on, code 301: "; -echo do_redirect(301, CURL_REDIR_POST_ALL), PHP_EOL; - -echo "ALL on, code 302: "; -echo do_redirect(302, CURL_REDIR_POST_ALL), PHP_EOL; - -echo "ALL on, code 303: "; -echo do_redirect(303, CURL_REDIR_POST_ALL), PHP_EOL; +foreach ($options as $option) { + foreach ($codes as $code) { + echo "code: $code; option ", var_export($option, true), ': '; + echo do_redirect($code, $option), "\n"; + } +} ?> --EXPECT-- -default 301: string(0) "" -default 302: string(0) "" -default 303: string(0) "" -301 on, code 301: string(7) "foo=bar" -301 on, code 302: string(0) "" -301 on, code 303: string(0) "" -302 on, code 301: string(0) "" -302 on, code 302: string(7) "foo=bar" -302 on, code 303: string(0) "" -303 on, code 301: string(0) "" -303 on, code 302: string(0) "" -303 on, code 303: string(7) "foo=bar" -ALL on, code 301: string(7) "foo=bar" -ALL on, code 302: string(7) "foo=bar" -ALL on, code 303: string(7) "foo=bar" +code: 301; option NULL: string(0) "" +code: 302; option NULL: string(0) "" +code: 303; option NULL: string(0) "" +code: 301; option 1: string(29) "postdata was kept in redirect" +code: 302; option 1: string(0) "" +code: 303; option 1: string(0) "" +code: 301; option 2: string(0) "" +code: 302; option 2: string(29) "postdata was kept in redirect" +code: 303; option 2: string(0) "" +code: 301; option 4: string(0) "" +code: 302; option 4: string(0) "" +code: 303; option 4: string(29) "postdata was kept in redirect" +code: 301; option 7: string(29) "postdata was kept in redirect" +code: 302; option 7: string(29) "postdata was kept in redirect" +code: 303; option 7: string(29) "postdata was kept in redirect" +code: 301; option 0: string(0) "" +code: 302; option 0: string(0) "" +code: 303; option 0: string(0) "" diff --git a/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt index b2564162b635..9bb6f0104cdf 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt @@ -5,6 +5,10 @@ curl --SKIPIF-- = 7.84.0"); +} ?> --FILE-- +--CLEAN-- + --EXPECTF-- HTTP/1.1 200 OK From 6d0a25b74dab34bc497bcb3ae8a49574f7d24cb0 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 24 Aug 2026 14:14:30 +0000 Subject: [PATCH 12/17] ext/curl: Skip CURLOPT_MAXFILESIZE_LARGE test on curl < 8.4.0 It has the option, but it works differently. We could make it work on earlier versions by including a Content-Type header, but I don't really see the use of that. The goal of the test is to see whether curl_off_t are correctly passed off to curl, not the behavior of curl itself. --- .../tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt b/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt index 72064be824f0..85c4c81bccd6 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt @@ -3,6 +3,15 @@ Curl option CURLOPT_MAXFILESIZE_LARGE --DESCRIPTION-- Test CURLOPT_MAXFILESIZE_LARGE with values that exceed, do not exceed, and disable the limit, as well as a negative value that triggers an error. +--SKIPIF-- += 8.4.0"); +} +?> --EXTENSIONS-- curl --FILE-- From 1735ae2a427f880c05f8300e582d1a0c6927a9b2 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Mon, 24 Aug 2026 15:07:32 +0000 Subject: [PATCH 13/17] Remove duplicate CURLE_OUT_OF_MEMORY --- ext/curl/tests/curl_errors.phpt | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/curl/tests/curl_errors.phpt b/ext/curl/tests/curl_errors.phpt index cf3d8c60770a..198dc4767228 100644 --- a/ext/curl/tests/curl_errors.phpt +++ b/ext/curl/tests/curl_errors.phpt @@ -24,7 +24,6 @@ $errors = [ "CURLE_WRITE_ERROR", "CURLE_READ_ERROR", "CURLE_OUT_OF_MEMORY", - "CURLE_OUT_OF_MEMORY", "CURLE_OPERATION_TIMEDOUT", "CURLE_FTP_PORT_FAILED", "CURLE_FTP_COULDNT_USE_REST", @@ -79,7 +78,6 @@ CURLE_HTTP_RETURNED_ERROR=22 CURLE_WRITE_ERROR=23 CURLE_READ_ERROR=26 CURLE_OUT_OF_MEMORY=27 -CURLE_OUT_OF_MEMORY=27 CURLE_OPERATION_TIMEDOUT=28 CURLE_FTP_PORT_FAILED=30 CURLE_FTP_COULDNT_USE_REST=31 From 67ba4a6270c1506ea579ec07fab8dea70db921de Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Tue, 25 Aug 2026 07:17:33 +0000 Subject: [PATCH 14/17] Test error code instead of error message --- ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt index 9bb6f0104cdf..819d7a0c98de 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_SSH_HOSTKEYFUNCTION.phpt @@ -22,9 +22,9 @@ $ch = curl_init('sftp://php@github.com/file.txt'); curl_setopt($ch, CURLOPT_SSH_HOSTKEYFUNCTION, 'hostkeyfunction'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); var_dump(curl_exec($ch)); -var_dump(curl_error($ch)); +var_dump(curl_errno($ch) == CURLE_SSL_CACERT); ?> --EXPECT-- bool(false) -string(49) "SSL peer certificate or SSH remote key was not OK" +bool(true) From 686bb0c197d6489d5b7334ef69c96360444761cb Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Tue, 25 Aug 2026 08:58:11 +0000 Subject: [PATCH 15/17] Run CURLOPT_FNMATCH_FUNCTION test on local test FTP server --- .../curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt | 16 ++++---- ext/ftp/tests/server.inc | 37 ++++++++++++++++++- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt index 94196842160e..5acfc9155322 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_FNMATCH_FUNCTION.phpt @@ -2,13 +2,11 @@ Curl option CURLOPT_FNMATCH_FUNCTION --EXTENSIONS-- curl ---SKIPIF-- - --FILE-- --EXPECT-- -The list of Debian mirror sites is available here: https://www.debian.org/mirror/list +For sale: baby shoes, never worn. bool(true) bool(true) diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 2c7a3a8a5643..6dc7af5a7156 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -329,7 +329,7 @@ if ($pid) { } }elseif (preg_match('/^RETR ([\/]*[\w\h]+)/', $buf, $matches)) { if(!empty($pasv)){ - ; + $fs = $pasvs; } else if (!$fs = stream_socket_client("tcp://$host:$port")) { fputs($s, "425 Can't open data connection\r\n"); @@ -495,7 +495,40 @@ if ($pid) { fputs($s, "226 Transfer complete\r\n"); }elseif (preg_match('/^LIST no_exists\//', $buf, $matches)) { fputs($s, "425 Error establishing connection\r\n"); - + }elseif (preg_match('/^LIST\s*$/', $buf, $matches)) { + if (empty($pasv)) { + fputs($s, "150 File status okay; about to open data connection\r\n"); + if (!$fs = stream_socket_client("tcp://$host:$port")) { + fputs($s, "425 Can't open data connection\r\n"); + continue; + } + } else { + fputs($s, "125 Data connection already open; transfer starting.\r\n"); + $fs = $pasvs; + } + fputs($fs, + "drwxr-xr-x 1 owner group 0 Jan 01 00:00 .\r\n" . + "drwxr-xr-x 1 owner group 0 Jan 01 00:00 ..\r\n" . + "drwxr-xr-x 1 owner group 0 Jan 01 00:00 www\r\n" . + "drwxr-xr-x 1 owner group 0 Jan 01 00:00 emptydir\r\n" . + "-rw-r--r-- 1 owner group 33 Jan 01 00:00 file1\r\n" . + "-rw-r--r-- 1 owner group 8 Jan 01 00:00 file\n" . + "-rw-r--r-- 1 owner group 35 Jan 01 00:00 a story\r\n" . + "-rw-r--r-- 1 owner group 14 Jan 01 00:00 binary data\r\n" . + "-rw-r--r-- 1 owner group 13 Jan 01 00:00 fget\r\n" . + "-rw-r--r-- 1 owner group 5 Jan 01 00:00 fgetresume\r\n" . + "-rw-r--r-- 1 owner group 5368709120 Jan 01 00:00 largefile\r\n" . + "-rw-r--r-- 1 owner group 5100 Jan 01 00:00 mediumfile\r\n" . + "-rw-r--r-- 1 owner group 1 Jan 01 00:00 fget_large\r\n" . + "-rw-r--r-- 1 owner group 4107 Jan 01 00:00 crlf_boundary\r\n" . + "-rw-r--r-- 1 owner group 4096 Jan 01 00:00 bare_cr\r\n" . + "-rw-r--r-- 1 owner group 6 Jan 01 00:00 trailing_cr\r\n" . + "-rw-r--r-- 1 owner group 10 Jan 01 00:00 gh10521\r\n" . + "-rw-r--r-- 1 owner group 10 Jan 01 00:00 pasv\r\n" . + "-rw-r--r-- 1 owner group 10 Jan 01 00:00 bug73457\r\n" + ); + fclose($fs); + fputs($s, "226 Closing data Connection.\r\n"); }elseif (preg_match('/^REST (\d+)/', $buf, $matches)) { $GLOBALS['rest_pos'] = $matches[1]; fputs($s, "350 OK\r\n"); From 964dacac5decdbccfecb8a81a3ae568b278b8fac Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Tue, 25 Aug 2026 09:01:49 +0000 Subject: [PATCH 16/17] Remove descriptions They are pretty verbose and don't add much --- ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt | 3 --- ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt | 3 --- ext/curl/tests/curl_setopt_CURLOPT_POSTREDIR.phpt | 5 ----- ext/curl/tests/curl_setopt_CURLOPT_WRITEHEADER.phpt | 2 -- 4 files changed, 13 deletions(-) diff --git a/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt b/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt index c03bd3bc6033..1627c03f2ba2 100644 --- a/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt +++ b/ext/curl/tests/curl_getinfo_CURLINFO_HEADER_OUT.phpt @@ -1,8 +1,5 @@ --TEST-- curl_getinfo CURLINFO_HEADER_OUT ---DESCRIPTION-- -Verify that CURLINFO_HEADER_OUT returns the request header sent on the -last request, and that toggling it back to 0 returns FALSE. --EXTENSIONS-- curl --FILE-- diff --git a/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt b/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt index 85c4c81bccd6..8e12e8b9a780 100644 --- a/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt +++ b/ext/curl/tests/curl_setopt_CURLOPT_MAXFILESIZE_LARGE.phpt @@ -1,8 +1,5 @@ --TEST-- Curl option CURLOPT_MAXFILESIZE_LARGE ---DESCRIPTION-- -Test CURLOPT_MAXFILESIZE_LARGE with values that exceed, do not exceed, and -disable the limit, as well as a negative value that triggers an error. --SKIPIF-- Date: Tue, 25 Aug 2026 09:34:42 +0000 Subject: [PATCH 17/17] Fix undefined variable warning --- ext/ftp/tests/server.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 6dc7af5a7156..291e09abc303 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -449,6 +449,8 @@ if ($pid) { if (empty($bug73457)) { $pasvs = stream_socket_accept($soc,10); + } else { + $pasvs = null; } } elseif (preg_match('/^EPSV/', $buf, $matches)) {