curl-library
Memory leak if FTP server responds "530 Login incorrect"
From: Alexey Simak <alexeysimak_at_gmail.com>
Date: Fri, 8 Dec 2006 17:16:28 +0200
Date: Fri, 8 Dec 2006 17:16:28 +0200
Hi,
struct connectdata allocated in url.c, line 2720 is not
destroyed if multi interface is used and FTP server
responds "530 Login incorrect".
libcurl version: 7.16.0
OS: Microsoft Windows Server 2003, Enterprise Edition, SP1, v1039.
Compiler: MS Visual C++ 6.0
FTP server: IIS 6.0
Here is a simple program to reproduce the problem:
//--------------------------------------------------------------------------
---
#include "curl.h"
struct FtpFile {
char *filename;
FILE *stream;
};
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out=(struct FtpFile *)stream;
if(out && !out->stream) {
/* open file for writing */
out->stream=fopen(out->filename, "wb");
if(!out->stream)
return -1; /* failure, can't open file to write */
}
return fwrite(buffer, size, nmemb, out->stream);
}
int main(int argc, char* argv[])
{
CURL* handle;
CURLM* multi_handle;
int still_running; /* keep number of running handles */
struct FtpFile ftpfile={
"test.txt", /* name to store the file as if succesful */
NULL
};
curl_global_init(CURL_GLOBAL_DEFAULT);
multi_handle = curl_multi_init();
handle = curl_easy_init();
CURLMcode code = curl_multi_add_handle( multi_handle, handle );
curl_easy_setopt(handle, CURLOPT_URL,
"ftp://ftp.univ.kiev.ua/pub/incoming/test.txt");
/* Define our callback to get called when there's data to be written */
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, my_fwrite);
/* Set a pointer to our struct to pass to the callback */
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &ftpfile);
/* Switch on full protocol/debug output */
curl_easy_setopt(handle, CURLOPT_VERBOSE, TRUE);
// Make FTP server respond 503
curl_easy_setopt( handle, CURLOPT_USERPWD, "invaliduser:invalidpwd" );
/* we start some action by calling perform right away */
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
while(still_running) {
struct timeval timeout;
int rc; /* select() return code */
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
/* set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
/* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
/* In a real-world program you OF COURSE check the return code of
the
function calls, *and* you make sure that maxfd is bigger than -1
so
that the call to select() below makes sense! */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) {
case -1:
/* select error */
still_running = 0;
printf("select() returns error, this is badness\n");
break;
case 0:
default:
/* timeout or readable/writable sockets */
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
break;
}
}
curl_multi_remove_handle( multi_handle, handle );
curl_easy_cleanup( handle );
curl_multi_cleanup( multi_handle );
if(ftpfile.stream)
fclose(ftpfile.stream); /* close the local file */
curl_global_cleanup();
return 0;
}
//--------------------------------------------------------------------------
---
Best regards,
Alexey Simak
Received on 2006-12-08