tool_operhlp: iterate through all slashes to find name

If there is no trailing file name for -O or --remote-name-all, continue
searching until there is no more to search. A URL ending with multiple
slashes would previously make it do wrong.

Add test 1639 and 1644 to verify.

Follow-up to e26eefd9ce

Reported-by: James Fuller

Closes #21165
This commit is contained in:
Daniel Stenberg 2026-03-30 23:34:14 +02:00
parent bae6237c45
commit 8e89646a3d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 136 additions and 7 deletions

View File

@ -198,19 +198,19 @@ CURLcode get_url_file_name(char **filename, const char *url, SANITIZEcode *sc)
curl_url_cleanup(uh);
uh = NULL;
if(!uerr) {
int i;
char *pc = NULL, *pc2 = NULL;
for(i = 0; i < 2; i++) {
do {
pc = strrchr(path, '/');
pc2 = strrchr(pc ? pc + 1 : path, '\\');
if(pc2)
pc = pc2;
if(pc && !pc[1] && !i) {
if(pc && !pc[1])
/* if the path ends with slash, try removing the trailing one
and get the last directory part */
*pc = 0;
}
}
else
break;
} while(1);
if(pc) {
/* duplicate the string beyond the slash */

View File

@ -217,8 +217,7 @@ test1614 test1615 test1616 test1617 test1618 test1619 test1620 test1621 \
test1622 test1623 test1624 test1625 test1626 test1627 \
\
test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 \
test1638 \
test1640 test1641 test1642 test1643 \
test1638 test1639 test1640 test1641 test1642 test1643 test1644 \
\
test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 \
test1658 test1659 test1660 test1661 test1662 test1663 test1664 test1665 \

65
tests/data/test1639 Normal file
View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="US-ASCII"?>
<testcase>
<info>
<keywords>
HTTP
HTTP GET
</keywords>
</info>
# Server-side
<reply>
<data crlf="headers" nocheck="yes">
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
</reply>
# Client-side
<client>
<server>
http
</server>
<name>
-O with URL without path using many trailing slashes
</name>
<command option="no-output">
http://%HOSTIP:%HTTPPORT///////////////// -O --output-dir %LOGDIR
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol crlf="headers">
GET ///////////////// HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="%LOGDIR/curl_response" crlf="headers">
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</file>
</verify>
</testcase>

65
tests/data/test1644 Normal file
View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="US-ASCII"?>
<testcase>
<info>
<keywords>
HTTP
HTTP GET
</keywords>
</info>
# Server-side
<reply>
<data crlf="headers" nocheck="yes">
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</data>
</reply>
# Client-side
<client>
<server>
http
</server>
<name>
-O with URL with path but using many trailing slashes
</name>
<command option="no-output">
http://%HOSTIP:%HTTPPORT///foo////////////// -O --output-dir %LOGDIR
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<protocol crlf="headers">
GET ///foo////////////// HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file name="%LOGDIR/foo" crlf="headers">
HTTP/1.1 200 OK
Date: Tue, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes
-foo-
</file>
</verify>
</testcase>