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
This commit is contained in:
Daniel Stenberg 2025-10-15 08:42:20 +02:00
parent 5ac3541cb4
commit be852e39b2
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 18 additions and 33 deletions

View file

@ -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.

View file

@ -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=<typecode>" 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;

View file

@ -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 <user:password>",
"Server user and password",
CURLHELP_IMPORTANT | CURLHELP_AUTH},

View file

@ -25,10 +25,10 @@ returned
tftp
</server>
<name>
TFTP retrieve with mode=i
TFTP retrieve with mode=octet
</name>
<command>
"tftp://%HOSTIP:%TFTPPORT//%TESTNUMBER;mode=i" --use-ascii
"tftp://%HOSTIP:%TFTPPORT//%TESTNUMBER;mode=octet" --use-ascii
</command>
</client>