Dmitriy Sergeyev provided an example source code that crashed CVS libcurl

but that worked nicely in 7.15.5. I converted it into test case 532 and
fixed the problem.
This commit is contained in:
Daniel Stenberg 2006-10-04 21:11:08 +00:00
parent e2b48366d3
commit 552b963e6d
7 changed files with 128 additions and 10 deletions

View File

@ -6,6 +6,11 @@
Changelog
Daniel (4 October 2006)
- Dmitriy Sergeyev provided an example source code that crashed CVS libcurl
but that worked nicely in 7.15.5. I converted it into test case 532 and
fixed the problem.
Daniel (29 September 2006)
- Removed a few other no-longer present options from the header file.

View File

@ -655,6 +655,12 @@ void curl_easy_reset(CURL *curl)
{
struct SessionHandle *data = (struct SessionHandle *)curl;
Curl_safefree(data->reqdata.pathbuffer);
data->reqdata.pathbuffer=NULL;
Curl_safefree(data->reqdata.proto.generic);
data->reqdata.proto.generic=NULL;
/* zero out UserDefined data: */
memset(&data->set, 0, sizeof(struct UserDefined));

View File

@ -351,6 +351,8 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
{
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
struct Curl_one_easy *easy;
struct closure *cl;
struct closure *prev=NULL;
/* First, make some basic checks that the CURLM handle is a good handle */
if(!GOOD_MULTI_HANDLE(multi))
@ -368,7 +370,21 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
if(!easy)
return CURLM_OUT_OF_MEMORY;
easy->numsocks=0;
cl = multi->closure;
while(cl) {
struct closure *next = cl->next;
if(cl->easy_handle == easy_handle) {
/* remove this handle from the closure list */
free(cl);
if(prev)
prev->next = next;
else
multi->closure = next;
break; /* no need to continue since this handle can only be present once
in the list */
}
cl = next;
}
/* set the easy handle */
easy->easy_handle = easy_handle;
@ -1796,8 +1812,10 @@ static bool multi_conn_using(struct Curl_multi *multi,
return FALSE;
}
/* add the given data pointer to the list of 'closure handles' that are
kept around only to be able to close some connections nicely */
/* Add the given data pointer to the list of 'closure handles' that are kept
around only to be able to close some connections nicely - just make sure
that this handle isn't already added, like for the cases when an easy
handle is removed, added and removed again... */
static void add_closure(struct Curl_multi *multi,
struct SessionHandle *data)
{

View File

@ -35,4 +35,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test256 test257 test258 test259 test260 test261 test262 test263 test264 \
test265 test266 test267 test268 test269 test270 test271 test272 test273 \
test274 test275 test524 test525 test276 test277 test526 test527 test528 \
test530 DISABLED test278 test279 test531 test280 test529
test530 DISABLED test278 test279 test531 test280 test529 test532

61
tests/data/test532 Normal file
View File

@ -0,0 +1,61 @@
<info>
<keywords>
FTP
PASV
RETR
</keywords>
</info>
# Server-side
<reply>
<data>
file contents should appear once for each file
</data>
<datacheck>
file contents should appear once for each file
file contents should appear once for each file
file contents should appear once for each file
file contents should appear once for each file
</datacheck>
</reply>
# Client-side
<client>
<server>
ftp
</server>
<tool>
lib532
</tool>
<name>
FTP RETR same file using reset handles between each transfer
</name>
<command>
ftp://%HOSTIP:%FTPPORT/path/532
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<strip>
</strip>
<protocol>
USER anonymous
PASS curl_by_daniel@haxx.se
PWD
CWD path
EPSV
TYPE I
SIZE 532
RETR 532
EPSV
SIZE 532
RETR 532
EPSV
SIZE 532
RETR 532
EPSV
SIZE 532
RETR 532
QUIT
</protocol>
</verify>

View File

@ -42,7 +42,7 @@ SUPPORTFILES = first.c test.h
noinst_PROGRAMS = lib500 lib501 lib502 lib503 lib504 lib505 lib506 \
lib507 lib508 lib509 lib510 lib511 lib512 lib513 lib514 lib515 lib516 \
lib517 lib518 lib519 lib520 lib521 lib523 lib524 lib525 lib526 lib527 \
lib529 lib530
lib529 lib530 lib532
lib500_SOURCES = lib500.c $(SUPPORTFILES)
lib500_LDADD = $(LIBDIR)/libcurl.la
@ -145,6 +145,7 @@ lib525_LDADD = $(LIBDIR)/libcurl.la
lib525_DEPENDENCIES = $(LIBDIR)/libcurl.la
lib526_SOURCES = lib526.c $(SUPPORTFILES)
lib526_CFLAGS = -DLIB526
lib526_LDADD = $(LIBDIR)/libcurl.la
lib526_DEPENDENCIES = $(LIBDIR)/libcurl.la
@ -162,3 +163,8 @@ lib530_SOURCES = lib530.c $(SUPPORTFILES)
lib530_CFLAGS = -DLIB530
lib530_LDADD = $(LIBDIR)/libcurl.la
lib530_DEPENDENCIES = $(LIBDIR)/libcurl.la
lib532_SOURCES = lib526.c $(SUPPORTFILES)
lib532_CFLAGS = -DLIB532
lib532_LDADD = $(LIBDIR)/libcurl.la
lib532_DEPENDENCIES = $(LIBDIR)/libcurl.la

View File

@ -14,11 +14,17 @@
* sharing within the multi handle all transfers are performed on the same
* persistent connection.
*
* This source code is used for lib526 _and_ lib527 with only #ifdefs
* controlling the small differences. lib526 closes all easy handles after
* they all have transfered the file over the single connection, while lib527
* closes each easy handle after each single transfer. 526 and 527 use FTP,
* while 528 uses the lib526 tool but use HTTP.
* This source code is used for lib526, lib527 and lib532 with only #ifdefs
* controlling the small differences.
*
* - lib526 closes all easy handles after
* they all have transfered the file over the single connection
* - lib527 closes each easy handle after each single transfer.
* - lib532 uses only a single easy handle that is removed, reset and then
* re-added for each transfer
*
* Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but
* with HTTP.
*/
#include "test.h"
@ -78,7 +84,21 @@ int test(char *URL)
#endif
if(++current < NUM_HANDLES) {
fprintf(stderr, "Advancing to URL %d\n", current);
#ifdef LIB532
/* first remove the only handle we use */
curl_multi_remove_handle(m, curl[0]);
/* make us re-use the same handle all the time, and try resetting
the handle first too */
curl_easy_reset(curl[0]);
curl_easy_setopt(curl[0], CURLOPT_URL, URL);
curl_easy_setopt(curl[0], CURLOPT_VERBOSE, 1);
/* re-add it */
res = (int)curl_multi_add_handle(m, curl[0]);
#else
res = (int)curl_multi_add_handle(m, curl[current]);
#endif
if(res) {
fprintf(stderr, "add handle failed: %d.\n", res);
res = 243;
@ -121,7 +141,9 @@ int test(char *URL)
#ifndef LIB527
/* get NUM_HANDLES easy handles */
for(i=0; i < NUM_HANDLES; i++) {
#ifdef LIB526
curl_multi_remove_handle(m, curl[i]);
#endif
curl_easy_cleanup(curl[i]);
}
#endif