Improve parsing of chunked transfer chunks per RFC2616:
authorPeter Avalos <pavalos@dragonflybsd.org>
Sat, 25 Aug 2007 21:05:27 +0000 (21:05 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sat, 25 Aug 2007 21:05:27 +0000 (21:05 +0000)
* more stringent chunk-size parsing
* ignore optional trailing ';chunk-ext' stuff, instead of barfing
* detect EOF before final \r\n.

contrib/tnftp/fetch.c
contrib/tnftp/ftp.1
contrib/tnftp/version.h

index 7954277..bd6073d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: fetch.c,v 1.180 2007/06/05 00:31:20 lukem Exp $        */
+/*     $NetBSD: fetch.c,v 1.182 2007/08/22 23:47:13 lukem Exp $        */
 
 /*-
  * Copyright (c) 1997-2007 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: fetch.c,v 1.180 2007/06/05 00:31:20 lukem Exp $");
+__RCSID("$NetBSD: fetch.c,v 1.182 2007/08/22 23:47:13 lukem Exp $");
 #endif /* not lint */
 
 /*
@@ -1146,31 +1146,52 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
                        /* Finally, suck down the file. */
        do {
                long chunksize;
+               short lastchunk;
 
                chunksize = 0;
-                                       /* read chunksize */
+               lastchunk = 0;
+                                       /* read chunk-size */
                if (ischunked) {
                        if (fgets(xferbuf, bufsize, fin) == NULL) {
-                               warnx("Unexpected EOF reading chunksize");
+                               warnx("Unexpected EOF reading chunk-size");
                                goto cleanup_fetch_url;
                        }
+                       errno = 0;
                        chunksize = strtol(xferbuf, &ep, 16);
+                       if (ep == xferbuf) {
+                               warnx("Invalid chunk-size");
+                               goto cleanup_fetch_url;
+                       }
+                       if (errno == ERANGE || chunksize < 0) {
+                               errno = ERANGE;
+                               warn("Chunk-size `%.*s'",
+                                   (int)(ep-xferbuf), xferbuf);
+                               goto cleanup_fetch_url;
+                       }
 
                                /*
                                 * XXX: Work around bug in Apache 1.3.9 and
                                 *      1.3.11, which incorrectly put trailing
-                                *      space after the chunksize.
+                                *      space after the chunk-size.
                                 */
                        while (*ep == ' ')
                                ep++;
 
+                                       /* skip [ chunk-ext ] */
+                       if (*ep == ';') {
+                               while (*ep && *ep != '\r')
+                                       ep++;
+                       }
+
                        if (strcmp(ep, "\r\n") != 0) {
-                               warnx("Unexpected data following chunksize");
+                               warnx("Unexpected data following chunk-size");
                                goto cleanup_fetch_url;
                        }
-                       DPRINTF("got chunksize of " LLF "\n", (LLT)chunksize);
-                       if (chunksize == 0)
-                               break;
+                       DPRINTF("got chunk-size of " LLF "\n", (LLT)chunksize);
+                       if (chunksize == 0) {
+                               lastchunk = 1;
+                               goto chunkdone;
+                       }
                }
                                        /* transfer file or chunk */
                while (1) {
@@ -1222,14 +1243,21 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
                                        /* read CRLF after chunk*/
  chunkdone:
                if (ischunked) {
-                       if (fgets(xferbuf, bufsize, fin) == NULL)
-                               break;
+                       if (fgets(xferbuf, bufsize, fin) == NULL) {
+                               warnx("Unexpected EOF reading chunk CRLF");
+                               goto cleanup_fetch_url;
+                       }
                        if (strcmp(xferbuf, "\r\n") != 0) {
                                warnx("Unexpected data following chunk");
                                goto cleanup_fetch_url;
                        }
+                       if (lastchunk)
+                               break;
                }
        } while (ischunked);
+
+/* XXX: deal with optional trailer & CRLF here? */
+
        if (hash && !progress && bytes > 0) {
                if (bytes < mark)
                        (void)putc('#', ttyout);
index 4f99f2b..e7c193a 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $NetBSD: ftp.1,v 1.119 2007/07/18 06:40:01 lukem Exp $
+.\"    $NetBSD: ftp.1,v 1.121 2007/08/20 16:07:05 perry Exp $
 .\"
 .\" Copyright (c) 1996-2007 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -64,7 +64,7 @@
 .\"
 .\"    @(#)ftp.1       8.3 (Berkeley) 10/9/94
 .\"
-.Dd July 18, 2007
+.Dd August 6, 2007
 .Dt FTP 1
 .Os
 .Sh NAME
@@ -86,10 +86,10 @@ Internet file transfer program
 .Bk -words
 .Op Fl q Ar quittime
 .Ek
-.Op Fl s Ar srcaddr
 .Bk -words
 .Op Fl r Ar retry
 .Ek
+.Op Fl s Ar srcaddr
 .Bk -words
 .\" [-T dir,max[,inc]]
 .Oo
@@ -2127,7 +2127,7 @@ is applicable only to the
 definition preceding it.
 A
 .Ic macdef
-entry cannot be utilized by multiple
+entry cannot be used by multiple
 .Ic machine
 definitions; rather, it must be defined following each
 .Ic machine
index 83243fe..e42140f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: version.h,v 1.68 2007/06/05 00:31:20 lukem Exp $       */
+/*     $NetBSD: version.h,v 1.70 2007/08/22 06:51:41 lukem Exp $       */
 /*-
  * Copyright (c) 1999-2007 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -40,5 +40,5 @@
 #endif
 
 #ifndef FTP_VERSION
-#define        FTP_VERSION     "20070605"
+#define        FTP_VERSION     "20070822"
 #endif