Loading CHANGES +5 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,11 @@ Changelog Daniel Stenberg (21 Aug 2009) - 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. - Lots of good work by Krister Johansen, mostly related to pipelining: Fix SIGSEGV on free'd easy_conn when pipe unexpectedly breaks Loading RELEASE-NOTES +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ This release includes the following bugfixes: o SIGSEGV when pipelined pipe unexpectedly breaks o data corruption issue with re-connected transfers o use after free if we're completed but easy_conn not NULL (pipelined) o missing strdup() return code check This release includes the following known bugs: Loading @@ -26,6 +27,6 @@ This release includes the following known bugs: This release would not have looked like this without help, code, reports and advice from friends like these: Karl Moerder, Kamil Dudka, Krister Johansen, Karl Moerder, Kamil Dudka, Krister Johansen, Andre Guibert de Bruet Thanks! (and sorry if I forgot to mention someone) lib/multi.c +16 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading lib/transfer.c +15 −9 Original line number Diff line number Diff line Loading @@ -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, 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) && Loading @@ -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 Loading @@ -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; } /* Loading Loading @@ -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; Loading lib/transfer.h +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading
CHANGES +5 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,11 @@ Changelog Daniel Stenberg (21 Aug 2009) - 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. - Lots of good work by Krister Johansen, mostly related to pipelining: Fix SIGSEGV on free'd easy_conn when pipe unexpectedly breaks Loading
RELEASE-NOTES +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ This release includes the following bugfixes: o SIGSEGV when pipelined pipe unexpectedly breaks o data corruption issue with re-connected transfers o use after free if we're completed but easy_conn not NULL (pipelined) o missing strdup() return code check This release includes the following known bugs: Loading @@ -26,6 +27,6 @@ This release includes the following known bugs: This release would not have looked like this without help, code, reports and advice from friends like these: Karl Moerder, Kamil Dudka, Krister Johansen, Karl Moerder, Kamil Dudka, Krister Johansen, Andre Guibert de Bruet Thanks! (and sorry if I forgot to mention someone)
lib/multi.c +16 −3 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading
lib/transfer.c +15 −9 Original line number Diff line number Diff line Loading @@ -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, 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) && Loading @@ -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 Loading @@ -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; } /* Loading Loading @@ -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; Loading
lib/transfer.h +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading