Package: curl
Version: 7.13.2-2
Severity: important

Some broken HTTP servers return response headers containing null bytes.
For example:
    http://ftp.pl.debian.org/debian/dists/sarge/main/binary-i386/Packages.gz
(at least until the webmaster fixes it).

When curl is parsing header lines, it reads a buffer and then looks
for the end-of-line by doing
            k->end_ptr = strchr (k->str_start, '\n');
in lib/transfer.c

But this is incorrect if the buffer contains embedded nulls -- the
strchr search will terminate too soon.  Then more data gets appended
to the header, the true CRLF termination is missed, and curl returns
insanely long headers which are actually part of the response data.

Here is a simple test program to reproduce the problem:

---- cut here ----
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

void
get_headers(char *url)
{
    CURL *handle;
    const int TRUE = 1;

    handle = curl_easy_init();

    // write headers to stdout
    curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, fwrite);
    curl_easy_setopt(handle, CURLOPT_WRITEHEADER, stdout);

    // exit when the data arrives
    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, exit);

#if DEBUG
    curl_easy_setopt(handle, CURLOPT_VERBOSE, TRUE);
#endif

    curl_easy_setopt(handle, CURLOPT_URL, url);
    curl_easy_setopt(handle, CURLOPT_HTTPGET, TRUE);
    curl_easy_perform(handle);
}

int
main(int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s URL\n", argv[0]);
        exit(1);
    }
    get_headers(argv[1]);
    return 0;
}
---- cut here ----

Run
    ./ctest 
http://ftp.pl.debian.org/debian/dists/sarge/main/binary-i386/Packages.gz > foo"
and examine foo with hexdump or emacs to see the problem.

Here is a patch that seems to fix it, but I've only tested it with the
site above.

---- patch ----
diff -ur curl-7.13.2/lib/transfer.c curl-7.13.2-ecc/lib/transfer.c
--- curl-7.13.2/lib/transfer.c  2005-02-16 09:31:33.000000000 -0500
+++ curl-7.13.2-ecc/lib/transfer.c      2005-05-26 20:48:40.000000000 -0400
@@ -351,11 +351,20 @@
             size_t rest_length;
             size_t full_length;
             int writetype;
+            int i;
 
             /* str_start is start of line within buf */
             k->str_start = k->str;
 
-            k->end_ptr = strchr (k->str_start, '\n');
+            /* we can't use strchr or index to find the end of line because
+               broken HTTP servers might put null bytes in the headers */
+            k->end_ptr = 0;
+            for (i = 0; i < nread; i++) {
+              if (k->str_start[i] == '\n') {
+                k->end_ptr = k->str_start + i;
+                break;
+              }
+            }
 
             if (!k->end_ptr) {
               /* Not a complete header line within buffer, append the data to
---- end patch ----

-- System Information:
Debian Release: 3.1
  APT prefers testing
  APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.11.10
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)

Versions of packages curl depends on:
ii  libc6                       2.3.2.ds1-21 GNU C Library: Shared libraries an
ii  libcurl3                    7.13.2-2     Multi-protocol file transfer libra
ii  libidn11                    0.5.13-1.0   GNU libidn library, implementation
ii  libssl0.9.7                 0.9.7e-3     SSL shared libraries
ii  zlib1g                      1:1.2.2-4    compression library - runtime

-- no debconf information


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to