summaryrefslogtreecommitdiff
path: root/lib/ftp.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2023-02-23 00:29:47 +0100
committerDaniel Stenberg <daniel@haxx.se>2023-02-24 16:43:15 +0100
commitb0f54f27a95b2ad70d5c54b576cc85c13783b8c1 (patch)
treec07fabd02191d4cfc81e0fc5e9228573d0c60b6b /lib/ftp.c
parentf6fe54e21edfb343a746c017e646669bbb1a105a (diff)
downloadcurl-b0f54f27a95b2ad70d5c54b576cc85c13783b8c1.tar.gz
ftp: make the EPSV response parser not use sscanf
Closes #10590
Diffstat (limited to 'lib/ftp.c')
-rw-r--r--lib/ftp.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 7766f76c7..4d8eadb2f 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1814,27 +1814,18 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
/* positive EPSV response */
char *ptr = strchr(str, '(');
if(ptr) {
- unsigned int num;
- char separator[4];
+ char sep;
ptr++;
- if(5 == sscanf(ptr, "%c%c%c%u%c",
- &separator[0],
- &separator[1],
- &separator[2],
- &num,
- &separator[3])) {
- const char sep1 = separator[0];
- int i;
-
- /* The four separators should be identical, or else this is an oddly
- formatted reply and we bail out immediately. */
- for(i = 1; i<4; i++) {
- if(separator[i] != sep1) {
- ptr = NULL; /* set to NULL to signal error */
- break;
- }
- }
- if(num > 0xffff) {
+ /* |||12345| */
+ sep = ptr[0];
+ /* the ISDIGIT() check here is because strtoul() accepts leading minus
+ etc */
+ if((ptr[1] == sep) && (ptr[2] == sep) && ISDIGIT(ptr[3])) {
+ char *endp;
+ unsigned long num = strtoul(&ptr[3], &endp, 10);
+ if(*endp != sep)
+ ptr = NULL;
+ else if(num > 0xffff) {
failf(data, "Illegal port number in EPSV reply");
return CURLE_FTP_WEIRD_PASV_REPLY;
}