mirror of
https://github.com/curl/curl.git
synced 2025-09-09 21:52:40 +03:00
multi: init_do(): check result
Calls to `Curl_init_do()` did not check on result and missed failures to properly and completely initialize a transfer request. The main cause of such an init failure is the need to rewind the READFUNCTION without a SEEKFUNCTION registered. Check the failure to "rewind" the upload data immediately make test cases 1576 and friends fail. Reported-by: Travis Lane Fixes #17139 Closes #17150
This commit is contained in:
parent
39f5e7cb69
commit
5e95556fc2
|
@ -1560,10 +1560,15 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
|
||||||
rc = curl_multi_add_handle(multi, data);
|
rc = curl_multi_add_handle(multi, data);
|
||||||
if(!rc) {
|
if(!rc) {
|
||||||
struct SingleRequest *k = &data->req;
|
struct SingleRequest *k = &data->req;
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
/* pass in NULL for 'conn' here since we do not want to init the
|
/* pass in NULL for 'conn' here since we do not want to init the
|
||||||
connection, only this transfer */
|
connection, only this transfer */
|
||||||
Curl_init_do(data, NULL);
|
result = Curl_init_do(data, NULL);
|
||||||
|
if(result) {
|
||||||
|
curl_multi_remove_handle(multi, data);
|
||||||
|
return CURLM_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/* take this handle to the perform state right away */
|
/* take this handle to the perform state right away */
|
||||||
multistate(data, MSTATE_PERFORMING);
|
multistate(data, MSTATE_PERFORMING);
|
||||||
|
|
32
lib/url.c
32
lib/url.c
|
@ -3533,28 +3533,26 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||||
/* conn_protocol can only provide "old" protocols */
|
/* conn_protocol can only provide "old" protocols */
|
||||||
data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK;
|
data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK;
|
||||||
result = conn->handler->connect_it(data, &done);
|
result = conn->handler->connect_it(data, &done);
|
||||||
|
if(result)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/* Setup a "faked" transfer that will do nothing */
|
/* Setup a "faked" transfer that will do nothing */
|
||||||
|
Curl_attach_connection(data, conn);
|
||||||
|
result = Curl_cpool_add(data, conn);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
Curl_attach_connection(data, conn);
|
/* Setup whatever necessary for a resumed transfer */
|
||||||
result = Curl_cpool_add(data, conn);
|
result = setup_range(data);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
/* Setup whatever necessary for a resumed transfer */
|
Curl_xfer_setup_nop(data);
|
||||||
result = setup_range(data);
|
result = Curl_init_do(data, conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result) {
|
|
||||||
DEBUGASSERT(conn->handler->done);
|
|
||||||
/* we ignore the return code for the protocol-specific DONE */
|
|
||||||
(void)conn->handler->done(data, result, FALSE);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
Curl_xfer_setup_nop(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* since we skip do_init() */
|
if(result) {
|
||||||
Curl_init_do(data, conn);
|
DEBUGASSERT(conn->handler->done);
|
||||||
|
/* we ignore the return code for the protocol-specific DONE */
|
||||||
|
(void)conn->handler->done(data, result, FALSE);
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3704,7 +3702,9 @@ static CURLcode create_conn(struct Curl_easy *data,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup and init stuff before DO starts, in preparing for the transfer. */
|
/* Setup and init stuff before DO starts, in preparing for the transfer. */
|
||||||
Curl_init_do(data, conn);
|
result = Curl_init_do(data, conn);
|
||||||
|
if(result)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup whatever necessary for a resumed transfer
|
* Setup whatever necessary for a resumed transfer
|
||||||
|
|
|
@ -38,6 +38,15 @@ static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
|
||||||
return strlen(testdata);
|
return strlen(testdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int seek_callback(void *ptr, curl_off_t offset, int origin)
|
||||||
|
{
|
||||||
|
(void)ptr;
|
||||||
|
(void)offset;
|
||||||
|
if(origin != SEEK_SET)
|
||||||
|
return CURL_SEEKFUNC_FAIL;
|
||||||
|
return CURL_SEEKFUNC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
CURLcode test(char *URL)
|
CURLcode test(char *URL)
|
||||||
{
|
{
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
|
@ -62,6 +71,7 @@ CURLcode test(char *URL)
|
||||||
test_setopt(curl, CURLOPT_URL, URL);
|
test_setopt(curl, CURLOPT_URL, URL);
|
||||||
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||||
test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||||
|
test_setopt(curl, CURLOPT_SEEKFUNCTION, seek_callback);
|
||||||
test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata));
|
test_setopt(curl, CURLOPT_INFILESIZE, (long)strlen(testdata));
|
||||||
|
|
||||||
test_setopt(curl, CURLOPT_CUSTOMREQUEST, "CURL");
|
test_setopt(curl, CURLOPT_CUSTOMREQUEST, "CURL");
|
||||||
|
|
|
@ -78,6 +78,7 @@ my @reused_symbols = (
|
||||||
"removeFd",
|
"removeFd",
|
||||||
"rlim2str",
|
"rlim2str",
|
||||||
"run_thread",
|
"run_thread",
|
||||||
|
"seek_callback",
|
||||||
"send_ping",
|
"send_ping",
|
||||||
"showem",
|
"showem",
|
||||||
"store_errmsg",
|
"store_errmsg",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user