From 5f805eec1149c218145097ec2a24ac7fb7d46f25 Mon Sep 17 00:00:00 2001
From: Dan Fandrich <dan@coneharvesters.com>
Date: Fri, 6 Jun 2025 10:21:09 -0700
Subject: [PATCH] tool_getparam: fix --ftp-pasv

This boolean option was moved to the wrong handling function. Make it
an ARG_NONE and move it to the correct handler and add a test to
verify that the option works.

Follow-up to 698491f44

Reported-by: fjaell on github
Fixes #17545
Closes #17547
---
 docs/cmdline-opts/ftp-pasv.md |  3 +-
 src/tool_getparam.c           |  8 ++---
 tests/data/Makefile.am        |  2 +-
 tests/data/test1547           | 59 +++++++++++++++++++++++++++++++++++
 4 files changed, 66 insertions(+), 6 deletions(-)
 create mode 100644 tests/data/test1547

diff --git a/docs/cmdline-opts/ftp-pasv.md b/docs/cmdline-opts/ftp-pasv.md
index 964f9769ae59..02deee30ded8 100644
--- a/docs/cmdline-opts/ftp-pasv.md
+++ b/docs/cmdline-opts/ftp-pasv.md
@@ -6,7 +6,8 @@ Help: Send PASV/EPSV instead of PORT
 Protocols: FTP
 Added: 7.11.0
 Category: ftp
-Multi: boolean
+Multi: mutex
+Mutexed: ftp-port
 See-also:
   - disable-epsv
 Example:
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 51156e46b97e..6d7020987d0a 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -153,7 +153,7 @@ static const struct LongShort aliases[]= {
   {"ftp-alternative-to-user",    ARG_STRG, ' ', C_FTP_ALTERNATIVE_TO_USER},
   {"ftp-create-dirs",            ARG_BOOL, ' ', C_FTP_CREATE_DIRS},
   {"ftp-method",                 ARG_STRG, ' ', C_FTP_METHOD},
-  {"ftp-pasv",                   ARG_BOOL, ' ', C_FTP_PASV},
+  {"ftp-pasv",                   ARG_NONE, ' ', C_FTP_PASV},
   {"ftp-port",                   ARG_STRG, 'P', C_FTP_PORT},
   {"ftp-pret",                   ARG_BOOL, ' ', C_FTP_PRET},
   {"ftp-skip-pasv-ip",           ARG_BOOL, ' ', C_FTP_SKIP_PASV_IP},
@@ -1703,6 +1703,9 @@ static ParameterError opt_none(struct GlobalConfig *global,
     break;
   case C_DUMP_CA_EMBED: /* --dump-ca-embed */
     return PARAM_CA_EMBED_REQUESTED;
+  case C_FTP_PASV: /* --ftp-pasv */
+    tool_safefree(config->ftpport);
+    break;
 
   case C_HTTP1_0: /* --http1.0 */
     /* HTTP version 1.0 */
@@ -2293,9 +2296,6 @@ static ParameterError opt_filestring(struct GlobalConfig *global,
   case C_URL: /* --url */
     err = parse_url(global, config, nextarg);
     break;
-  case C_FTP_PASV: /* --ftp-pasv */
-    tool_safefree(config->ftpport);
-    break;
   case C_SOCKS5: /* --socks5 */
     /*  socks5 proxy to use, and resolves the name locally and passes on the
         resolved address */
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 1ef85cd3a2da..446674605835 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -203,7 +203,7 @@ test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
 test1516 test1517 test1518 test1519 test1520 test1521 test1522 test1523 \
 test1524 test1525 test1526 test1527 test1528 test1529 test1530 test1531 \
 test1532 test1533 test1534 test1535 test1536 test1537 test1538 test1539 \
-test1540 test1541 test1542 test1543 test1544 test1545 test1546 \
+test1540 test1541 test1542 test1543 test1544 test1545 test1546 test1547 \
 \
 test1550 test1551 test1552 test1553 test1554 test1555 test1556 test1557 \
 test1558 test1559 test1560 test1561 test1562 test1563 test1564 test1565 \
diff --git a/tests/data/test1547 b/tests/data/test1547
new file mode 100644
index 000000000000..244151a5abd1
--- /dev/null
+++ b/tests/data/test1547
@@ -0,0 +1,59 @@
+<testcase>
+# Based on test100 & test101
+<info>
+<keywords>
+FTP
+PASV
+LIST
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data mode="text">
+total 20
+drwxr-xr-x   8 98       98           512 Oct 22 13:06 .
+drwxr-xr-x   8 98       98           512 Oct 22 13:06 ..
+drwxr-xr-x   2 98       98           512 May  2  1996 curl-releases
+-r--r--r--   1 0        1             35 Jul 16  1996 README
+lrwxrwxrwx   1 0        1              7 Dec  9  1999 bin -> usr/bin
+dr-xr-xr-x   2 0        1            512 Oct  1  1997 dev
+drwxrwxrwx   2 98       98           512 May 29 16:04 download.html
+dr-xr-xr-x   2 0        1            512 Nov 30  1995 etc
+drwxrwxrwx   2 98       1            512 Oct 30 14:33 pub
+dr-xr-xr-x   5 0        1            512 Oct  1  1997 usr
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+ftp
+</server>
+<name>
+FTP dir list PASV overriding PORT
+</name>
+<command>
+ftp://%HOSTIP:%FTPPORT/test-%TESTNUMBER/ -P %CLIENTIP --ftp-pasv
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+QUIT
+</strip>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+CWD test-%TESTNUMBER
+EPSV
+TYPE A
+LIST
+QUIT
+</protocol>
+</verify>
+</testcase>
