From be852e39b25a4abbb7e5ecbe89d72f410ccfb3a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 15 Oct 2025 08:42:20 +0200 Subject: [PATCH] tftp: check for trailing ";mode=" in URL without strstr RFC 3617 defines two specific modes, "netascii" and "octet". This code now checks only for those trailing ones - and not in the hostname since they can't be there anymore. Assisted-by: Jay Satiro Closes #19070 --- docs/cmdline-opts/use-ascii.md | 9 +++++---- lib/tftp.c | 36 ++++++++++------------------------ src/tool_listhelp.c | 2 +- tests/data/test1093 | 4 ++-- 4 files changed, 18 insertions(+), 33 deletions(-) diff --git a/docs/cmdline-opts/use-ascii.md b/docs/cmdline-opts/use-ascii.md index 30cc860b0a..4dba446ffe 100644 --- a/docs/cmdline-opts/use-ascii.md +++ b/docs/cmdline-opts/use-ascii.md @@ -4,8 +4,8 @@ SPDX-License-Identifier: curl Short: B Long: use-ascii Help: Use ASCII/text transfer -Protocols: FTP LDAP -Category: ftp output ldap +Protocols: FTP LDAP TFTP +Category: ftp output ldap tftp Added: 5.0 Multi: boolean See-also: @@ -18,5 +18,6 @@ Example: # `--use-ascii` Enable ASCII transfer mode. For FTP, this can also be enforced by using a URL -that ends with `;type=A`. This option causes data sent to stdout to be in text -mode for Win32 systems. +that ends with `;type=A`. For TFTP, this can also be enforced by using a URL +that ends with `;mode=netascii`. This option causes data sent to stdout to be +in text mode for Win32 systems. diff --git a/lib/tftp.c b/lib/tftp.c index 0a9b8a8e87..d9d978c24e 100644 --- a/lib/tftp.c +++ b/lib/tftp.c @@ -1379,35 +1379,19 @@ static CURLcode tftp_do(struct Curl_easy *data, bool *done) static CURLcode tftp_setup_connection(struct Curl_easy *data, struct connectdata *conn) { - char *type; + char *path = data->state.up.path; + size_t len = strlen(path); conn->transport_wanted = TRNSPRT_UDP; - /* TFTP URLs support an extension like ";mode=" that - * we will try to get now! */ - type = strstr(data->state.up.path, ";mode="); - - if(!type) - type = strstr(conn->host.rawalloc, ";mode="); - - if(type) { - char command; - *type = 0; /* it was in the middle of the hostname */ - command = Curl_raw_toupper(type[6]); - - switch(command) { - case 'A': /* ASCII mode */ - case 'N': /* NETASCII mode */ - data->state.prefer_ascii = TRUE; - break; - - case 'O': /* octet mode */ - case 'I': /* binary mode */ - default: - /* switch off ASCII */ - data->state.prefer_ascii = FALSE; - break; - } + /* TFTP URLs support a trailing ";mode=netascii" or ";mode=octet" */ + if((len >= 14) && !memcmp(&path[len - 14], ";mode=netascii", 14)) { + data->state.prefer_ascii = TRUE; + path[len - 14] = 0; /* cut it there */ + } + else if((len >= 11) && !memcmp(&path[len - 11], ";mode=octet", 11)) { + data->state.prefer_ascii = FALSE; + path[len - 11] = 0; /* cut it there */ } return CURLE_OK; diff --git a/src/tool_listhelp.c b/src/tool_listhelp.c index c8e31e77a6..21019c7de1 100644 --- a/src/tool_listhelp.c +++ b/src/tool_listhelp.c @@ -834,7 +834,7 @@ const struct helptxt helptext[] = { CURLHELP_HTTP | CURLHELP_POST | CURLHELP_UPLOAD}, {"-B, --use-ascii", "Use ASCII/text transfer", - CURLHELP_FTP | CURLHELP_OUTPUT | CURLHELP_LDAP}, + CURLHELP_FTP | CURLHELP_OUTPUT | CURLHELP_LDAP | CURLHELP_TFTP}, {"-u, --user ", "Server user and password", CURLHELP_IMPORTANT | CURLHELP_AUTH}, diff --git a/tests/data/test1093 b/tests/data/test1093 index 1bed99bec1..a135876ae0 100644 --- a/tests/data/test1093 +++ b/tests/data/test1093 @@ -25,10 +25,10 @@ returned tftp -TFTP retrieve with mode=i +TFTP retrieve with mode=octet -"tftp://%HOSTIP:%TFTPPORT//%TESTNUMBER;mode=i" --use-ascii +"tftp://%HOSTIP:%TFTPPORT//%TESTNUMBER;mode=octet" --use-ascii -- 2.47.3