From 3dcdb9826bea199a27db67dd5ba6472e05a18a1d Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Fri, 17 Jul 2026 07:08:58 -0400 Subject: [PATCH 1/8] ext/soap: truncate a user_agent containing newline characters (#22771) GH-17976 sanitized user_agent where the HTTP wrapper emits headers and left the SOAP client alone, so a value carrying CRLF still injects request headers through all three of its sources: the SoapClient user_agent option, the http.user_agent stream context option, and the ini setting. Resolve the three to one zend_string and emit it through the same truncate-and-warn check the HTTP wrapper applies. Closes GH-22771 --- ext/soap/php_http.c | 39 ++++++++++----- .../tests/user_agent_header_injection.phpt | 47 +++++++++++++++++++ 2 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 ext/soap/tests/user_agent_header_injection.phpt diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 43c2182ae47a..22c18259d689 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -25,6 +25,23 @@ static zend_string *get_http_headers(php_stream *socketd); #define smart_str_append_const(str, const) \ smart_str_appendl(str,const,sizeof(const)-1) +static void soap_smart_str_append_header_value(smart_str *dest, const zend_string *value, const char *header_name) +{ + const char *src = ZSTR_VAL(value); + size_t len = ZSTR_LEN(value); + size_t i = 0; + while (i < len && src[i] != '\r' && src[i] != '\n') { + i++; + } + if (i < len) { + smart_str_appendl(dest, src, i); + php_error_docref(NULL, E_WARNING, + "Header %s value contains newline characters and has been truncated", header_name); + } else { + smart_str_append(dest, value); + } +} + /* Proxy HTTP Authentication */ bool proxy_authentication(zval* this_ptr, smart_str* soap_headers) { @@ -607,25 +624,25 @@ bool make_http_soap_request( smart_str_append_const(&soap_headers, "\r\n" "Connection: Keep-Alive\r\n"); } + zend_string *ua_str = NULL; + tmp = Z_CLIENT_USER_AGENT_P(this_ptr); if (Z_TYPE_P(tmp) == IS_STRING) { - if (Z_STRLEN_P(tmp) > 0) { - smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_append(&soap_headers, Z_STR_P(tmp)); - smart_str_append_const(&soap_headers, "\r\n"); - } + ua_str = Z_STR_P(tmp); } else if (context && (tmp = php_stream_context_get_option(context, "http", "user_agent")) != NULL && Z_TYPE_P(tmp) == IS_STRING) { - if (Z_STRLEN_P(tmp) > 0) { + ua_str = Z_STR_P(tmp); + } else if (FG(user_agent)) { + ua_str = FG(user_agent); + } + + if (ua_str) { + if (ZSTR_LEN(ua_str) > 0) { smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_append(&soap_headers, Z_STR_P(tmp)); + soap_smart_str_append_header_value(&soap_headers, ua_str, "User-Agent"); smart_str_append_const(&soap_headers, "\r\n"); } - } else if (FG(user_agent)) { - smart_str_append_const(&soap_headers, "User-Agent: "); - smart_str_append(&soap_headers, FG(user_agent)); - smart_str_append_const(&soap_headers, "\r\n"); } else { smart_str_append_const(&soap_headers, "User-Agent: PHP-SOAP/"PHP_VERSION"\r\n"); } diff --git a/ext/soap/tests/user_agent_header_injection.phpt b/ext/soap/tests/user_agent_header_injection.phpt new file mode 100644 index 000000000000..979e1e579280 --- /dev/null +++ b/ext/soap/tests/user_agent_header_injection.phpt @@ -0,0 +1,47 @@ +--TEST-- +SoapClient must truncate a user_agent that contains newline characters +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- + 'http://' . PHP_CLI_SERVER_ADDRESS, + 'uri' => 'misc-uri', + 'trace' => true, +]); + +$client->__soapCall("foo", []); +echo $client->__getLastRequestHeaders(); + +?> +--EXPECTF-- +Warning: SoapClient::__doRequest(): Header User-Agent value contains newline characters and has been truncated in %s on line %d +POST / HTTP/1.1 +Host: localhost:%d +Connection: Keep-Alive +User-Agent: evil +Content-Type: text/xml; charset=utf-8 +SOAPAction: "misc-uri#foo" +Content-Length: %d From 7522c496300417d7cfbbf6a3cac48651e4574f3b Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Fri, 17 Jul 2026 07:09:41 -0400 Subject: [PATCH 2/8] ext/sqlite3: reject NUL bytes in SQLite3::escapeString() (#22774) escapeString() used sqlite3_mprintf("%q"), which stops at the first C NUL. PHP strings are length-aware and may embed NULs, so values such as "a\0b" were silently truncated to "a" when interpolated into SQL. Prepared binds pass an explicit length and are unaffected. ext/pdo_sqlite rejected the same inputs for PDO::quote in 0a10f6db268 (GH-13952), on 8.5 and up. That check consults the connection's error mode; escapeString() is static and has no connection, so it throws instead. Closes GH-22774 --- ext/sqlite3/sqlite3.c | 2 +- .../tests/gh_sqlite3_escapestring_nul.phpt | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 67ff850cadd0..b81a0677a6c2 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -469,7 +469,7 @@ PHP_METHOD(SQLite3, escapeString) zend_string *sql; char *ret; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S", &sql)) { + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "P", &sql)) { RETURN_THROWS(); } diff --git a/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt b/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt new file mode 100644 index 000000000000..49d66a1accf5 --- /dev/null +++ b/ext/sqlite3/tests/gh_sqlite3_escapestring_nul.phpt @@ -0,0 +1,35 @@ +--TEST-- +SQLite3::escapeString() rejects strings with embedded NUL bytes +--EXTENSIONS-- +sqlite3 +--FILE-- +getMessage(), "\n"; + } +} + +echo "ok: ", SQLite3::escapeString("ok"), "\n"; +echo "quote: ", SQLite3::escapeString("test''%"), "\n"; +echo "empty: ", var_export(SQLite3::escapeString(""), true), "\n"; +?> +--EXPECT-- +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ValueError: SQLite3::escapeString(): Argument #1 ($string) must not contain any null bytes +ok: ok +quote: test''''% +empty: '' From f9b6254375f4da163439daee1a564798250535ac Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Thu, 16 Jul 2026 12:41:51 -0400 Subject: [PATCH 3/8] ext/odbc: do not mutate the caller's DSN string odbc_sqlconnect() stripped a trailing semicolon by writing a NUL into the Z_PARAM_STRING buffer, which is a zend_string. Shared variables, interned literals, and const values used as the DSN were permanently altered (strlen unchanged, last byte became NUL). Compute the base length instead and pass it to spprintf with %.*s, matching the non-mutating approach used when assembling UID/PWD into the connect string. Closes GH-22776 --- ext/odbc/php_odbc.c | 12 ++++++------ ext/odbc/tests/gh_odbc_dsn_immutability.phpt | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 ext/odbc/tests/gh_odbc_dsn_immutability.phpt diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 16617078d3c1..8b78308f9426 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -2217,9 +2217,9 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool /* Force UID and PWD to be set in the DSN */ if (use_uid_arg || use_pwd_arg) { - db_end--; - if ((unsigned char)*(db_end) == ';') { - *db_end = '\0'; + size_t base_len = db_len; + if (base_len > 0 && db[base_len - 1] == ';') { + base_len--; } char *uid_quoted = NULL, *pwd_quoted = NULL; @@ -2235,7 +2235,7 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool } if (!use_pwd_arg) { - spprintf(&ldb, 0, "%s;UID=%s;", db, uid_quoted); + spprintf(&ldb, 0, "%.*s;UID=%s;", (int) base_len, db, uid_quoted); } } @@ -2250,12 +2250,12 @@ bool odbc_sqlconnect(zval *zv, char *db, char *uid, char *pwd, int cur_opt, bool } if (!use_uid_arg) { - spprintf(&ldb, 0, "%s;PWD=%s;", db, pwd_quoted); + spprintf(&ldb, 0, "%.*s;PWD=%s;", (int) base_len, db, pwd_quoted); } } if (use_uid_arg && use_pwd_arg) { - spprintf(&ldb, 0, "%s;UID=%s;PWD=%s;", db, uid_quoted, pwd_quoted); + spprintf(&ldb, 0, "%.*s;UID=%s;PWD=%s;", (int) base_len, db, uid_quoted, pwd_quoted); } if (uid_quoted && should_quote_uid) { diff --git a/ext/odbc/tests/gh_odbc_dsn_immutability.phpt b/ext/odbc/tests/gh_odbc_dsn_immutability.phpt new file mode 100644 index 000000000000..e3023b387c70 --- /dev/null +++ b/ext/odbc/tests/gh_odbc_dsn_immutability.phpt @@ -0,0 +1,20 @@ +--TEST-- +odbc_connect() must not mutate the caller's DSN string +--EXTENSIONS-- +odbc +--FILE-- + +--EXPECT-- +string(37) "Driver=DoesNotExist;Database=x;SS001;" +string(43) "Driver=DoesNotExist;Database=x;SS001_CONST;" From 583403a9a0e965c64d3152ff73c3e208375db507 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Fri, 17 Jul 2026 20:05:20 +0800 Subject: [PATCH 4/8] ext/sockets: Fix TCP_USER_TIMEOUT range error message This is a follow-up commit to 3882f55 where all malformed error message in the socket extension in 8.5 has been fixed. This fixed a specific one appears only in the master branch. --- NEWS | 2 +- ext/sockets/sockets.c | 2 +- ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt | 2 +- ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index b63ae8a81c99..c548f32d052a 100644 --- a/NEWS +++ b/NEWS @@ -30,7 +30,7 @@ PHP NEWS - Sockets: . Fixed socket_set_option() validation error messages for UDP_SEGMENT and - SO_LINGER options. (Weilin Du) + TCP_USER_TIMEOUT, and SO_LINGER options. (Weilin Du) 16 Jul 2026, PHP 8.6.0alpha2 diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index ea90c2ae6425..9c9c86ba6733 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -2154,7 +2154,7 @@ PHP_FUNCTION(socket_set_option) // TCP_USER_TIMEOUT unsigned int if (timeout < 0 || timeout > UINT_MAX) { - zend_argument_value_error(4, "must be of between 0 and %u", UINT_MAX); + zend_argument_value_error(4, "must be between 0 and %u", UINT_MAX); RETURN_THROWS(); } diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt index 3f12120e54d8..05970b719874 100644 --- a/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout_32bit.phpt @@ -29,6 +29,6 @@ var_dump($retval_3 === $timeout); socket_close($socket); ?> --EXPECTF-- -socket_setopt(): Argument #4 ($value) must be of between 0 and %d +socket_setopt(): Argument #4 ($value) must be between 0 and %d bool(true) bool(true) diff --git a/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt index 8dbb7f80e48b..894a24d2a49b 100644 --- a/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt +++ b/ext/sockets/tests/socket_setoption_tcpusertimeout_64bit.phpt @@ -35,7 +35,7 @@ var_dump($retval_3 === $timeout); socket_close($socket); ?> --EXPECTF-- -socket_setopt(): Argument #4 ($value) must be of between 0 and %d -socket_setopt(): Argument #4 ($value) must be of between 0 and %d +socket_setopt(): Argument #4 ($value) must be between 0 and %d +socket_setopt(): Argument #4 ($value) must be between 0 and %d bool(true) bool(true) From ff23286266fb84dc342dc7bb8a6dd0ca970dcf58 Mon Sep 17 00:00:00 2001 From: Sjoerd Langkemper Date: Fri, 17 Jul 2026 15:30:43 +0200 Subject: [PATCH 5/8] Size is always one in curl functions (#22733) Assert and take advantage of that size is always 1. This is also documented in [the curl docs](https://curl.se/libcurl/c/CURLOPT_READFUNCTION.html). So there is no need to multiply with size, so this can be removed. I started this to see whether size * nmemb can overflow. This makes it clear that it cannot. --- ext/curl/interface.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index c0286069776e..2571eb60e42d 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -522,9 +522,11 @@ PHP_MSHUTDOWN_FUNCTION(curl) /* {{{ curl_write */ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) { + ZEND_ASSERT(size == 1); + php_curl *ch = (php_curl *) ctx; php_curl_write *write_handler = ch->handlers.write; - size_t length = size * nmemb; + size_t length = nmemb; #if PHP_CURL_DEBUG fprintf(stderr, "curl_write() called\n"); @@ -786,6 +788,8 @@ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key, /* {{{ curl_read */ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) { + ZEND_ASSERT(size == 1); + php_curl *ch = (php_curl *)ctx; php_curl_read *read_handler = ch->handlers.read; size_t length = 0; @@ -808,7 +812,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) } else { ZVAL_NULL(&argv[1]); } - ZVAL_LONG(&argv[2], (int)size * nmemb); + ZVAL_LONG(&argv[2], (zend_long) nmemb); ch->in_callback = true; zend_call_known_fcc(&read_handler->fcc, &retval, /* param_count */ 3, argv, /* named_params */ NULL); @@ -816,7 +820,7 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) if (!Z_ISUNDEF(retval)) { _php_curl_verify_handlers(ch, /* reporterror */ true); if (Z_TYPE(retval) == IS_STRING) { - length = MIN(size * nmemb, Z_STRLEN(retval)); + length = MIN(nmemb, Z_STRLEN(retval)); memcpy(data, Z_STRVAL(retval), length); } else if (Z_TYPE(retval) == IS_LONG) { length = Z_LVAL_P(&retval); @@ -884,9 +888,11 @@ static int curl_seek(void *clientp, curl_off_t offset, int origin) /* {{{ curl_write_header */ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx) { + ZEND_ASSERT(size == 1); + php_curl *ch = (php_curl *) ctx; php_curl_write *write_handler = ch->handlers.write_header; - size_t length = size * nmemb; + size_t length = nmemb; switch (write_handler->method) { case PHP_CURL_STDOUT: From 1f7abed78993fb0ae780eff2fa489a851bc90fd6 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Jul 2026 17:43:49 +0100 Subject: [PATCH 6/8] streams: remove php_stream_wrapper_warn_param() functions And instead let the normal docref error handling code handle arguments --- Zend/tests/display_error_function_args.phpt | 2 +- .../session_set_save_handler_variation4.phpt | 2 +- .../session_set_save_handler_variation5.phpt | 2 +- ext/standard/tests/file/copy_variation4.phpt | 8 ++-- .../tests/file/copy_variation5-win32.phpt | 4 +- .../tests/file/mkdir_rmdir_error.phpt | 2 +- .../file/mkdir_rmdir_variation-win32-mb.phpt | 2 +- .../file/mkdir_rmdir_variation-win32.phpt | 2 +- .../tests/file/mkdir_rmdir_variation2.phpt | 2 +- .../readlink_realpath_variation2-win32.phpt | 4 +- .../file/readlink_realpath_variation2.phpt | 4 +- .../tests/file/rename_variation-win32.phpt | 2 +- ext/standard/tests/file/rename_variation.phpt | 2 +- .../tests/file/rmdir_variation3-win32.phpt | 6 +-- ext/standard/tests/file/rmdir_variation3.phpt | 6 +-- .../tests/file/unlink_error-win32-mb.phpt | 4 +- .../tests/file/unlink_error-win32.phpt | 4 +- ext/standard/tests/file/unlink_error.phpt | 4 +- .../file/unlink_variation1-win32-mb.phpt | 2 +- .../tests/file/unlink_variation1-win32.phpt | 2 +- .../tests/file/unlink_variation1.phpt | 2 +- .../tests/file/unlink_variation10.phpt | 2 +- .../tests/file/unlink_variation4.phpt | 2 +- .../tests/file/unlink_variation8-win32.phpt | 10 ++--- .../tests/file/unlink_variation8.phpt | 30 +++++++------- .../tests/file/unlink_variation9-win32.phpt | 10 ++--- ext/zlib/tests/gh19922.phpt | 3 +- main/streams/php_stream_errors.h | 20 ---------- main/streams/plain_wrapper.c | 40 +++++++++---------- main/streams/stream_errors.c | 32 --------------- main/streams/streams.c | 15 +++---- .../open_basedir_copy_variation1.phpt | 2 +- 32 files changed, 88 insertions(+), 146 deletions(-) diff --git a/Zend/tests/display_error_function_args.phpt b/Zend/tests/display_error_function_args.phpt index c28a4a2808b4..03530eb98189 100644 --- a/Zend/tests/display_error_function_args.phpt +++ b/Zend/tests/display_error_function_args.phpt @@ -25,6 +25,6 @@ Warning: unlink('/'): %s in %s on line %d Warning: password_hash(Object(SensitiveParameterValue), '2y', Array): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d -Warning: unlink(/): %s in %s on line %d +Warning: unlink(): %s in %s on line %d Warning: password_hash(): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d diff --git a/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt b/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt index cb708e33f52b..84e49f26d122 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_variation4.phpt @@ -83,6 +83,6 @@ array(3) { } Destroy [%s,%s] -Warning: unlink(%s): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d Close [%s,PHPSESSID] bool(true) diff --git a/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt b/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt index a3e21c35e49d..7354f90f28ca 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_variation5.phpt @@ -97,6 +97,6 @@ GC [0] bool(true) Destroy [%s,PHPT-%d] -Warning: unlink(%s): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d Close [%s,PHPSESSID] bool(true) diff --git a/ext/standard/tests/file/copy_variation4.phpt b/ext/standard/tests/file/copy_variation4.phpt index d467cb4ce9ab..4dc318789488 100644 --- a/ext/standard/tests/file/copy_variation4.phpt +++ b/ext/standard/tests/file/copy_variation4.phpt @@ -91,7 +91,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 2 -- Existence of destination file before copy => bool(true) @@ -103,7 +103,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 3 -- Existence of destination file before copy => bool(true) @@ -115,7 +115,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 4 -- Existence of destination file before copy => bool(true) @@ -127,7 +127,7 @@ Destination file name => %s/ Size of source file => int(1500) Size of destination file => int(%d) -Warning: unlink(%s): %s +Warning: unlink(): %s -- Iteration 5 -- Existence of destination file before copy => bool(false) diff --git a/ext/standard/tests/file/copy_variation5-win32.phpt b/ext/standard/tests/file/copy_variation5-win32.phpt index af352dbe0732..e4c42e2f9322 100644 --- a/ext/standard/tests/file/copy_variation5-win32.phpt +++ b/ext/standard/tests/file/copy_variation5-win32.phpt @@ -98,7 +98,7 @@ Destination file name => %s/CopY5.TMP Size of source file => int(1500) Size of destination file => int(1500) -Warning: unlink(%s/COPY5.TMP): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -Warning: unlink(%s/CopY5.TMP): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d *** Done *** diff --git a/ext/standard/tests/file/mkdir_rmdir_error.phpt b/ext/standard/tests/file/mkdir_rmdir_error.phpt index 4500de027668..44dc68f6da47 100644 --- a/ext/standard/tests/file/mkdir_rmdir_error.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_error.phpt @@ -11,6 +11,6 @@ echo "Done\n"; --EXPECTF-- *** Testing rmdir() on non-existent directory *** -Warning: rmdir(temp): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt b/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt index b6c186ed0b09..4e642cf7ae03 100644 --- a/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_variation-win32-mb.phpt @@ -1596,7 +1596,7 @@ bool(true) *** Testing rmdir() on a non-empty directory *** bool(true) -Warning: rmdir(%s/mkdir私はガラスを食べられます/): Directory not empty in %s on line %d +Warning: rmdir(): Directory not empty in %s on line %d bool(false) *** Testing mkdir() and rmdir() for binary safe functionality *** diff --git a/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt b/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt index f4f412e802ff..377de5e6b9fe 100644 --- a/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_variation-win32.phpt @@ -1596,7 +1596,7 @@ bool(true) *** Testing rmdir() on a non-empty directory *** bool(true) -Warning: rmdir(%s/mkdir/): Directory not empty in %s on line %d +Warning: rmdir(): Directory not empty in %s on line %d bool(false) *** Testing mkdir() and rmdir() for binary safe functionality *** diff --git a/ext/standard/tests/file/mkdir_rmdir_variation2.phpt b/ext/standard/tests/file/mkdir_rmdir_variation2.phpt index 4da0b374ba94..831cb0c95662 100644 --- a/ext/standard/tests/file/mkdir_rmdir_variation2.phpt +++ b/ext/standard/tests/file/mkdir_rmdir_variation2.phpt @@ -56,7 +56,7 @@ bool(true) *** Testing rmdir() on a non-empty directory *** bool(true) -Warning: rmdir(%s/mkdir_variation2/): %s on line %d +Warning: rmdir(): %s on line %d bool(false) *** Testing mkdir() and rmdir() for binary safe functionality *** diff --git a/ext/standard/tests/file/readlink_realpath_variation2-win32.phpt b/ext/standard/tests/file/readlink_realpath_variation2-win32.phpt index f1f561538179..8de003eacd77 100644 --- a/ext/standard/tests/file/readlink_realpath_variation2-win32.phpt +++ b/ext/standard/tests/file/readlink_realpath_variation2-win32.phpt @@ -80,7 +80,7 @@ Warning: readlink(): readlink failed to read the symbolic link (%s), error %d in bool(false) bool(false) -Warning: unlink(%s/./readlink_realpath_variation2/home/../home//tests//..//..//..//home//readlink_realpath_variation2_link.tmp/): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- Testing readlink() and realpath() with hardlink, linkname stored inside an array -- bool(true) @@ -94,5 +94,5 @@ Warning: readlink(): readlink failed to read the symbolic link (%s), error %d in bool(false) bool(false) -Warning: unlink(%s/./readlink_realpath_variation2/home/../home//tests//..//..//..//home//readlink_realpath_variation2_link.tmp/): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d Done diff --git a/ext/standard/tests/file/readlink_realpath_variation2.phpt b/ext/standard/tests/file/readlink_realpath_variation2.phpt index e7d681036e26..02d024d5e973 100644 --- a/ext/standard/tests/file/readlink_realpath_variation2.phpt +++ b/ext/standard/tests/file/readlink_realpath_variation2.phpt @@ -77,7 +77,7 @@ Warning: readlink(): No such file or directory in %s on line %d bool(false) bool(false) -Warning: unlink(%s/./readlink_realpath_variation2/home/../home//tests//..//..//..//home//readlink_realpath_variation2_link.tmp/): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- Testing readlink() and realpath() with hardlink, linkname stored inside an array -- bool(true) @@ -93,5 +93,5 @@ Warning: readlink(): No such file or directory in %s on line %d bool(false) bool(false) -Warning: unlink(%s/./readlink_realpath_variation2/home/../home//tests//..//..//..//home//readlink_realpath_variation2_link.tmp/): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d Done diff --git a/ext/standard/tests/file/rename_variation-win32.phpt b/ext/standard/tests/file/rename_variation-win32.phpt index 158a8421ec79..e9614c1f8a4c 100644 --- a/ext/standard/tests/file/rename_variation-win32.phpt +++ b/ext/standard/tests/file/rename_variation-win32.phpt @@ -66,7 +66,7 @@ bool(false) bool(false) bool(false) -Warning: unlink(%s/rename_variation2.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- Iteration 3 -- bool(true) bool(false) diff --git a/ext/standard/tests/file/rename_variation.phpt b/ext/standard/tests/file/rename_variation.phpt index 88ad26080f4a..ce50e98d89f0 100644 --- a/ext/standard/tests/file/rename_variation.phpt +++ b/ext/standard/tests/file/rename_variation.phpt @@ -60,7 +60,7 @@ bool(false) bool(false) bool(false) -Warning: unlink(%s): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- Iteration 3 -- bool(true) bool(false) diff --git a/ext/standard/tests/file/rmdir_variation3-win32.phpt b/ext/standard/tests/file/rmdir_variation3-win32.phpt index 7a478b8a5cfa..4f39ae5caf4d 100644 --- a/ext/standard/tests/file/rmdir_variation3-win32.phpt +++ b/ext/standard/tests/file/rmdir_variation3-win32.phpt @@ -75,10 +75,10 @@ Directory removed Directory removed -- removing rmdirVar3.tmp\..\BADDIR\aSubDir -- -Warning: rmdir(rmdirVar3.tmp\..\BADDIR\aSubDir): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d -- removing BADDIR\aSubDir -- -Warning: rmdir(BADDIR\aSubDir): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d -- removing %s\rmdirVar3.tmp\aSubDir -- Directory removed -- removing %s\.\rmdirVar3.tmp\aSubDir -- @@ -87,7 +87,7 @@ Directory removed Directory removed -- removing %s\BADDIR\aSubDir -- -Warning: rmdir(%s\BADDIR\aSubDir): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d -- removing rmdirVar3.tmp\aSubDir\ -- Directory removed -- removing %s\rmdirVar3.tmp\aSubDir\ -- diff --git a/ext/standard/tests/file/rmdir_variation3.phpt b/ext/standard/tests/file/rmdir_variation3.phpt index efd66c8bdfd4..3e8cea123805 100644 --- a/ext/standard/tests/file/rmdir_variation3.phpt +++ b/ext/standard/tests/file/rmdir_variation3.phpt @@ -65,10 +65,10 @@ Directory removed Directory removed -- removing rmdirVar3.tmp/../BADDIR/aSubDir -- -Warning: rmdir(rmdirVar3.tmp/../BADDIR/aSubDir): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d -- removing BADDIR/aSubDir -- -Warning: rmdir(BADDIR/aSubDir): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d -- removing %s/rmdirVar3.tmp/aSubDir -- Directory removed -- removing %s/./rmdirVar3.tmp/aSubDir -- @@ -77,7 +77,7 @@ Directory removed Directory removed -- removing %s/BADDIR/aSubDir -- -Warning: rmdir(%s/BADDIR/aSubDir): No such file or directory in %s on line %d +Warning: rmdir(): No such file or directory in %s on line %d -- removing rmdirVar3.tmp/aSubDir/ -- Directory removed -- removing %s/rmdirVar3.tmp/aSubDir/ -- diff --git a/ext/standard/tests/file/unlink_error-win32-mb.phpt b/ext/standard/tests/file/unlink_error-win32-mb.phpt index df98e2e36735..a62114fe7dab 100644 --- a/ext/standard/tests/file/unlink_error-win32-mb.phpt +++ b/ext/standard/tests/file/unlink_error-win32-mb.phpt @@ -65,11 +65,11 @@ bool(false) -- Testing unlink() on non-existent file -- -Warning: unlink(%s/non_existent_file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d bool(false) -- Testing unlink() on directory -- -Warning: unlink(%s/unlink_error): Is a directory in %s on line %d +Warning: unlink(): Is a directory in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_error-win32.phpt b/ext/standard/tests/file/unlink_error-win32.phpt index 6bce3d4b8060..1e4500d2b7e8 100644 --- a/ext/standard/tests/file/unlink_error-win32.phpt +++ b/ext/standard/tests/file/unlink_error-win32.phpt @@ -62,11 +62,11 @@ bool(false) -- Testing unlink() on non-existent file -- -Warning: unlink(%s/non_existent_file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d bool(false) -- Testing unlink() on directory -- -Warning: unlink(%s/unlink_error): Is a directory in %s on line %d +Warning: unlink(): Is a directory in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_error.phpt b/ext/standard/tests/file/unlink_error.phpt index 1dd8ef1a25c9..8174f1b01268 100644 --- a/ext/standard/tests/file/unlink_error.phpt +++ b/ext/standard/tests/file/unlink_error.phpt @@ -61,11 +61,11 @@ bool(false) -- Testing unlink() on non-existent file -- -Warning: unlink(%s/non_existent_file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d bool(false) -- Testing unlink() on directory -- -Warning: unlink(%s/unlink_error): %s in %s on line %d +Warning: unlink(): %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_variation1-win32-mb.phpt b/ext/standard/tests/file/unlink_variation1-win32-mb.phpt index 8d2a80726a67..37132d13d63a 100644 --- a/ext/standard/tests/file/unlink_variation1-win32-mb.phpt +++ b/ext/standard/tests/file/unlink_variation1-win32-mb.phpt @@ -77,7 +77,7 @@ bool(true) -- Unlinking file without write permission, its dir having default permission -- bool(true) -Warning: unlink(%s/unlink_variation1/unlink_variation1-win32.tmp): Permission denied in %s on line %d +Warning: unlink(): Permission denied in %s on line %d bool(false) bool(true) bool(false) diff --git a/ext/standard/tests/file/unlink_variation1-win32.phpt b/ext/standard/tests/file/unlink_variation1-win32.phpt index 813e4a2e77fc..c6a0f8804a38 100644 --- a/ext/standard/tests/file/unlink_variation1-win32.phpt +++ b/ext/standard/tests/file/unlink_variation1-win32.phpt @@ -75,7 +75,7 @@ bool(true) -- Unlinking file without write permission, its dir having default permission -- bool(true) -Warning: unlink(%s/unlink_variation1/unlink_variation1-win32.tmp): Permission denied in %s on line %d +Warning: unlink(): Permission denied in %s on line %d bool(false) bool(true) bool(false) diff --git a/ext/standard/tests/file/unlink_variation1.phpt b/ext/standard/tests/file/unlink_variation1.phpt index eafdf92f1f06..5f6320b60651 100644 --- a/ext/standard/tests/file/unlink_variation1.phpt +++ b/ext/standard/tests/file/unlink_variation1.phpt @@ -64,7 +64,7 @@ echo "Done\n"; -- Unlink file having default permission and its dir having read only permission -- bool(true) -Warning: unlink(%s): %s in %s on line %d +Warning: unlink(): %s in %s on line %d bool(false) bool(false) bool(true) diff --git a/ext/standard/tests/file/unlink_variation10.phpt b/ext/standard/tests/file/unlink_variation10.phpt index 127b070d23a2..4a3c8de596fc 100644 --- a/ext/standard/tests/file/unlink_variation10.phpt +++ b/ext/standard/tests/file/unlink_variation10.phpt @@ -95,4 +95,4 @@ directory unlinked --- try to unlink a directory --- -Warning: unlink(unlinkVar10.tmp/linkme.tmp): %s in %s on line %d +Warning: unlink(): %s in %s on line %d diff --git a/ext/standard/tests/file/unlink_variation4.phpt b/ext/standard/tests/file/unlink_variation4.phpt index 99dd0c632dbb..193d50821abd 100644 --- a/ext/standard/tests/file/unlink_variation4.phpt +++ b/ext/standard/tests/file/unlink_variation4.phpt @@ -29,6 +29,6 @@ echo "Done\n"; bool(true) bool(false) -Warning: unlink(%s/unlink_variation4.tmp): %s in %s on line %d +Warning: unlink(): %s in %s on line %d bool(false) Done diff --git a/ext/standard/tests/file/unlink_variation8-win32.phpt b/ext/standard/tests/file/unlink_variation8-win32.phpt index 016beddce1c1..1a9afcae7ff2 100644 --- a/ext/standard/tests/file/unlink_variation8-win32.phpt +++ b/ext/standard/tests/file/unlink_variation8-win32.phpt @@ -80,10 +80,10 @@ file removed file removed -- removing unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing %s/unlinkVar8.tmp/file.tmp -- file removed -- removing %s/./unlinkVar8.tmp/file.tmp -- @@ -92,13 +92,13 @@ file removed file removed -- removing %s/BADDIR/file.tmp -- -Warning: unlink(%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing %s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(%s/unlinkVar8.tmp/file.tmp/): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing unlinkVar8.tmp//file.tmp -- file removed -- removing %s//unlinkVar8.tmp//file.tmp -- diff --git a/ext/standard/tests/file/unlink_variation8.phpt b/ext/standard/tests/file/unlink_variation8.phpt index 71eca9199acd..d79d9e805787 100644 --- a/ext/standard/tests/file/unlink_variation8.phpt +++ b/ext/standard/tests/file/unlink_variation8.phpt @@ -123,22 +123,22 @@ file unlinked file unlinked -- removing unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking soft link unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking hard link unlinkVar8.tmp/../BADDIR/file.tmp -- -Warning: unlink(unlinkVar8.tmp/../BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking soft link BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking hard link BADDIR/file.tmp -- -Warning: unlink(BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing /%s/unlinkVar8.tmp/file.tmp -- file removed -- unlinking soft link /%s/unlinkVar8.tmp/file.tmp -- @@ -159,31 +159,31 @@ file unlinked file unlinked -- removing /%s/BADDIR/file.tmp -- -Warning: unlink(/%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking soft link /%s/BADDIR/file.tmp -- -Warning: unlink(/%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- unlinking hard link /%s/BADDIR/file.tmp -- -Warning: unlink(/%s/BADDIR/file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- unlinking soft link unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): %s directory in %s on line %d +Warning: unlink(): %s directory in %s on line %d -- unlinking hard link unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- removing /%s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(/%s/unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- unlinking soft link /%s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(/%s/unlinkVar8.tmp/file.tmp/): %s directory in %s on line %d +Warning: unlink(): %s directory in %s on line %d -- unlinking hard link /%s/unlinkVar8.tmp/file.tmp/ -- -Warning: unlink(/%s/unlinkVar8.tmp/file.tmp/): Not a directory in %s on line %d +Warning: unlink(): Not a directory in %s on line %d -- removing unlinkVar8.tmp//file.tmp -- file removed -- unlinking soft link unlinkVar8.tmp//file.tmp -- diff --git a/ext/standard/tests/file/unlink_variation9-win32.phpt b/ext/standard/tests/file/unlink_variation9-win32.phpt index 68e11be92763..d5406f99d85f 100644 --- a/ext/standard/tests/file/unlink_variation9-win32.phpt +++ b/ext/standard/tests/file/unlink_variation9-win32.phpt @@ -82,10 +82,10 @@ file removed file removed -- removing unlinkVar9.tmp\..\BADDIR\file.tmp -- -Warning: unlink(unlinkVar9.tmp\..\BADDIR\file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing BADDIR\file.tmp -- -Warning: unlink(BADDIR\file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing %s\unlinkVar9.tmp\file.tmp -- file removed -- removing %s\.\unlinkVar9.tmp\file.tmp -- @@ -94,13 +94,13 @@ file removed file removed -- removing %s\BADDIR\file.tmp -- -Warning: unlink(%s\BADDIR\file.tmp): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d -- removing unlinkVar9.tmp\file.tmp\ -- -Warning: unlink(unlinkVar9.tmp\file.tmp\): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing %s\unlinkVar9.tmp\file.tmp\ -- -Warning: unlink(%s\unlinkVar9.tmp\file.tmp\): %rNo such file or directory|Not a directory%r in %s on line %d +Warning: unlink(): %rNo such file or directory|Not a directory%r in %s on line %d -- removing unlinkVar9.tmp\\file.tmp -- file removed -- removing %s\\unlinkVar9.tmp\\file.tmp -- diff --git a/ext/zlib/tests/gh19922.phpt b/ext/zlib/tests/gh19922.phpt index 71644512e665..a9d76a331310 100644 --- a/ext/zlib/tests/gh19922.phpt +++ b/ext/zlib/tests/gh19922.phpt @@ -7,6 +7,5 @@ zlib var_dump(gzopen("php://output", 14)); ?> --EXPECTF-- - -Warning: gzopen(php://output): could not make seekable - php://output in %s on line %d +Warning: gzopen(): could not make seekable - php://output in %s on line %d bool(false) diff --git a/main/streams/php_stream_errors.h b/main/streams/php_stream_errors.h index 239a34ff870f..438397a24ded 100644 --- a/main/streams/php_stream_errors.h +++ b/main/streams/php_stream_errors.h @@ -130,11 +130,6 @@ PHPAPI void php_stream_wrapper_error(php_stream_wrapper *wrapper, php_stream_con zend_enum_StreamErrorCode code, const char *fmt, ...) ZEND_ATTRIBUTE_FORMAT(printf, 8, 9); -PHPAPI void php_stream_wrapper_error_param(php_stream_wrapper *wrapper, php_stream_context *context, - const char *docref, int options, int severity, bool terminating, - zend_enum_StreamErrorCode code, const char *param, const char *fmt, ...) - ZEND_ATTRIBUTE_FORMAT(printf, 9, 10); - PHPAPI void php_stream_error(php_stream *stream, const char *docref, int severity, bool terminating, zend_enum_StreamErrorCode code, const char *fmt, ...) ZEND_ATTRIBUTE_FORMAT(printf, 6, 7); @@ -145,11 +140,6 @@ PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, zend_enum_StreamErrorCode code, const char *fmt, ...) ZEND_ATTRIBUTE_FORMAT(printf, 7, 8); -PHPAPI void php_stream_wrapper_log_error_param(const php_stream_wrapper *wrapper, - php_stream_context *context, int options, int severity, bool terminating, - zend_enum_StreamErrorCode code, const char *param, const char *fmt, ...) - ZEND_ATTRIBUTE_FORMAT(printf, 8, 9); - PHPAPI void php_stream_display_wrapper_name_errors(const char *wrapper_name, php_stream_context *context, zend_enum_StreamErrorCode code, const char *path, const char *caption); @@ -179,16 +169,6 @@ PHPAPI void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper); php_stream_wrapper_error(wrapper, context, NULL, options, E_NOTICE, false, \ PHP_STREAM_EC(code), __VA_ARGS__) -#define php_stream_wrapper_warn_param(wrapper, context, options, code, param, ...) \ - php_stream_wrapper_error_param( \ - wrapper, context, NULL, options, E_WARNING, true, \ - PHP_STREAM_EC(code), param, __VA_ARGS__) - -#define php_stream_wrapper_warn_param_nt(wrapper, context, options, code, param, ...) \ - php_stream_wrapper_error_param( \ - wrapper, context, NULL, options, E_WARNING, false, \ - PHP_STREAM_EC(code), param, __VA_ARGS__) - #define php_stream_warn(stream, code, ...) \ php_stream_error(stream, NULL, E_WARNING, true, PHP_STREAM_EC(code), __VA_ARGS__) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index a95ca0eab768..9289b6b5ec6e 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -1327,9 +1327,9 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url, if (ret == -1) { if (options & REPORT_ERRORS) { char errstr[256]; - php_stream_wrapper_warn_param(wrapper, context, options, - UnlinkFailed, url, - "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + UnlinkFailed, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); } return 0; } @@ -1572,17 +1572,17 @@ static int php_plain_files_rmdir(php_stream_wrapper *wrapper, const char *url, i char errstr[256]; #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(url, strlen(url))) { - php_stream_wrapper_warn_param(wrapper, context, options, - NotFound, url, - "%s", php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + NotFound, "%s", + php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); return 0; } #endif if (VCWD_RMDIR(url) < 0) { - php_stream_wrapper_warn_param(wrapper, context, options, - RmdirFailed, url, - "%s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, options, + RmdirFailed, "%s", + php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } @@ -1605,9 +1605,9 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url #ifdef PHP_WIN32 if (!php_win32_check_trailing_space(url, strlen(url))) { - php_stream_wrapper_warn_param(wrapper, context, REPORT_ERRORS, - NotFound, url, - "%s", php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + NotFound, "%s", + php_socket_strerror_s(ENOENT, errstr, sizeof(errstr))); return 0; } #endif @@ -1626,8 +1626,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url if (VCWD_ACCESS(url, F_OK) != 0) { FILE *file = VCWD_FOPEN(url, "w"); if (file == NULL) { - php_stream_wrapper_warn_param(wrapper, context, REPORT_ERRORS, - PermissionDenied, url, + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + PermissionDenied, "Unable to create file %s because %s", url, php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; @@ -1642,8 +1642,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url case PHP_STREAM_META_OWNER: if(option == PHP_STREAM_META_OWNER_NAME) { if(php_get_uid_by_name((char *)value, &uid) != SUCCESS) { - php_stream_wrapper_warn_param(wrapper, context, REPORT_ERRORS, - MetaFailed, url, + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + MetaFailed, "Unable to find uid for %s", (char *)value); return 0; } @@ -1656,8 +1656,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url case PHP_STREAM_META_GROUP_NAME: if(option == PHP_STREAM_META_GROUP_NAME) { if(php_get_gid_by_name((char *)value, &gid) != SUCCESS) { - php_stream_wrapper_warn_param(wrapper, context, REPORT_ERRORS, - MetaFailed, url, + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + MetaFailed, "Unable to find gid for %s", (char *)value); return 0; } @@ -1676,8 +1676,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url return 0; } if (ret == -1) { - php_stream_wrapper_warn_param(wrapper, context, REPORT_ERRORS, - MetaFailed, url, + php_stream_wrapper_warn(wrapper, context, REPORT_ERRORS, + MetaFailed, "Operation failed: %s", php_socket_strerror_s(errno, errstr, sizeof(errstr))); return 0; } diff --git a/main/streams/stream_errors.c b/main/streams/stream_errors.c index 3b64e6ba39c5..c70b8f3f53b6 100644 --- a/main/streams/stream_errors.c +++ b/main/streams/stream_errors.c @@ -626,26 +626,6 @@ PHPAPI void php_stream_wrapper_error(php_stream_wrapper *wrapper, php_stream_con wrapper_name, context, docref, options, severity, terminating, code, NULL, message); } -PHPAPI void php_stream_wrapper_error_param(php_stream_wrapper *wrapper, php_stream_context *context, - const char *docref, int options, int severity, bool terminating, - zend_enum_StreamErrorCode code, const char *param, const char *fmt, ...) -{ - if (!(options & REPORT_ERRORS)) { - return; - } - - va_list args; - va_start(args, fmt); - zend_string *message = vstrpprintf(0, fmt, args); - va_end(args); - - const char *wrapper_name = PHP_STREAM_ERROR_WRAPPER_NAME(wrapper); - char *param_copy = param ? estrdup(param) : NULL; - - php_stream_wrapper_error_internal(wrapper_name, context, docref, options, severity, terminating, - code, param_copy, message); -} - /* Stream error reporting */ PHPAPI void php_stream_error(php_stream *stream, const char *docref, int severity, @@ -743,18 +723,6 @@ PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, va_end(args); } -PHPAPI void php_stream_wrapper_log_error_param(const php_stream_wrapper *wrapper, - php_stream_context *context, int options, int severity, bool terminating, - zend_enum_StreamErrorCode code, const char *param, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - char *param_copy = param ? estrdup(param) : NULL; - php_stream_wrapper_log_error_internal( - wrapper, context, options, severity, terminating, code, param_copy, fmt, args); - va_end(args); -} - static zend_llist *php_stream_get_wrapper_errors_list(const char *wrapper_name) { if (!FG(wrapper_logged_errors)) { diff --git a/main/streams/streams.c b/main/streams/streams.c index 2525e4126e88..c3bde0a8b109 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -2304,16 +2304,11 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod default: php_stream_close(stream); stream = NULL; - if (options & REPORT_ERRORS) { - char *tmp = estrdup(path); - php_strip_url_passwd(tmp); - php_stream_wrapper_warn_param(wrapper, context, options, - SeekNotSupported, tmp, - "could not make seekable - %s", tmp); - efree(tmp); - - options &= ~REPORT_ERRORS; - } + php_stream_wrapper_warn(wrapper, context, options, + SeekNotSupported, + "could not make seekable - %s", path); + /* We do not want multiple errors so we negate it */ + options &= ~REPORT_ERRORS; } } diff --git a/tests/security/open_basedir_copy_variation1.phpt b/tests/security/open_basedir_copy_variation1.phpt index e388ad76d782..d6ea27659e85 100644 --- a/tests/security/open_basedir_copy_variation1.phpt +++ b/tests/security/open_basedir_copy_variation1.phpt @@ -28,6 +28,6 @@ bool(true) Warning: copy(): open_basedir restriction in effect. File(../bad/bad.txt) is not within the allowed path(s): (.) in %s on line %d bool(false) -Warning: unlink(copy.txt): No such file or directory in %s on line %d +Warning: unlink(): No such file or directory in %s on line %d bool(false) *** Finished testing open_basedir configuration [copy] *** From b06eb82fef8de522fb89dada626127c34039499c Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Jul 2026 18:31:27 +0100 Subject: [PATCH 7/8] streams: embed php_stream_wrapper_log_error_internal() As it now only has a single usage --- main/streams/stream_errors.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/main/streams/stream_errors.c b/main/streams/stream_errors.c index c70b8f3f53b6..e7d964e999f3 100644 --- a/main/streams/stream_errors.c +++ b/main/streams/stream_errors.c @@ -696,30 +696,22 @@ static void php_stream_wrapper_log_store_error(zend_string *message, zend_enum_S zend_llist_add_element(list, &entry); } -static void php_stream_wrapper_log_error_internal(const php_stream_wrapper *wrapper, +PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, php_stream_context *context, int options, int severity, bool terminating, - zend_enum_StreamErrorCode code, char *param, const char *fmt, va_list args) + zend_enum_StreamErrorCode code, const char *fmt, ...) { + va_list args; + va_start(args, fmt); zend_string *message = vstrpprintf(0, fmt, args); const char *wrapper_name = PHP_STREAM_ERROR_WRAPPER_NAME(wrapper); if (options & REPORT_ERRORS) { php_stream_wrapper_error_internal( - wrapper_name, context, NULL, options, severity, terminating, code, param, message); + wrapper_name, context, NULL, options, severity, terminating, code, NULL, message); } else { php_stream_wrapper_log_store_error( - message, code, wrapper_name, param, severity, terminating); + message, code, wrapper_name, NULL, severity, terminating); } -} - -PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, - php_stream_context *context, int options, int severity, bool terminating, - zend_enum_StreamErrorCode code, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - php_stream_wrapper_log_error_internal( - wrapper, context, options, severity, terminating, code, NULL, fmt, args); va_end(args); } From dec19edc4badf33e55b1346711efebf789d9fe92 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Thu, 16 Jul 2026 18:32:13 +0100 Subject: [PATCH 8/8] streams: remove 'param' parameter of php_stream_wrapper_log_store_error() It's always NULL --- main/streams/stream_errors.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/main/streams/stream_errors.c b/main/streams/stream_errors.c index e7d964e999f3..70c06b70182a 100644 --- a/main/streams/stream_errors.c +++ b/main/streams/stream_errors.c @@ -665,15 +665,13 @@ static void php_stream_error_list_dtor(zval *item) } static void php_stream_wrapper_log_store_error(zend_string *message, zend_enum_StreamErrorCode code, - const char *wrapper_name, const char *param, int severity, bool terminating) + const char *wrapper_name, int severity, bool terminating) { - char *param_copy = param ? estrdup(param) : NULL; - php_stream_error_entry *entry = ecalloc(1, sizeof(php_stream_error_entry)); entry->message = message; entry->code = code; entry->wrapper_name = wrapper_name ? estrdup(wrapper_name) : NULL; - entry->param = param_copy; + entry->param = NULL; entry->severity = severity; entry->terminating = terminating; @@ -710,7 +708,7 @@ PHPAPI void php_stream_wrapper_log_error(const php_stream_wrapper *wrapper, wrapper_name, context, NULL, options, severity, terminating, code, NULL, message); } else { php_stream_wrapper_log_store_error( - message, code, wrapper_name, NULL, severity, terminating); + message, code, wrapper_name, severity, terminating); } va_end(args); }