From ff50fe0348466cae1a9f9f759b362c03f7060c34 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 14 Aug 2017 23:33:23 +0200 Subject: strtoofft: reduce integer overflow risks globally ... make sure we bail out on overflows. Reported-by: Brian Carpenter Closes #1758 --- lib/ftp.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'lib/ftp.c') diff --git a/lib/ftp.c b/lib/ftp.c index 6e86e5386..481b14a88 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -2260,11 +2260,13 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn, { CURLcode result = CURLE_OK; struct Curl_easy *data=conn->data; - curl_off_t filesize; + curl_off_t filesize = -1; char *buf = data->state.buffer; /* get the size from the ascii string: */ - filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1; + if(ftpcode == 213) + /* ignores parsing errors, which will make the size remain unknown */ + (void)curlx_strtoofft(buf+4, NULL, 0, &filesize); if(instate == FTP_SIZE) { #ifdef CURL_FTP_HTTPSTYLE_HEAD @@ -2435,7 +2437,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn, /* if we have nothing but digits: */ if(bytes++) { /* get the number! */ - size = curlx_strtoofft(bytes, NULL, 0); + (void)curlx_strtoofft(bytes, NULL, 0, &size); } } } @@ -3466,31 +3468,32 @@ static CURLcode ftp_range(struct connectdata *conn) { curl_off_t from, to; char *ptr; - char *ptr2; struct Curl_easy *data = conn->data; struct ftp_conn *ftpc = &conn->proto.ftpc; if(data->state.use_range && data->state.range) { - from=curlx_strtoofft(data->state.range, &ptr, 0); + CURLofft from_t; + CURLofft to_t; + from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); + if(from_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; while(*ptr && (ISSPACE(*ptr) || (*ptr=='-'))) ptr++; - to=curlx_strtoofft(ptr, &ptr2, 0); - if(ptr == ptr2) { - /* we didn't get any digit */ - to=-1; - } - if((-1 == to) && (from>=0)) { + to_t = curlx_strtoofft(ptr, NULL, 0, &to); + if(to_t == CURL_OFFT_FLOW) + return CURLE_RANGE_ERROR; + if((to_t == CURL_OFFT_INVAL) && !from_t) { /* X - */ data->state.resume_from = from; DEBUGF(infof(conn->data, "FTP RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n", from)); } - else if(from < 0) { + else if(!to_t && (from_t == CURL_OFFT_INVAL)) { /* -Y */ - data->req.maxdownload = -from; - data->state.resume_from = from; + data->req.maxdownload = to; + data->state.resume_from = -to; DEBUGF(infof(conn->data, "FTP RANGE the last %" CURL_FORMAT_CURL_OFF_T - " bytes\n", -from)); + " bytes\n", to)); } else { /* X-Y */ -- cgit v1.2.3