- Frank Hempel found out a bug and provided the fix:

curl_easy_duphandle did not necessarily duplicate the CURLOPT_COOKIEFILE
  option. It only enabled the cookie engine in the destination handle if
  data->cookies is not NULL (where data is the source handle). In case of a
  newly initialized handle which just had the cookie support enabled by a
  curl_easy_setopt(handle, CURL_COOKIEFILE, "")-call, handle->cookies was
  still NULL because the setopt-call only appends the value to
  data->change.cookielist, hence duplicating this handle would not have the
  cookie engine switched on.

  We also concluded that the slist-functionality would be suitable for being
  put in its own module rather than simply hanging out in lib/sendf.c so I
  created lib/slist.[ch] for them.
This commit is contained in:
Daniel Stenberg 2009-03-09 12:21:46 +00:00
parent c86c294f55
commit bdec6f2b20
7 changed files with 204 additions and 80 deletions

15
CHANGES
View File

@ -7,6 +7,21 @@
Changelog Changelog
Daniel Stenberg (9 Mar 2009) Daniel Stenberg (9 Mar 2009)
- Frank Hempel found out a bug and provided the fix:
curl_easy_duphandle did not necessarily duplicate the CURLOPT_COOKIEFILE
option. It only enabled the cookie engine in the destination handle if
data->cookies is not NULL (where data is the source handle). In case of a
newly initialized handle which just had the cookie support enabled by a
curl_easy_setopt(handle, CURL_COOKIEFILE, "")-call, handle->cookies was
still NULL because the setopt-call only appends the value to
data->change.cookielist, hence duplicating this handle would not have the
cookie engine switched on.
We also concluded that the slist-functionality would be suitable for being
put in its own module rather than simply hanging out in lib/sendf.c so I
created lib/slist.[ch] for them.
- Andreas Farber made the 'buildconf' script check for the presence of m4 - Andreas Farber made the 'buildconf' script check for the presence of m4
scripts to make it detect a bad checkout earlier. People with older scripts to make it detect a bad checkout earlier. People with older
checkouts who don't do cvs update with the -d option won't get the new dirs checkouts who don't do cvs update with the -d option won't get the new dirs

View File

@ -17,6 +17,7 @@ This release includes the following bugfixes:
o NTLM authentication memory leak on SSPI enabled Windows builds o NTLM authentication memory leak on SSPI enabled Windows builds
o fixed the GnuTLS-using code to do correct return code checks o fixed the GnuTLS-using code to do correct return code checks
o an alloc-related call in the OpenSSL-using code didn't check the return value o an alloc-related call in the OpenSSL-using code didn't check the return value
o curl_easy_duphandle() failed to duplicate cookies at times
This release includes the following known bugs: This release includes the following known bugs:
@ -26,6 +27,6 @@ This release would not have looked like this without help, code, reports and
advice from friends like these: advice from friends like these:
Daniel Fandrich, Yang Tse, David James, Chris Deidun, Bill Egert, Daniel Fandrich, Yang Tse, David James, Chris Deidun, Bill Egert,
Andre Guibert de Bruet, Andreas Farber Andre Guibert de Bruet, Andreas Farber, Frank Hempel
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@ -10,7 +10,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \ hostares.c hostasyn.c hostip4.c hostip6.c hostsyn.c hostthre.c \
inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \ inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c \
strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c \ strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c \
socks_gssapi.c socks_sspi.c curl_sspi.c socks_gssapi.c socks_sspi.c curl_sspi.c slist.c
HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \ progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h \
@ -21,4 +21,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h \
strtoofft.h strerror.h inet_ntop.h curlx.h memory.h setup.h \ strtoofft.h strerror.h inet_ntop.h curlx.h memory.h setup.h \
transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h \ transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h \
tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \ tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h \
curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h

View File

@ -84,6 +84,7 @@
#include "sendf.h" /* for failf function prototype */ #include "sendf.h" /* for failf function prototype */
#include "http_ntlm.h" #include "http_ntlm.h"
#include "connect.h" /* for Curl_getconnectinfo */ #include "connect.h" /* for Curl_getconnectinfo */
#include "slist.h"
#define _MPRINTF_REPLACE /* use our functions only */ #define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h> #include <curl/mprintf.h>
@ -648,6 +649,16 @@ CURL *curl_easy_duphandle(CURL *incurl)
/* duplicate all values in 'change' */ /* duplicate all values in 'change' */
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
if(data->change.cookielist) {
outcurl->change.cookielist =
Curl_slist_duplicate(data->change.cookielist);
if (!outcurl->change.cookielist)
break;
}
#endif /* CURL_DISABLE_HTTP */
if(data->change.url) { if(data->change.url) {
outcurl->change.url = strdup(data->change.url); outcurl->change.url = strdup(data->change.url);
if(!outcurl->change.url) if(!outcurl->change.url)
@ -692,6 +703,10 @@ CURL *curl_easy_duphandle(CURL *incurl)
Curl_rm_connc(outcurl->state.connc); Curl_rm_connc(outcurl->state.connc);
if(outcurl->state.headerbuff) if(outcurl->state.headerbuff)
free(outcurl->state.headerbuff); free(outcurl->state.headerbuff);
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
if(outcurl->change.cookielist)
curl_slist_free_all(outcurl->change.cookielist);
#endif
if(outcurl->change.url) if(outcurl->change.url)
free(outcurl->change.url); free(outcurl->change.url);
if(outcurl->change.referer) if(outcurl->change.referer)

View File

@ -5,7 +5,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 * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@ -62,82 +62,6 @@
/* The last #include file should be: */ /* The last #include file should be: */
#include "memdebug.h" #include "memdebug.h"
/* returns last node in linked list */
static struct curl_slist *slist_get_last(struct curl_slist *list)
{
struct curl_slist *item;
/* if caller passed us a NULL, return now */
if(!list)
return NULL;
/* loop through to find the last item */
item = list;
while(item->next) {
item = item->next;
}
return item;
}
/*
* curl_slist_append() appends a string to the linked list. It always returns
* the address of the first record, so that you can use this function as an
* initialization function as well as an append function. If you find this
* bothersome, then simply create a separate _init function and call it
* appropriately from within the program.
*/
struct curl_slist *curl_slist_append(struct curl_slist *list,
const char *data)
{
struct curl_slist *last;
struct curl_slist *new_item;
new_item = malloc(sizeof(struct curl_slist));
if(new_item) {
char *dupdata = strdup(data);
if(dupdata) {
new_item->next = NULL;
new_item->data = dupdata;
}
else {
free(new_item);
return NULL;
}
}
else
return NULL;
if(list) {
last = slist_get_last(list);
last->next = new_item;
return list;
}
/* if this is the first item, then new_item *is* the list */
return new_item;
}
/* be nice and clean up resources */
void curl_slist_free_all(struct curl_slist *list)
{
struct curl_slist *next;
struct curl_slist *item;
if(!list)
return;
item = list;
do {
next = item->next;
if(item->data) {
free(item->data);
}
free(item);
item = next;
} while(next);
}
#ifdef CURL_DO_LINEEND_CONV #ifdef CURL_DO_LINEEND_CONV
/* /*
* convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF

136
lib/slist.c Normal file
View File

@ -0,0 +1,136 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
#include "setup.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "memory.h"
#include "slist.h"
/* The last #include file should be: */
#include "memdebug.h"
/* returns last node in linked list */
static struct curl_slist *slist_get_last(struct curl_slist *list)
{
struct curl_slist *item;
/* if caller passed us a NULL, return now */
if(!list)
return NULL;
/* loop through to find the last item */
item = list;
while(item->next) {
item = item->next;
}
return item;
}
/*
* curl_slist_append() appends a string to the linked list. It always returns
* the address of the first record, so that you can use this function as an
* initialization function as well as an append function. If you find this
* bothersome, then simply create a separate _init function and call it
* appropriately from within the program.
*/
struct curl_slist *curl_slist_append(struct curl_slist *list,
const char *data)
{
struct curl_slist *last;
struct curl_slist *new_item;
new_item = malloc(sizeof(struct curl_slist));
if(new_item) {
char *dupdata = strdup(data);
if(dupdata) {
new_item->next = NULL;
new_item->data = dupdata;
}
else {
free(new_item);
return NULL;
}
}
else
return NULL;
if(list) {
last = slist_get_last(list);
last->next = new_item;
return list;
}
/* if this is the first item, then new_item *is* the list */
return new_item;
}
/*
* Curl_slist_duplicate() duplicates a linked list. It always returns the
* address of the first record of the cloned list or NULL in case of an
* error (or if the input list was NULL).
*/
struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist)
{
struct curl_slist *outlist = NULL;
struct curl_slist *tmp;
while(inlist) {
tmp = curl_slist_append(outlist, inlist->data);
if (!tmp) {
curl_slist_free_all(outlist);
return NULL;
}
outlist = tmp;
inlist = inlist->next;
}
return outlist;
}
/* be nice and clean up resources */
void curl_slist_free_all(struct curl_slist *list)
{
struct curl_slist *next;
struct curl_slist *item;
if(!list)
return;
item = list;
do {
next = item->next;
if(item->data) {
free(item->data);
}
free(item);
item = next;
} while(next);
}

33
lib/slist.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef __SLIST_H
#define __SLIST_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* 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
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* $Id$
***************************************************************************/
/*
* Curl_slist_duplicate() duplicates a linked list. It always returns the
* address of the first record of the cloned list or NULL in case of an
* error (or if the input list was NULL).
*/
struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist);
#endif /* __SLIST_H */