Package: wget
Version: 1.10.2-2
Severity: normal
Tags: patch

Note the negative length returned by my http server here.
The file's larger than 2GiB and I'm sure there's a server bug there.
But wget could easily handle it more gracefully - all the code for doing so is 
there.
First, though, here's how it handles the negative size at the moment:

(gdb) r http://bobthe/Company/Engineering/Software/VirtualSMUImages/copper-1.zip
Starting program: /tmp/wget-1.10.2/src/wget 
http://bobthe/Company/Engineering/Software/VirtualSMUImages/copper-1.zip
[Thread debugging using libthread_db enabled]
[New Thread 47666932903152 (LWP 31249)]
--17:00:40--  
http://bobthe/Company/Engineering/Software/VirtualSMUImages/copper-1.zip
           => `copper-1.zip'
Resolving bobthe... 10.2.1.7
Connecting to bobthe|10.2.1.7|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: -1,449,214,731 [application/zip]

    [ <=>                                                              ] 0      
       --.--K/s             


Program received signal SIGABRT, Aborted.
[Switching to Thread 47666932903152 (LWP 31249)]
0x00002b5a5256c07b in raise () from /lib/libc.so.6
(gdb) bt
#0  0x00002b5a5256c07b in raise () from /lib/libc.so.6
#1  0x00002b5a5256d84e in abort () from /lib/libc.so.6
#2  0x0000000000415e5a in http_loop (u=0x5430c0, newloc=0x7fff58c48d88, 
local_file=0x7fff58c48d80, referer=<value optimized out>, dt=0x7fff58c48ee8, 
proxy=0x0) at http.c:2456
#3  0x000000000041e2e5 in retrieve_url (origurl=0x543000 "h"..., 
file=0x7fff58c48ee0, newloc=0x7fff58c48ed8, refurl=0x0, dt=0x7fff58c48ee8) at 
retr.c:667
#4  0x000000000041a65d in main (argc=2, argv=0x7fff58c48ff8) at main.c:943
(gdb) 

This is the code that's abort()ing:

      else if (hstat.res == 0) /* No read error */
        {
          if (hstat.contlen == -1)  /* We don't know how much we were supposed
                                       to get, so assume we succeeded. */ 
            {
...
            }
          else if (hstat.len < hstat.contlen) /* meaning we lost the
                                                 connection too soon */
            {
...
            }
          else
            /* Getting here would mean reading more data than
               requested with content-length, which we never do.  */
            abort ();

My patch treats negatives lengths like out-of-range integers.
I was expecting this to cause the download to fail with a nice error message.
It actually treated the length as unknown and continued.
That seems like useful behavior, though a warning might be a useful addition.
Still, a minimal patch is always less controversial when hacking another's code.

-- System Information:
Debian Release: 4.0
  APT prefers stable
  APT policy: (500, 'stable'), (50, 'unstable')
Architecture: amd64 (x86_64)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-4-amd64
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) (ignored: LC_ALL 
set to en_US.UTF-8)

Versions of packages wget depends on:
ii  libc6                  2.3.6.ds1-13etch2 GNU C Library: Shared libraries
ii  libssl0.9.8            0.9.8c-4etch1     SSL shared libraries

wget recommends no packages.

-- no debconf information
--- http.c.orig	2007-12-13 16:57:24.000000000 -0800
+++ http.c	2007-12-13 16:58:44.000000000 -0800
@@ -1601,7 +1601,7 @@
       wgint parsed;
       errno = 0;
       parsed = str_to_wgint (hdrval, NULL, 10);
-      if (parsed == WGINT_MAX && errno == ERANGE)
+      if ((parsed == WGINT_MAX && errno == ERANGE) || parsed < 0)
 	/* Out of range.
 	   #### If Content-Length is out of range, it most likely
 	   means that the file is larger than 2G and that we're

Reply via email to