diff options
author | Daniel Stenberg <daniel@haxx.se> | 2009-08-21 12:01:36 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2009-08-21 12:01:36 +0000 |
commit | 8b5102ca835d73d5cc633f1e7b8d05b3a8082f61 (patch) | |
tree | 0fd77ac2f297a551ff7c6b93298e944f2cd6bbbf /lib | |
parent | 1048043963d5487ed4d70f426a85aff07c2ee5f1 (diff) |
- Andre Guibert de Bruet pointed out a missing return code check for a
strdup() that could lead to segfault if it returned NULL. I extended his
suggest patch to now have Curl_retry_request() return a regular return code
and better check that.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/multi.c | 19 | ||||
-rw-r--r-- | lib/transfer.c | 24 | ||||
-rw-r--r-- | lib/transfer.h | 4 |
3 files changed, 33 insertions, 14 deletions
diff --git a/lib/multi.c b/lib/multi.c index 1099b525d..686372ad1 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1183,7 +1183,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, char *newurl; followtype follow=FOLLOW_NONE; CURLcode drc; - bool retry = Curl_retry_request(easy->easy_conn, &newurl); + bool retry = FALSE; + + drc = Curl_retry_request(easy->easy_conn, &newurl); + if(drc) { + /* a failure here pretty much implies an out of memory */ + easy->result = drc; + disconnect_conn = TRUE; + } + else + retry = newurl?TRUE:FALSE; Curl_posttransfer(easy->easy_handle); drc = Curl_done(&easy->easy_conn, easy->result, FALSE); @@ -1370,9 +1379,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else if(TRUE == done) { char *newurl; - bool retry = Curl_retry_request(easy->easy_conn, &newurl); + bool retry = FALSE; followtype follow=FOLLOW_NONE; + easy->result = Curl_retry_request(easy->easy_conn, &newurl); + if(!easy->result) + retry = newurl?TRUE:FALSE; + /* call this even if the readwrite function returned error */ Curl_posttransfer(easy->easy_handle); @@ -1406,7 +1419,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, multistate(easy, CURLM_STATE_CONNECT); result = CURLM_CALL_MULTI_PERFORM; } - else + else if(newurl) /* Since we "took it", we are in charge of freeing this on failure */ free(newurl); diff --git a/lib/transfer.c b/lib/transfer.c index e5ba279d0..5bd742f47 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -2550,19 +2550,20 @@ Curl_reconnect_request(struct connectdata **connp) return result; } -/* Returns TRUE and sets '*url' if a request retry is wanted. +/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted. NOTE: that the *url is malloc()ed. */ -bool Curl_retry_request(struct connectdata *conn, - char **url) +CURLcode Curl_retry_request(struct connectdata *conn, + char **url) { - bool retry = FALSE; struct SessionHandle *data = conn->data; + *url = NULL; + /* if we're talking upload, we can't do the checks below, unless the protocol is HTTP as when uploading over HTTP we will still get a response */ if(data->set.upload && !(conn->protocol&PROT_HTTP)) - return retry; + return CURLE_OK; if((data->req.bytecount + data->req.headerbytecount == 0) && @@ -2574,6 +2575,8 @@ bool Curl_retry_request(struct connectdata *conn, it again. Bad luck. Retry the same request on a fresh connect! */ infof(conn->data, "Connection died, retrying a fresh connect\n"); *url = strdup(conn->data->change.url); + if(!*url) + return CURLE_OUT_OF_MEMORY; conn->bits.close = TRUE; /* close this connection */ conn->bits.retry = TRUE; /* mark this as a connection we're about @@ -2581,10 +2584,8 @@ bool Curl_retry_request(struct connectdata *conn, prevent i.e HTTP transfers to return error just because nothing has been transfered! */ - retry = TRUE; } - - return retry; + return CURLE_OK; } /* @@ -2629,7 +2630,12 @@ CURLcode Curl_perform(struct SessionHandle *data) if(res == CURLE_OK) { res = Transfer(conn); /* now fetch that URL please */ if((res == CURLE_OK) || (res == CURLE_RECV_ERROR)) { - bool retry = Curl_retry_request(conn, &newurl); + bool retry = FALSE; + CURLcode rc = Curl_retry_request(conn, &newurl); + if(rc) + res = rc; + else + retry = newurl?TRUE:FALSE; if(retry) { res = CURLE_OK; diff --git a/lib/transfer.h b/lib/transfer.h index 4b39faa18..a9b1cd370 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -47,7 +47,7 @@ int Curl_single_getsock(const struct connectdata *conn, CURLcode Curl_readrewind(struct connectdata *conn); CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp); CURLcode Curl_reconnect_request(struct connectdata **connp); -bool Curl_retry_request(struct connectdata *conn, char **url); +CURLcode Curl_retry_request(struct connectdata *conn, char **url); /* This sets up a forthcoming transfer */ CURLcode |