Improve parsing of chunked transfer chunks per RFC2616:
* more stringent chunk-size parsing * ignore optional trailing ';chunk-ext' stuff, instead of barfing * detect EOF before final \r\n.
This commit is contained in:
parent
fc68757006
commit
91c7169d78
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: fetch.c,v 1.180 2007/06/05 00:31:20 lukem Exp $ */
|
/* $NetBSD: fetch.c,v 1.181 2007/08/22 06:51:41 lukem Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1997-2007 The NetBSD Foundation, Inc.
|
* Copyright (c) 1997-2007 The NetBSD Foundation, Inc.
|
||||||
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: fetch.c,v 1.180 2007/06/05 00:31:20 lukem Exp $");
|
__RCSID("$NetBSD: fetch.c,v 1.181 2007/08/22 06:51:41 lukem Exp $");
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1146,31 +1146,52 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
|
|||||||
/* Finally, suck down the file. */
|
/* Finally, suck down the file. */
|
||||||
do {
|
do {
|
||||||
long chunksize;
|
long chunksize;
|
||||||
|
short lastchunk;
|
||||||
|
|
||||||
chunksize = 0;
|
chunksize = 0;
|
||||||
/* read chunksize */
|
lastchunk = 0;
|
||||||
|
/* read chunk-size */
|
||||||
if (ischunked) {
|
if (ischunked) {
|
||||||
if (fgets(xferbuf, bufsize, fin) == NULL) {
|
if (fgets(xferbuf, bufsize, fin) == NULL) {
|
||||||
warnx("Unexpected EOF reading chunksize");
|
warnx("Unexpected EOF reading chunk-size");
|
||||||
goto cleanup_fetch_url;
|
goto cleanup_fetch_url;
|
||||||
}
|
}
|
||||||
|
errno = 0;
|
||||||
chunksize = strtol(xferbuf, &ep, 16);
|
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'",
|
||||||
|
ep-xferbuf, xferbuf);
|
||||||
|
goto cleanup_fetch_url;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: Work around bug in Apache 1.3.9 and
|
* XXX: Work around bug in Apache 1.3.9 and
|
||||||
* 1.3.11, which incorrectly put trailing
|
* 1.3.11, which incorrectly put trailing
|
||||||
* space after the chunksize.
|
* space after the chunk-size.
|
||||||
*/
|
*/
|
||||||
while (*ep == ' ')
|
while (*ep == ' ')
|
||||||
ep++;
|
ep++;
|
||||||
|
|
||||||
|
/* skip [ chunk-ext ] */
|
||||||
|
if (*ep == ';') {
|
||||||
|
while (*ep && *ep != '\r')
|
||||||
|
ep++;
|
||||||
|
}
|
||||||
|
|
||||||
if (strcmp(ep, "\r\n") != 0) {
|
if (strcmp(ep, "\r\n") != 0) {
|
||||||
warnx("Unexpected data following chunksize");
|
warnx("Unexpected data following chunk-size");
|
||||||
goto cleanup_fetch_url;
|
goto cleanup_fetch_url;
|
||||||
}
|
}
|
||||||
DPRINTF("got chunksize of " LLF "\n", (LLT)chunksize);
|
DPRINTF("got chunk-size of " LLF "\n", (LLT)chunksize);
|
||||||
if (chunksize == 0)
|
if (chunksize == 0) {
|
||||||
break;
|
lastchunk = 1;
|
||||||
|
goto chunkdone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* transfer file or chunk */
|
/* transfer file or chunk */
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -1222,14 +1243,21 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
|
|||||||
/* read CRLF after chunk*/
|
/* read CRLF after chunk*/
|
||||||
chunkdone:
|
chunkdone:
|
||||||
if (ischunked) {
|
if (ischunked) {
|
||||||
if (fgets(xferbuf, bufsize, fin) == NULL)
|
if (fgets(xferbuf, bufsize, fin) == NULL) {
|
||||||
break;
|
warnx("Unexpected EOF reading chunk CRLF");
|
||||||
|
goto cleanup_fetch_url;
|
||||||
|
}
|
||||||
if (strcmp(xferbuf, "\r\n") != 0) {
|
if (strcmp(xferbuf, "\r\n") != 0) {
|
||||||
warnx("Unexpected data following chunk");
|
warnx("Unexpected data following chunk");
|
||||||
goto cleanup_fetch_url;
|
goto cleanup_fetch_url;
|
||||||
}
|
}
|
||||||
|
if (lastchunk)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} while (ischunked);
|
} while (ischunked);
|
||||||
|
|
||||||
|
/* XXX: deal with optional trailer & CRLF here? */
|
||||||
|
|
||||||
if (hash && !progress && bytes > 0) {
|
if (hash && !progress && bytes > 0) {
|
||||||
if (bytes < mark)
|
if (bytes < mark)
|
||||||
(void)putc('#', ttyout);
|
(void)putc('#', ttyout);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: version.h,v 1.69 2007/08/06 03:41:14 lukem Exp $ */
|
/* $NetBSD: version.h,v 1.70 2007/08/22 06:51:41 lukem Exp $ */
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999-2007 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999-2007 The NetBSD Foundation, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -40,5 +40,5 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FTP_VERSION
|
#ifndef FTP_VERSION
|
||||||
#define FTP_VERSION "20070722"
|
#define FTP_VERSION "20070822"
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user