From b0f54f27a95b2ad70d5c54b576cc85c13783b8c1 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 23 Feb 2023 00:29:47 +0100 Subject: [PATCH] ftp: make the EPSV response parser not use sscanf Closes #10590 --- lib/ftp.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/lib/ftp.c b/lib/ftp.c index 7766f76c70..4d8eadb2fe 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; }