From 95c7e08c248fef2125d4f03dc4b15d7ac69f7745 Mon Sep 17 00:00:00 2001 From: transcendtient Date: Fri, 28 Aug 2026 15:32:23 -0500 Subject: [PATCH] Fix SFTP path corruption for root-path URLs strstr() can match resource->path against the "://" scheme separator instead of the actual path when the path is short (e.g. "/"), corrupting ssh2.sftp:/// URLs used for directory listings. Only run the search when # or ? is present, since that's the only case it's needed for. See https://github.com/php/pecl-networking-ssh2/issues/99 --- ssh2_fopen_wrappers.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ssh2_fopen_wrappers.c b/ssh2_fopen_wrappers.c index f1b3ce1..3e3c744 100644 --- a/ssh2_fopen_wrappers.c +++ b/ssh2_fopen_wrappers.c @@ -280,9 +280,15 @@ php_url *php_ssh2_fopen_wrapper_parse_path(const char *path, char *type, php_str Find resource->path in the original path string, then copy from that position to the end. This preserves ?query and #fragment (e.g. filenames containing '#') which php_url_parse() strips from resource->path. + Only search if # or ? is present, since a plain strstr() can otherwise + match resource->path against the "://" scheme separator (e.g. a root + path of "/" matching inside "ssh2.sftp:///"). */ { - const char *path_in_original = strstr(path, ZSTR_VAL(resource->path)); + const char *path_in_original = NULL; + if (strpbrk(path, "#?") != NULL) { + path_in_original = strstr(path, ZSTR_VAL(resource->path)); + } if (path_in_original) { zend_string_release(resource->path); resource->path = zend_string_init(path_in_original, strlen(path_in_original), 0);