diff --git a/CHANGES b/CHANGES index c98a3f670..49a1d76ef 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,21 @@ Changelog 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 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 diff --git a/RELEASE-NOTES b/RELEASE-NOTES index d7cd170a2..c28844f9e 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -17,6 +17,7 @@ This release includes the following bugfixes: o NTLM authentication memory leak on SSPI enabled Windows builds 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 curl_easy_duphandle() failed to duplicate cookies at times 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: 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) diff --git a/lib/Makefile.inc b/lib/Makefile.inc index 9991fd89c..e4e631d0b 100644 --- a/lib/Makefile.inc +++ b/lib/Makefile.inc @@ -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 \ 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 \ - 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 \ 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 \ 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 \ - curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h + curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h diff --git a/lib/easy.c b/lib/easy.c index c0670d519..dc6c59366 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -84,6 +84,7 @@ #include "sendf.h" /* for failf function prototype */ #include "http_ntlm.h" #include "connect.h" /* for Curl_getconnectinfo */ +#include "slist.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -648,6 +649,16 @@ CURL *curl_easy_duphandle(CURL *incurl) /* 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) { outcurl->change.url = strdup(data->change.url); if(!outcurl->change.url) @@ -692,6 +703,10 @@ CURL *curl_easy_duphandle(CURL *incurl) Curl_rm_connc(outcurl->state.connc); if(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) free(outcurl->change.url); if(outcurl->change.referer) diff --git a/lib/sendf.c b/lib/sendf.c index 5b7a6beb3..e622b9ac6 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -62,82 +62,6 @@ /* 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; -} - -/* 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 /* * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF diff --git a/lib/slist.c b/lib/slist.c new file mode 100644 index 000000000..638a67018 --- /dev/null +++ b/lib/slist.c @@ -0,0 +1,136 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , 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 +#include +#include + +#include +#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); +} + diff --git a/lib/slist.h b/lib/slist.h new file mode 100644 index 000000000..1847f81f3 --- /dev/null +++ b/lib/slist.h @@ -0,0 +1,33 @@ +#ifndef __SLIST_H +#define __SLIST_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , 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 */