]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
- Frank Hempel found out a bug and provided the fix:
authorDaniel Stenberg <daniel@haxx.se>
Mon, 9 Mar 2009 12:21:46 +0000 (12:21 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 9 Mar 2009 12:21:46 +0000 (12:21 +0000)
  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.

CHANGES
RELEASE-NOTES
lib/Makefile.inc
lib/easy.c
lib/sendf.c
lib/slist.c [new file with mode: 0644]
lib/slist.h [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index c98a3f6702f1b55286a82926e54762602142886e..49a1d76ef20a90b2c8f36480a44ebe73e90e55b0 100644 (file)
--- 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
index d7cd170a24d04be60797879be573e081ee2cbc61..c28844f9eee7ba9cd864ba676dbc203679bf6229 100644 (file)
@@ -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)
index 9991fd89c765dedab8c5309bb7cad8956b63f74b..e4e631d0bf54e3be45dadc53d3deeca632ccf552 100644 (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       \
   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
index c0670d51921c7da6fd5d76d6bbbcdf8758438fd6..dc6c59366cf5ef7c96880b686df3735339f09609 100644 (file)
@@ -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 <curl/mprintf.h>
@@ -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)
index 5b7a6beb31ef0810957b3a0ff8986415123d2745..e622b9ac630d86841c0c1ece48e1fccbae73de9d 100644 (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
  * you should have received as part of this distribution. The terms
 /* 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 (file)
index 0000000..638a670
--- /dev/null
@@ -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);
+}
+
diff --git a/lib/slist.h b/lib/slist.h
new file mode 100644 (file)
index 0000000..1847f81
--- /dev/null
@@ -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 */