From 64bbe9dfafc6693a96b742f3133c636385835a19 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 2 Sep 2002 22:31:18 +0000 Subject: James Gallagher's Content-Encoding work --- lib/content_encoding.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 lib/content_encoding.c (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c new file mode 100644 index 000000000..51b59c584 --- /dev/null +++ b/lib/content_encoding.c @@ -0,0 +1,122 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * + * In order to be useful for every potential user, curl and libcurl are + * dual-licensed under the MPL and the MIT/X-derivate licenses. + * + * 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 MPL or the MIT/X-derivate + * licenses. You may pick one of these licenses. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + *****************************************************************************/ + +#include "setup.h" + +#ifdef HAVE_LIBZ + +#include "urldata.h" +#include +#include +#include "sendf.h" + +#define DSIZ 4096 /* buffer size for decompressed data */ + + +static CURLcode +process_zlib_error(struct SessionHandle *data, z_stream *z) +{ + if (z->msg) + failf (data, "Error while processing content unencoding.\n%s", + z->msg); + else + failf (data, "Error while processing content unencoding.\n" + "Unknown failure within decompression software."); + + return CURLE_BAD_CONTENT_ENCODING; +} + +static CURLcode +exit_zlib(z_stream *z, bool *zlib_init, CURLcode result) +{ + inflateEnd(z); + *zlib_init = 0; + return result; +} + +CURLcode +Curl_unencode_deflate_write(struct SessionHandle *data, + struct Curl_transfer_keeper *k, + ssize_t nread) +{ + int status; /* zlib status */ + int result; /* Curl_client_write status */ + char decomp[DSIZ]; /* Put the decompressed data here. */ + z_stream *z = &k->z; /* zlib state structure */ + + /* Initialize zlib? */ + if (!k->zlib_init) { + z->zalloc = (alloc_func)Z_NULL; + z->zfree = (free_func)Z_NULL; + z->opaque = 0; /* of dubious use 08/27/02 jhrg */ + if (inflateInit(z) != Z_OK) + return process_zlib_error(data, z); + k->zlib_init = 1; + } + + /* Set the compressed input when this fucntion is called */ + z->next_in = (Bytef *)k->str; + z->avail_in = nread; + + /* because the buffer size is fixed, iteratively decompress + and transfer to the client via client_write. */ + for (;;) { + /* (re)set buffer for decompressed output for every iteration */ + z->next_out = (Bytef *)&decomp[0]; + z->avail_out = DSIZ; + + status = inflate(z, Z_SYNC_FLUSH); + if (status == Z_OK || status == Z_STREAM_END) { + result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, + DSIZ - z->avail_out); + /* if !CURLE_OK, clean up, return */ + if (result) { + return exit_zlib(z, &k->zlib_init, result); + } + + /* Done?; clean up, return */ + if (status == Z_STREAM_END) { + if (inflateEnd(z) == Z_OK) + return exit_zlib(z, &k->zlib_init, result); + else + return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + } + + /* Done with these bytes, exit */ + if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) + return result; + } + else { /* Error; exit loop, handle below */ + return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + } + } +} +#endif /* HAVE_LIBZ */ + +/* + * local variables: + * eval: (load-file "../curl-mode.el") + * end: + * vim600: fdm=marker + * vim: et sw=2 ts=2 sts=2 tw=78 + */ -- cgit v1.2.1 From ba4e69bebc8f7f32f3bc7faa1e13e7580754075b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Sep 2002 11:52:59 +0000 Subject: updated source code boilerplate/header --- lib/content_encoding.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 51b59c584..80d9eec5b 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | @@ -7,19 +7,19 @@ * * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. * - * In order to be useful for every potential user, curl and libcurl are - * dual-licensed under the MPL and the MIT/X-derivate licenses. - * + * 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 MPL or the MIT/X-derivate - * licenses. You may pick one of these licenses. + * 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" -- cgit v1.2.1 From f26a338a54e04d0a6907f5d2479d8b0fa9daf297 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Jan 2003 21:08:12 +0000 Subject: copyright year update in the source header --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 80d9eec5b..bec0cbf43 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From a7c72b7abf1213c471f3fd11e6b8e3a37d526f60 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Jan 2003 10:14:20 +0000 Subject: removed the local variables for emacs and vim, use the new sample.emacs way for emacs, and vim users should provide a similar non-polluting style --- lib/content_encoding.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index bec0cbf43..5abb6e8cf 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -112,11 +112,3 @@ Curl_unencode_deflate_write(struct SessionHandle *data, } } #endif /* HAVE_LIBZ */ - -/* - * local variables: - * eval: (load-file "../curl-mode.el") - * end: - * vim600: fdm=marker - * vim: et sw=2 ts=2 sts=2 tw=78 - */ -- cgit v1.2.1 From 019c4088cfcca0d2b7c5cc4f52ca5dac0c616089 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Apr 2003 08:49:20 +0000 Subject: Dan Fandrich's gzip patch applied --- lib/content_encoding.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 235 insertions(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 5abb6e8cf..84240ea34 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -25,6 +25,9 @@ #ifdef HAVE_LIBZ +#include +#include + #include "urldata.h" #include #include @@ -32,6 +35,16 @@ #define DSIZ 4096 /* buffer size for decompressed data */ +#define GZIP_MAGIC_0 0x1f +#define GZIP_MAGIC_1 0x8b + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ static CURLcode process_zlib_error(struct SessionHandle *data, z_stream *z) @@ -74,7 +87,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, k->zlib_init = 1; } - /* Set the compressed input when this fucntion is called */ + /* Set the compressed input when this function is called */ z->next_in = (Bytef *)k->str; z->avail_in = nread; @@ -111,4 +124,225 @@ Curl_unencode_deflate_write(struct SessionHandle *data, } } } + +/* Skip over the gzip header */ +static enum { + GZIP_OK, + GZIP_BAD, + GZIP_UNDERFLOW +} +check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen) +{ + int method, flags; + const ssize_t totallen = len; + + /* The shortest header is 10 bytes */ + if (len < 10) + return GZIP_UNDERFLOW; + + if ((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1)) + return GZIP_BAD; + + method = data[2]; + flags = data[3]; + + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + /* Can't handle this compression method or unknown flag */ + return GZIP_BAD; + } + + /* Skip over time, xflags, OS code and all previous bytes */ + len -= 10; + data += 10; + + if (flags & EXTRA_FIELD) { + ssize_t extra_len; + + if (len < 2) + return GZIP_UNDERFLOW; + + extra_len = (data[1] << 8) | data[0]; + + if (len < (extra_len+2)) + return GZIP_UNDERFLOW; + + len -= (extra_len + 2); + } + + if (flags & ORIG_NAME) { + /* Skip over NUL-terminated file name */ + while (len && *data) { + --len; + ++data; + } + if (!len || *data) + return GZIP_UNDERFLOW; + + /* Skip over the NUL */ + --len; + ++data; + } + + if (flags & COMMENT) { + /* Skip over NUL-terminated comment */ + while (len && *data) { + --len; + ++data; + } + if (!len || *data) + return GZIP_UNDERFLOW; + + /* Skip over the NUL */ + --len; + ++data; + } + + if (flags & HEAD_CRC) { + if (len < 2) + return GZIP_UNDERFLOW; + + len -= 2; + data += 2; + } + + *headerlen = totallen - len; + return GZIP_OK; +} + +CURLcode +Curl_unencode_gzip_write(struct SessionHandle *data, + struct Curl_transfer_keeper *k, + ssize_t nread) +{ + int status; /* zlib status */ + int result; /* Curl_client_write status */ + char decomp[DSIZ]; /* Put the decompressed data here. */ + z_stream *z = &k->z; /* zlib state structure */ + + /* Initialize zlib? */ + if (!k->zlib_init) { + z->zalloc = (alloc_func)Z_NULL; + z->zfree = (free_func)Z_NULL; + z->opaque = 0; /* of dubious use 08/27/02 jhrg */ + if (inflateInit2(z, -MAX_WBITS) != Z_OK) + return process_zlib_error(data, z); + k->zlib_init = 1; /* Initial call state */ + } + + /* This next mess is to get around the potential case where there isn't + enough data passed in to skip over the gzip header. If that happens, + we malloc a block and copy what we have then wait for the next call. If + there still isn't enough (this is definitely a worst-case scenario), we + make the block bigger, copy the next part in and keep waiting. */ + + /* Skip over gzip header? */ + if (k->zlib_init == 1) { + /* Initial call state */ + ssize_t hlen; + + switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) { + case GZIP_OK: + z->next_in = (Bytef *)k->str + hlen; + z->avail_in = nread - hlen; + k->zlib_init = 3; /* Inflating stream state */ + break; + + case GZIP_UNDERFLOW: + /* We need more data so we can find the end of the gzip header */ + z->avail_in = nread; + z->next_in = malloc(z->avail_in); + if (z->next_in == NULL) { + return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); + } + memcpy(z->next_in, k->str, z->avail_in); + k->zlib_init = 2; /* Need more gzip header data state */ + /* We don't have any data to inflate yet */ + return CURLE_OK; + + case GZIP_BAD: + default: + return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + } + + } + else if (k->zlib_init == 2) { + /* Need more gzip header data state */ + ssize_t hlen; + unsigned char *oldblock = z->next_in; + + z->avail_in += nread; + z->next_in = realloc(z->next_in, z->avail_in); + if (z->next_in == NULL) { + free(oldblock); + return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); + } + /* Append the new block of data to the previous one */ + memcpy(z->next_in + z->avail_in - nread, k->str, nread); + + switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) { + case GZIP_OK: + /* This is the zlib stream data */ + free(z->next_in); + /* Don't point into the malloced block since we just freed it */ + z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in; + z->avail_in = z->avail_in - hlen; + k->zlib_init = 3; /* Inflating stream state */ + break; + + case GZIP_UNDERFLOW: + /* We still don't have any data to inflate! */ + return CURLE_OK; + + case GZIP_BAD: + default: + free(z->next_in); + return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + } + + } + else { + /* Inflating stream state */ + z->next_in = (Bytef *)k->str; + z->avail_in = nread; + } + + if (z->avail_in == 0) { + /* We don't have any data to inflate; wait until next time */ + return CURLE_OK; + } + + /* because the buffer size is fixed, iteratively decompress + and transfer to the client via client_write. */ + for (;;) { + /* (re)set buffer for decompressed output for every iteration */ + z->next_out = (Bytef *)&decomp[0]; + z->avail_out = DSIZ; + + status = inflate(z, Z_SYNC_FLUSH); + if (status == Z_OK || status == Z_STREAM_END) { + result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, + DSIZ - z->avail_out); + /* if !CURLE_OK, clean up, return */ + if (result) { + return exit_zlib(z, &k->zlib_init, result); + } + + /* Done?; clean up, return */ + /* We should really check the gzip CRC here */ + if (status == Z_STREAM_END) { + if (inflateEnd(z) == Z_OK) + return exit_zlib(z, &k->zlib_init, result); + else + return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + } + + /* Done with these bytes, exit */ + if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) + return result; + } + else { /* Error; exit loop, handle below */ + return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + } + } +} #endif /* HAVE_LIBZ */ -- cgit v1.2.1 From fece361a55aabd8eab617ee3a3ab4cd549ff3fcf Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Apr 2003 16:31:18 +0000 Subject: Nic fixed so that Curl_client_write() must not be called with 0 lenth data. I edited somewhat and removed trailing whitespaces. --- lib/content_encoding.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 84240ea34..9705c009c 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -1,8 +1,8 @@ /*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. @@ -10,7 +10,7 @@ * 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. @@ -68,7 +68,7 @@ exit_zlib(z_stream *z, bool *zlib_init, CURLcode result) } CURLcode -Curl_unencode_deflate_write(struct SessionHandle *data, +Curl_unencode_deflate_write(struct SessionHandle *data, struct Curl_transfer_keeper *k, ssize_t nread) { @@ -76,7 +76,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, int result; /* Curl_client_write status */ char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ - + /* Initialize zlib? */ if (!k->zlib_init) { z->zalloc = (alloc_func)Z_NULL; @@ -100,11 +100,12 @@ Curl_unencode_deflate_write(struct SessionHandle *data, status = inflate(z, Z_SYNC_FLUSH); if (status == Z_OK || status == Z_STREAM_END) { - result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, - DSIZ - z->avail_out); - /* if !CURLE_OK, clean up, return */ - if (result) { - return exit_zlib(z, &k->zlib_init, result); + if (DSIZ - z->avail_out) { + result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, + DSIZ - z->avail_out); + /* if !CURLE_OK, clean up, return */ + if (result) + return exit_zlib(z, &k->zlib_init, result); } /* Done?; clean up, return */ @@ -116,7 +117,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, } /* Done with these bytes, exit */ - if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) + if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) return result; } else { /* Error; exit loop, handle below */ @@ -130,8 +131,7 @@ static enum { GZIP_OK, GZIP_BAD, GZIP_UNDERFLOW -} -check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen) +} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen) { int method, flags; const ssize_t totallen = len; @@ -210,7 +210,7 @@ check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen) } CURLcode -Curl_unencode_gzip_write(struct SessionHandle *data, +Curl_unencode_gzip_write(struct SessionHandle *data, struct Curl_transfer_keeper *k, ssize_t nread) { @@ -218,7 +218,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, int result; /* Curl_client_write status */ char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ - + /* Initialize zlib? */ if (!k->zlib_init) { z->zalloc = (alloc_func)Z_NULL; @@ -320,11 +320,12 @@ Curl_unencode_gzip_write(struct SessionHandle *data, status = inflate(z, Z_SYNC_FLUSH); if (status == Z_OK || status == Z_STREAM_END) { - result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, - DSIZ - z->avail_out); - /* if !CURLE_OK, clean up, return */ - if (result) { - return exit_zlib(z, &k->zlib_init, result); + if(DSIZ - z->avail_out) { + result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, + DSIZ - z->avail_out); + /* if !CURLE_OK, clean up, return */ + if (result) + return exit_zlib(z, &k->zlib_init, result); } /* Done?; clean up, return */ @@ -337,7 +338,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, } /* Done with these bytes, exit */ - if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) + if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) return result; } else { /* Error; exit loop, handle below */ -- cgit v1.2.1 From c95814c04d6a0436e5c4c88d2e1d57c7e0c91060 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 22 Apr 2003 22:32:02 +0000 Subject: Dan Fandrich's gzip bugfix --- lib/content_encoding.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 9705c009c..92152cdf7 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -33,7 +33,7 @@ #include #include "sendf.h" -#define DSIZ 4096 /* buffer size for decompressed data */ +#define DSIZ 0x10000 /* buffer size for decompressed data */ #define GZIP_MAGIC_0 0x1f #define GZIP_MAGIC_1 0x8b @@ -248,7 +248,12 @@ Curl_unencode_gzip_write(struct SessionHandle *data, break; case GZIP_UNDERFLOW: - /* We need more data so we can find the end of the gzip header */ + /* We need more data so we can find the end of the gzip header. + It's possible that the memory block we malloc here will never be + freed if the transfer abruptly aborts after this point. Since it's + unlikely that circumstances will be right for this code path to be + followed in the first place, and it's even more unlikely for a transfer + to fail immediately afterwards, it should seldom be a problem. */ z->avail_in = nread; z->next_in = malloc(z->avail_in); if (z->next_in == NULL) { -- cgit v1.2.1 From 292ef5fabbe0b2031906ed36ac64c83dfb2b4dbc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Jan 2004 22:54:45 +0000 Subject: Dan Fandrich's zlib fix --- lib/content_encoding.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 92152cdf7..47cc78166 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -82,6 +82,8 @@ Curl_unencode_deflate_write(struct SessionHandle *data, z->zalloc = (alloc_func)Z_NULL; z->zfree = (free_func)Z_NULL; z->opaque = 0; /* of dubious use 08/27/02 jhrg */ + z->next_in = NULL; + z->avail_in = 0; if (inflateInit(z) != Z_OK) return process_zlib_error(data, z); k->zlib_init = 1; @@ -224,6 +226,8 @@ Curl_unencode_gzip_write(struct SessionHandle *data, z->zalloc = (alloc_func)Z_NULL; z->zfree = (free_func)Z_NULL; z->opaque = 0; /* of dubious use 08/27/02 jhrg */ + z->next_in = NULL; + z->avail_in = 0; if (inflateInit2(z, -MAX_WBITS) != Z_OK) return process_zlib_error(data, z); k->zlib_init = 1; /* Initial call state */ -- cgit v1.2.1 From 053f6c85efd0bf698f73343989474d672d0563a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Jan 2004 09:19:33 +0000 Subject: updated year in the copyright string --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 47cc78166..da0b2f634 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From 61e3d75def4ca1789a847fe57b06ab25ede05731 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 16 Jan 2004 09:17:04 +0000 Subject: Gisle Vanem's patch for variables that "might be used uninitialized" --- lib/content_encoding.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index da0b2f634..1eb465161 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -73,7 +73,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, ssize_t nread) { int status; /* zlib status */ - int result; /* Curl_client_write status */ + int result = CURLE_OK; /*?*/ /* Curl_client_write status */ char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ @@ -217,7 +217,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, ssize_t nread) { int status; /* zlib status */ - int result; /* Curl_client_write status */ + int result = CURLE_OK; /*?*/ /* Curl_client_write status */ char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ -- cgit v1.2.1 From 4d17d6876e4b2f08380812c4ec113073b0a14639 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 29 Jan 2004 13:56:45 +0000 Subject: Dan Fandrich's cleanup patch to make pedantic compiler options cause less warnings. Minor edits by me. --- lib/content_encoding.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 1eb465161..4ccef4834 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -32,6 +32,7 @@ #include #include #include "sendf.h" +#include "content_encoding.h" #define DSIZ 0x10000 /* buffer size for decompressed data */ -- cgit v1.2.1 From 4d17e77532934c9db2956083eb76821e01e98f0f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 13 Feb 2004 12:16:24 +0000 Subject: use CURLcode, not int, prevents picky compilers to warn --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 4ccef4834..496af07d2 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -74,7 +74,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, ssize_t nread) { int status; /* zlib status */ - int result = CURLE_OK; /*?*/ /* Curl_client_write status */ + CURLcode result = CURLE_OK; /*?*/ /* Curl_client_write status */ char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ -- cgit v1.2.1 From 8ddc18a4f961dc8eb4ae41101cb2bf8f87d4cd7f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 15 Feb 2004 13:58:57 +0000 Subject: another case which should use CURLcode and not int --- lib/content_encoding.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 496af07d2..a2b357b49 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -74,7 +74,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, ssize_t nread) { int status; /* zlib status */ - CURLcode result = CURLE_OK; /*?*/ /* Curl_client_write status */ + CURLcode result = CURLE_OK; /* Curl_client_write status */ char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ @@ -218,7 +218,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, ssize_t nread) { int status; /* zlib status */ - int result = CURLE_OK; /*?*/ /* Curl_client_write status */ + CURLcode result = CURLE_OK; /* Curl_client_write status */ char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ -- cgit v1.2.1 From 5dcfb8ad666269ee5ee886ec4c22969f744238e4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 26 Apr 2004 14:02:01 +0000 Subject: ignore the curl/types.h header file --- lib/content_encoding.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index a2b357b49..a36bba778 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -30,7 +30,6 @@ #include "urldata.h" #include -#include #include "sendf.h" #include "content_encoding.h" -- cgit v1.2.1 From bbafb2eb27954c34967f91c705e74cc0c186970d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 May 2004 11:30:23 +0000 Subject: curl_global_init_mem() allows the memory functions to be replaced. memory.h is included everywhere for this. --- lib/content_encoding.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index a36bba778..2a0aaf402 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -32,6 +32,9 @@ #include #include "sendf.h" #include "content_encoding.h" +#include "memory.h" + +#include "memdebug.h" #define DSIZ 0x10000 /* buffer size for decompressed data */ -- cgit v1.2.1 From 018affe6d03eba7d2eb302f156f36c5f5aa865ee Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 May 2004 07:55:05 +0000 Subject: Edited comments only. --- lib/content_encoding.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 2a0aaf402..387e81703 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -84,7 +84,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, if (!k->zlib_init) { z->zalloc = (alloc_func)Z_NULL; z->zfree = (free_func)Z_NULL; - z->opaque = 0; /* of dubious use 08/27/02 jhrg */ + z->opaque = 0; z->next_in = NULL; z->avail_in = 0; if (inflateInit(z) != Z_OK) @@ -228,7 +228,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, if (!k->zlib_init) { z->zalloc = (alloc_func)Z_NULL; z->zfree = (free_func)Z_NULL; - z->opaque = 0; /* of dubious use 08/27/02 jhrg */ + z->opaque = 0; z->next_in = NULL; z->avail_in = 0; if (inflateInit2(z, -MAX_WBITS) != Z_OK) @@ -237,10 +237,11 @@ Curl_unencode_gzip_write(struct SessionHandle *data, } /* This next mess is to get around the potential case where there isn't - enough data passed in to skip over the gzip header. If that happens, - we malloc a block and copy what we have then wait for the next call. If - there still isn't enough (this is definitely a worst-case scenario), we - make the block bigger, copy the next part in and keep waiting. */ + * enough data passed in to skip over the gzip header. If that happens, we + * malloc a block and copy what we have then wait for the next call. If + * there still isn't enough (this is definitely a worst-case scenario), we + * make the block bigger, copy the next part in and keep waiting. + */ /* Skip over gzip header? */ if (k->zlib_init == 1) { @@ -255,12 +256,13 @@ Curl_unencode_gzip_write(struct SessionHandle *data, break; case GZIP_UNDERFLOW: - /* We need more data so we can find the end of the gzip header. - It's possible that the memory block we malloc here will never be - freed if the transfer abruptly aborts after this point. Since it's - unlikely that circumstances will be right for this code path to be - followed in the first place, and it's even more unlikely for a transfer - to fail immediately afterwards, it should seldom be a problem. */ + /* We need more data so we can find the end of the gzip header. It's + * possible that the memory block we malloc here will never be freed if + * the transfer abruptly aborts after this point. Since it's unlikely + * that circumstances will be right for this code path to be followed in + * the first place, and it's even more unlikely for a transfer to fail + * immediately afterwards, it should seldom be a problem. + */ z->avail_in = nread; z->next_in = malloc(z->avail_in); if (z->next_in == NULL) { @@ -323,8 +325,8 @@ Curl_unencode_gzip_write(struct SessionHandle *data, return CURLE_OK; } - /* because the buffer size is fixed, iteratively decompress - and transfer to the client via client_write. */ + /* because the buffer size is fixed, iteratively decompress and transfer to + the client via client_write. */ for (;;) { /* (re)set buffer for decompressed output for every iteration */ z->next_out = (Bytef *)&decomp[0]; -- cgit v1.2.1 From e39b29fc4828d20ff7aff3b23370f7cdde5d6621 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 4 Jul 2004 21:53:46 +0000 Subject: typecast the conversion to uInt when assigning z->avail_in to prevent warnings from picky compilers --- lib/content_encoding.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 387e81703..b786e3f9c 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -94,7 +94,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, /* Set the compressed input when this function is called */ z->next_in = (Bytef *)k->str; - z->avail_in = nread; + z->avail_in = (uInt)nread; /* because the buffer size is fixed, iteratively decompress and transfer to the client via client_write. */ @@ -251,7 +251,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) { case GZIP_OK: z->next_in = (Bytef *)k->str + hlen; - z->avail_in = nread - hlen; + z->avail_in = (uInt)(nread - hlen); k->zlib_init = 3; /* Inflating stream state */ break; @@ -263,7 +263,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, * the first place, and it's even more unlikely for a transfer to fail * immediately afterwards, it should seldom be a problem. */ - z->avail_in = nread; + z->avail_in = (uInt)nread; z->next_in = malloc(z->avail_in); if (z->next_in == NULL) { return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); @@ -299,7 +299,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, free(z->next_in); /* Don't point into the malloced block since we just freed it */ z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in; - z->avail_in = z->avail_in - hlen; + z->avail_in = (uInt)(z->avail_in - hlen); k->zlib_init = 3; /* Inflating stream state */ break; @@ -317,7 +317,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, else { /* Inflating stream state */ z->next_in = (Bytef *)k->str; - z->avail_in = nread; + z->avail_in = (uInt)nread; } if (z->avail_in == 0) { -- cgit v1.2.1 From 8bfcae65ef9f7835b447a1e210c99ec8f5ac6198 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 27 Oct 2004 21:46:11 +0000 Subject: Dan Fandrich's gzip handling fix --- lib/content_encoding.c | 199 ++++++++++++++++++++++++++++++------------------- 1 file changed, 121 insertions(+), 78 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index b786e3f9c..ac17befaf 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -36,6 +36,10 @@ #include "memdebug.h" +/* Comment this out if zlib is always going to be at least ver. 1.2.0.4 + (doing so will reduce code size slightly). */ +#define OLD_ZLIB_SUPPORT 1 + #define DSIZ 0x10000 /* buffer size for decompressed data */ #define GZIP_MAGIC_0 0x1f @@ -49,14 +53,23 @@ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ +enum zlibState { + ZLIB_UNINIT, /* uninitialized */ + ZLIB_INIT, /* initialized */ + ZLIB_GZIP_HEADER, /* reading gzip header */ + ZLIB_GZIP_INFLATING, /* inflating gzip stream */ + ZLIB_INIT_GZIP /* initialized in transparent gzip mode */ +}; + static CURLcode -process_zlib_error(struct SessionHandle *data, z_stream *z) +process_zlib_error(struct SessionHandle *data, + z_stream *z) { if (z->msg) - failf (data, "Error while processing content unencoding.\n%s", + failf (data, "Error while processing content unencoding: %s", z->msg); else - failf (data, "Error while processing content unencoding.\n" + failf (data, "Error while processing content unencoding: " "Unknown failure within decompression software."); return CURLE_BAD_CONTENT_ENCODING; @@ -66,55 +79,48 @@ static CURLcode exit_zlib(z_stream *z, bool *zlib_init, CURLcode result) { inflateEnd(z); - *zlib_init = 0; + *zlib_init = ZLIB_UNINIT; return result; } -CURLcode -Curl_unencode_deflate_write(struct SessionHandle *data, - struct Curl_transfer_keeper *k, - ssize_t nread) +static CURLcode +inflate_stream(struct SessionHandle *data, + struct Curl_transfer_keeper *k) { + z_stream *z = &k->z; /* zlib state structure */ int status; /* zlib status */ CURLcode result = CURLE_OK; /* Curl_client_write status */ - char decomp[DSIZ]; /* Put the decompressed data here. */ - z_stream *z = &k->z; /* zlib state structure */ + char *decomp; /* Put the decompressed data here. */ - /* Initialize zlib? */ - if (!k->zlib_init) { - z->zalloc = (alloc_func)Z_NULL; - z->zfree = (free_func)Z_NULL; - z->opaque = 0; - z->next_in = NULL; - z->avail_in = 0; - if (inflateInit(z) != Z_OK) - return process_zlib_error(data, z); - k->zlib_init = 1; + /* Dynamically allocate a buffer for decompression because it's uncommonly + large to hold on the stack */ + decomp = (char*)malloc(DSIZ); + if (decomp == NULL) { + return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); } - /* Set the compressed input when this function is called */ - z->next_in = (Bytef *)k->str; - z->avail_in = (uInt)nread; - - /* because the buffer size is fixed, iteratively decompress - and transfer to the client via client_write. */ + /* because the buffer size is fixed, iteratively decompress and transfer to + the client via client_write. */ for (;;) { /* (re)set buffer for decompressed output for every iteration */ - z->next_out = (Bytef *)&decomp[0]; + z->next_out = (Bytef *)decomp; z->avail_out = DSIZ; status = inflate(z, Z_SYNC_FLUSH); if (status == Z_OK || status == Z_STREAM_END) { - if (DSIZ - z->avail_out) { + if(DSIZ - z->avail_out) { result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, DSIZ - z->avail_out); /* if !CURLE_OK, clean up, return */ - if (result) + if (result) { + free(decomp); return exit_zlib(z, &k->zlib_init, result); + } } - /* Done?; clean up, return */ + /* Done? clean up, return */ if (status == Z_STREAM_END) { + free(decomp); if (inflateEnd(z) == Z_OK) return exit_zlib(z, &k->zlib_init, result); else @@ -122,15 +128,47 @@ Curl_unencode_deflate_write(struct SessionHandle *data, } /* Done with these bytes, exit */ - if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) + if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) { + free(decomp); return result; + } } else { /* Error; exit loop, handle below */ + free(decomp); return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); } } + /* Will never get here */ } +CURLcode +Curl_unencode_deflate_write(struct SessionHandle *data, + struct Curl_transfer_keeper *k, + ssize_t nread) +{ + z_stream *z = &k->z; /* zlib state structure */ + + /* Initialize zlib? */ + if (k->zlib_init == ZLIB_UNINIT) { + z->zalloc = (alloc_func)Z_NULL; + z->zfree = (free_func)Z_NULL; + z->opaque = 0; + z->next_in = NULL; + z->avail_in = 0; + if (inflateInit(z) != Z_OK) + return process_zlib_error(data, z); + k->zlib_init = ZLIB_INIT; + } + + /* Set the compressed input when this function is called */ + z->next_in = (Bytef *)k->str; + z->avail_in = (uInt)nread; + + /* Now uncompress the data */ + return inflate_stream(data, k); +} + +#ifdef OLD_ZLIB_SUPPORT /* Skip over the gzip header */ static enum { GZIP_OK, @@ -213,38 +251,67 @@ static enum { *headerlen = totallen - len; return GZIP_OK; } +#endif CURLcode Curl_unencode_gzip_write(struct SessionHandle *data, struct Curl_transfer_keeper *k, ssize_t nread) { - int status; /* zlib status */ - CURLcode result = CURLE_OK; /* Curl_client_write status */ - char decomp[DSIZ]; /* Put the decompressed data here. */ z_stream *z = &k->z; /* zlib state structure */ /* Initialize zlib? */ - if (!k->zlib_init) { + if (k->zlib_init == ZLIB_UNINIT) { z->zalloc = (alloc_func)Z_NULL; z->zfree = (free_func)Z_NULL; z->opaque = 0; z->next_in = NULL; z->avail_in = 0; - if (inflateInit2(z, -MAX_WBITS) != Z_OK) - return process_zlib_error(data, z); - k->zlib_init = 1; /* Initial call state */ + + if (strcmp(zlibVersion(), "1.2.0.4") >= 0) { + /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ + if (inflateInit2(z, MAX_WBITS+32) != Z_OK) { + return process_zlib_error(data, z); + } + k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ + + } else { + /* we must parse the gzip header ourselves */ + if (inflateInit2(z, -MAX_WBITS) != Z_OK) { + return process_zlib_error(data, z); + } + k->zlib_init = ZLIB_INIT; /* Initial call state */ + } + } + + if (k->zlib_init == ZLIB_INIT_GZIP) { + /* Let zlib handle the gzip decompression entirely */ + z->next_in = (Bytef *)k->str; + z->avail_in = (uInt)nread; + /* Now uncompress the data */ + return inflate_stream(data, k); } +#ifndef OLD_ZLIB_SUPPORT + /* Support for old zlib versions is compiled away and we are running with + an old version, so return an error. */ + return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND); + +#else /* This next mess is to get around the potential case where there isn't * enough data passed in to skip over the gzip header. If that happens, we * malloc a block and copy what we have then wait for the next call. If * there still isn't enough (this is definitely a worst-case scenario), we * make the block bigger, copy the next part in and keep waiting. + * + * This is only required with zlib versions < 1.2.0.4 as newer versions + * can handle the gzip header themselves. */ + switch (k->zlib_init) { /* Skip over gzip header? */ - if (k->zlib_init == 1) { + case ZLIB_INIT: + { /* Initial call state */ ssize_t hlen; @@ -252,7 +319,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, case GZIP_OK: z->next_in = (Bytef *)k->str + hlen; z->avail_in = (uInt)(nread - hlen); - k->zlib_init = 3; /* Inflating stream state */ + k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */ break; case GZIP_UNDERFLOW: @@ -269,7 +336,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); } memcpy(z->next_in, k->str, z->avail_in); - k->zlib_init = 2; /* Need more gzip header data state */ + k->zlib_init = ZLIB_GZIP_HEADER; /* Need more gzip header data state */ /* We don't have any data to inflate yet */ return CURLE_OK; @@ -279,7 +346,10 @@ Curl_unencode_gzip_write(struct SessionHandle *data, } } - else if (k->zlib_init == 2) { + break; + + case ZLIB_GZIP_HEADER: + { /* Need more gzip header data state */ ssize_t hlen; unsigned char *oldblock = z->next_in; @@ -300,7 +370,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, /* Don't point into the malloced block since we just freed it */ z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in; z->avail_in = (uInt)(z->avail_in - hlen); - k->zlib_init = 3; /* Inflating stream state */ + k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */ break; case GZIP_UNDERFLOW: @@ -314,10 +384,14 @@ Curl_unencode_gzip_write(struct SessionHandle *data, } } - else { + break; + + case ZLIB_GZIP_INFLATING: + default: /* Inflating stream state */ z->next_in = (Bytef *)k->str; z->avail_in = (uInt)nread; + break; } if (z->avail_in == 0) { @@ -325,39 +399,8 @@ Curl_unencode_gzip_write(struct SessionHandle *data, return CURLE_OK; } - /* because the buffer size is fixed, iteratively decompress and transfer to - the client via client_write. */ - for (;;) { - /* (re)set buffer for decompressed output for every iteration */ - z->next_out = (Bytef *)&decomp[0]; - z->avail_out = DSIZ; - - status = inflate(z, Z_SYNC_FLUSH); - if (status == Z_OK || status == Z_STREAM_END) { - if(DSIZ - z->avail_out) { - result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, - DSIZ - z->avail_out); - /* if !CURLE_OK, clean up, return */ - if (result) - return exit_zlib(z, &k->zlib_init, result); - } - - /* Done?; clean up, return */ - /* We should really check the gzip CRC here */ - if (status == Z_STREAM_END) { - if (inflateEnd(z) == Z_OK) - return exit_zlib(z, &k->zlib_init, result); - else - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); - } - - /* Done with these bytes, exit */ - if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) - return result; - } - else { /* Error; exit loop, handle below */ - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); - } - } + /* We've parsed the header, now uncompress the data */ + return inflate_stream(data, k); +#endif } #endif /* HAVE_LIBZ */ -- cgit v1.2.1 From c28e15c68249a897be37d2bf5e49ab02d60479a6 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 30 Nov 2004 09:44:54 +0000 Subject: Dan Fandrich's fix for libz 1.1 and "extra field" usage in a gzip stream --- lib/content_encoding.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index ac17befaf..473b82b1e 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -210,6 +210,7 @@ static enum { return GZIP_UNDERFLOW; len -= (extra_len + 2); + data += (extra_len + 2); } if (flags & ORIG_NAME) { -- cgit v1.2.1 From e4a1788614aed581f03b54cd421ab949aac3b37d Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 7 Feb 2005 19:12:37 +0000 Subject: Fix for a bug report that compressed files that are exactly 64 KiB long produce a zlib error. --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 473b82b1e..47f245e9f 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -128,7 +128,7 @@ inflate_stream(struct SessionHandle *data, } /* Done with these bytes, exit */ - if (status == Z_OK && z->avail_in == 0 && z->avail_out > 0) { + if (status == Z_OK && z->avail_in == 0) { free(decomp); return result; } -- cgit v1.2.1 From ab4086bc244bf3267976e9f0193e5ed4430190d8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 31 Mar 2005 07:02:02 +0000 Subject: Updated the copyright year since changes have been this year. --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 47f245e9f..e3e66b140 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From 87c5ed8beca8ae36da5c38ef3594b56d132e7dde Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Apr 2006 20:49:40 +0000 Subject: Paul Querna fixed libcurl to better deal with deflate content encoding when the stream (wrongly) lacks a proper zlib header. This seems to be the case on too many actual server implementations. --- lib/content_encoding.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index e3e66b140..bcd5b838a 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -87,7 +87,10 @@ static CURLcode inflate_stream(struct SessionHandle *data, struct Curl_transfer_keeper *k) { + int allow_restart = 1; z_stream *z = &k->z; /* zlib state structure */ + uInt nread = z->avail_in; + Bytef *orig_in = z->next_in; int status; /* zlib status */ CURLcode result = CURLE_OK; /* Curl_client_write status */ char *decomp; /* Put the decompressed data here. */ @@ -108,6 +111,7 @@ inflate_stream(struct SessionHandle *data, status = inflate(z, Z_SYNC_FLUSH); if (status == Z_OK || status == Z_STREAM_END) { + allow_restart = 0; if(DSIZ - z->avail_out) { result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, DSIZ - z->avail_out); @@ -133,6 +137,19 @@ inflate_stream(struct SessionHandle *data, return result; } } + else if (allow_restart && status == Z_DATA_ERROR) { + /* some servers seem to not generate zlib headers, so this is an attempt + to fix and continue anyway */ + + inflateReset(z); + if (inflateInit2(z, -MAX_WBITS) != Z_OK) { + return process_zlib_error(data, z); + } + z->next_in = orig_in; + z->avail_in = nread; + allow_restart = 0; + continue; + } else { /* Error; exit loop, handle below */ free(decomp); return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); -- cgit v1.2.1 From cfdcae4bc75fba04b9864cae18e0bbe66b8655b9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 19 Aug 2006 21:18:36 +0000 Subject: Based on a patch by Armel Asselin, the FTP code no longer re-issues the TYPE command on subsequent requests on a re-used connection unless it has to. --- lib/content_encoding.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index bcd5b838a..97f834177 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -62,9 +62,9 @@ enum zlibState { }; static CURLcode -process_zlib_error(struct SessionHandle *data, - z_stream *z) +process_zlib_error(struct connectdata *conn, z_stream *z) { + struct SessionHandle *data = conn->data; if (z->msg) failf (data, "Error while processing content unencoding: %s", z->msg); @@ -84,7 +84,7 @@ exit_zlib(z_stream *z, bool *zlib_init, CURLcode result) } static CURLcode -inflate_stream(struct SessionHandle *data, +inflate_stream(struct connectdata *conn, struct Curl_transfer_keeper *k) { int allow_restart = 1; @@ -113,7 +113,7 @@ inflate_stream(struct SessionHandle *data, if (status == Z_OK || status == Z_STREAM_END) { allow_restart = 0; if(DSIZ - z->avail_out) { - result = Curl_client_write(data, CLIENTWRITE_BODY, decomp, + result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp, DSIZ - z->avail_out); /* if !CURLE_OK, clean up, return */ if (result) { @@ -128,7 +128,7 @@ inflate_stream(struct SessionHandle *data, if (inflateEnd(z) == Z_OK) return exit_zlib(z, &k->zlib_init, result); else - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } /* Done with these bytes, exit */ @@ -143,7 +143,7 @@ inflate_stream(struct SessionHandle *data, inflateReset(z); if (inflateInit2(z, -MAX_WBITS) != Z_OK) { - return process_zlib_error(data, z); + return process_zlib_error(conn, z); } z->next_in = orig_in; z->avail_in = nread; @@ -152,14 +152,14 @@ inflate_stream(struct SessionHandle *data, } else { /* Error; exit loop, handle below */ free(decomp); - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } } /* Will never get here */ } CURLcode -Curl_unencode_deflate_write(struct SessionHandle *data, +Curl_unencode_deflate_write(struct connectdata *conn, struct Curl_transfer_keeper *k, ssize_t nread) { @@ -173,7 +173,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, z->next_in = NULL; z->avail_in = 0; if (inflateInit(z) != Z_OK) - return process_zlib_error(data, z); + return process_zlib_error(conn, z); k->zlib_init = ZLIB_INIT; } @@ -182,7 +182,7 @@ Curl_unencode_deflate_write(struct SessionHandle *data, z->avail_in = (uInt)nread; /* Now uncompress the data */ - return inflate_stream(data, k); + return inflate_stream(conn, k); } #ifdef OLD_ZLIB_SUPPORT @@ -272,7 +272,7 @@ static enum { #endif CURLcode -Curl_unencode_gzip_write(struct SessionHandle *data, +Curl_unencode_gzip_write(struct connectdata *conn, struct Curl_transfer_keeper *k, ssize_t nread) { @@ -289,14 +289,14 @@ Curl_unencode_gzip_write(struct SessionHandle *data, if (strcmp(zlibVersion(), "1.2.0.4") >= 0) { /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ if (inflateInit2(z, MAX_WBITS+32) != Z_OK) { - return process_zlib_error(data, z); + return process_zlib_error(conn, z); } k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ } else { /* we must parse the gzip header ourselves */ if (inflateInit2(z, -MAX_WBITS) != Z_OK) { - return process_zlib_error(data, z); + return process_zlib_error(conn, z); } k->zlib_init = ZLIB_INIT; /* Initial call state */ } @@ -307,7 +307,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, z->next_in = (Bytef *)k->str; z->avail_in = (uInt)nread; /* Now uncompress the data */ - return inflate_stream(data, k); + return inflate_stream(conn, k); } #ifndef OLD_ZLIB_SUPPORT @@ -360,7 +360,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, case GZIP_BAD: default: - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } } @@ -398,7 +398,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, case GZIP_BAD: default: free(z->next_in); - return exit_zlib(z, &k->zlib_init, process_zlib_error(data, z)); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } } @@ -418,7 +418,7 @@ Curl_unencode_gzip_write(struct SessionHandle *data, } /* We've parsed the header, now uncompress the data */ - return inflate_stream(data, k); + return inflate_stream(conn, k); #endif } #endif /* HAVE_LIBZ */ -- cgit v1.2.1 From 9bf9617ad6206f99d239f0a18c8f082add832152 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 22 Feb 2007 06:19:39 +0000 Subject: Fix compiler warnings "case label value exceeds maximum value for type" and "comparison is always false due to limited range of data type" Both triggered when using a bool variable as the switch variable in a switch statement and using enums for the case targets. --- lib/content_encoding.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 97f834177..a363f6db0 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -53,14 +53,6 @@ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ -enum zlibState { - ZLIB_UNINIT, /* uninitialized */ - ZLIB_INIT, /* initialized */ - ZLIB_GZIP_HEADER, /* reading gzip header */ - ZLIB_GZIP_INFLATING, /* inflating gzip stream */ - ZLIB_INIT_GZIP /* initialized in transparent gzip mode */ -}; - static CURLcode process_zlib_error(struct connectdata *conn, z_stream *z) { @@ -76,7 +68,7 @@ process_zlib_error(struct connectdata *conn, z_stream *z) } static CURLcode -exit_zlib(z_stream *z, bool *zlib_init, CURLcode result) +exit_zlib(z_stream *z, zlibInitState *zlib_init, CURLcode result) { inflateEnd(z); *zlib_init = ZLIB_UNINIT; -- cgit v1.2.1 From 668c204970399211770542b21b8b873dcf68383c Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 8 Aug 2007 17:51:40 +0000 Subject: Song Ma noted a zlib memory leak in the illegal compressed header countermeasures code path. --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index a363f6db0..b80a57888 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -133,7 +133,7 @@ inflate_stream(struct connectdata *conn, /* some servers seem to not generate zlib headers, so this is an attempt to fix and continue anyway */ - inflateReset(z); + (void) inflateEnd(z); /* don't care about the return code */ if (inflateInit2(z, -MAX_WBITS) != Z_OK) { return process_zlib_error(conn, z); } -- cgit v1.2.1 From ad6e28073c985a42e8b15d2234baa7ef67ffcb35 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 5 Nov 2007 09:45:09 +0000 Subject: removed space after if and while before the parenthesis for better source code consistency --- lib/content_encoding.c | 66 +++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index b80a57888..bde84570f 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -57,7 +57,7 @@ static CURLcode process_zlib_error(struct connectdata *conn, z_stream *z) { struct SessionHandle *data = conn->data; - if (z->msg) + if(z->msg) failf (data, "Error while processing content unencoding: %s", z->msg); else @@ -90,7 +90,7 @@ inflate_stream(struct connectdata *conn, /* Dynamically allocate a buffer for decompression because it's uncommonly large to hold on the stack */ decomp = (char*)malloc(DSIZ); - if (decomp == NULL) { + if(decomp == NULL) { return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); } @@ -102,39 +102,39 @@ inflate_stream(struct connectdata *conn, z->avail_out = DSIZ; status = inflate(z, Z_SYNC_FLUSH); - if (status == Z_OK || status == Z_STREAM_END) { + if(status == Z_OK || status == Z_STREAM_END) { allow_restart = 0; if(DSIZ - z->avail_out) { result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp, DSIZ - z->avail_out); /* if !CURLE_OK, clean up, return */ - if (result) { + if(result) { free(decomp); return exit_zlib(z, &k->zlib_init, result); } } /* Done? clean up, return */ - if (status == Z_STREAM_END) { + if(status == Z_STREAM_END) { free(decomp); - if (inflateEnd(z) == Z_OK) + if(inflateEnd(z) == Z_OK) return exit_zlib(z, &k->zlib_init, result); else return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } /* Done with these bytes, exit */ - if (status == Z_OK && z->avail_in == 0) { + if(status == Z_OK && z->avail_in == 0) { free(decomp); return result; } } - else if (allow_restart && status == Z_DATA_ERROR) { + else if(allow_restart && status == Z_DATA_ERROR) { /* some servers seem to not generate zlib headers, so this is an attempt to fix and continue anyway */ (void) inflateEnd(z); /* don't care about the return code */ - if (inflateInit2(z, -MAX_WBITS) != Z_OK) { + if(inflateInit2(z, -MAX_WBITS) != Z_OK) { return process_zlib_error(conn, z); } z->next_in = orig_in; @@ -158,13 +158,13 @@ Curl_unencode_deflate_write(struct connectdata *conn, z_stream *z = &k->z; /* zlib state structure */ /* Initialize zlib? */ - if (k->zlib_init == ZLIB_UNINIT) { + if(k->zlib_init == ZLIB_UNINIT) { z->zalloc = (alloc_func)Z_NULL; z->zfree = (free_func)Z_NULL; z->opaque = 0; z->next_in = NULL; z->avail_in = 0; - if (inflateInit(z) != Z_OK) + if(inflateInit(z) != Z_OK) return process_zlib_error(conn, z); k->zlib_init = ZLIB_INIT; } @@ -189,16 +189,16 @@ static enum { const ssize_t totallen = len; /* The shortest header is 10 bytes */ - if (len < 10) + if(len < 10) return GZIP_UNDERFLOW; - if ((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1)) + if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1)) return GZIP_BAD; method = data[2]; flags = data[3]; - if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + if(method != Z_DEFLATED || (flags & RESERVED) != 0) { /* Can't handle this compression method or unknown flag */ return GZIP_BAD; } @@ -207,28 +207,28 @@ static enum { len -= 10; data += 10; - if (flags & EXTRA_FIELD) { + if(flags & EXTRA_FIELD) { ssize_t extra_len; - if (len < 2) + if(len < 2) return GZIP_UNDERFLOW; extra_len = (data[1] << 8) | data[0]; - if (len < (extra_len+2)) + if(len < (extra_len+2)) return GZIP_UNDERFLOW; len -= (extra_len + 2); data += (extra_len + 2); } - if (flags & ORIG_NAME) { + if(flags & ORIG_NAME) { /* Skip over NUL-terminated file name */ - while (len && *data) { + while(len && *data) { --len; ++data; } - if (!len || *data) + if(!len || *data) return GZIP_UNDERFLOW; /* Skip over the NUL */ @@ -236,13 +236,13 @@ static enum { ++data; } - if (flags & COMMENT) { + if(flags & COMMENT) { /* Skip over NUL-terminated comment */ - while (len && *data) { + while(len && *data) { --len; ++data; } - if (!len || *data) + if(!len || *data) return GZIP_UNDERFLOW; /* Skip over the NUL */ @@ -250,8 +250,8 @@ static enum { ++data; } - if (flags & HEAD_CRC) { - if (len < 2) + if(flags & HEAD_CRC) { + if(len < 2) return GZIP_UNDERFLOW; len -= 2; @@ -271,30 +271,30 @@ Curl_unencode_gzip_write(struct connectdata *conn, z_stream *z = &k->z; /* zlib state structure */ /* Initialize zlib? */ - if (k->zlib_init == ZLIB_UNINIT) { + if(k->zlib_init == ZLIB_UNINIT) { z->zalloc = (alloc_func)Z_NULL; z->zfree = (free_func)Z_NULL; z->opaque = 0; z->next_in = NULL; z->avail_in = 0; - if (strcmp(zlibVersion(), "1.2.0.4") >= 0) { + if(strcmp(zlibVersion(), "1.2.0.4") >= 0) { /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ - if (inflateInit2(z, MAX_WBITS+32) != Z_OK) { + if(inflateInit2(z, MAX_WBITS+32) != Z_OK) { return process_zlib_error(conn, z); } k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ } else { /* we must parse the gzip header ourselves */ - if (inflateInit2(z, -MAX_WBITS) != Z_OK) { + if(inflateInit2(z, -MAX_WBITS) != Z_OK) { return process_zlib_error(conn, z); } k->zlib_init = ZLIB_INIT; /* Initial call state */ } } - if (k->zlib_init == ZLIB_INIT_GZIP) { + if(k->zlib_init == ZLIB_INIT_GZIP) { /* Let zlib handle the gzip decompression entirely */ z->next_in = (Bytef *)k->str; z->avail_in = (uInt)nread; @@ -342,7 +342,7 @@ Curl_unencode_gzip_write(struct connectdata *conn, */ z->avail_in = (uInt)nread; z->next_in = malloc(z->avail_in); - if (z->next_in == NULL) { + if(z->next_in == NULL) { return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); } memcpy(z->next_in, k->str, z->avail_in); @@ -366,7 +366,7 @@ Curl_unencode_gzip_write(struct connectdata *conn, z->avail_in += nread; z->next_in = realloc(z->next_in, z->avail_in); - if (z->next_in == NULL) { + if(z->next_in == NULL) { free(oldblock); return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); } @@ -404,7 +404,7 @@ Curl_unencode_gzip_write(struct connectdata *conn, break; } - if (z->avail_in == 0) { + if(z->avail_in == 0) { /* We don't have any data to inflate; wait until next time */ return CURLE_OK; } -- cgit v1.2.1 From 13648f8ccda6f99674ac407640474634e856804c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Nov 2007 23:16:55 +0000 Subject: struct HandleData is now called struct SingleRequest, and is only for data that is inited at the start of the DO action. I removed the Curl_transfer_keeper struct completely, and I had to move out a few struct members (that had to be set before DO or used after DONE) to the UrlState struct. The SingleRequest struct is accessed with SessionHandle->req. One of the biggest reasons for doing this was the bunch of duplicate struct members in HandleData and Curl_transfer_keeper since it was really messy to keep track of two variables with the same name and basically the same purpose! --- lib/content_encoding.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index bde84570f..1d2852b5a 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -77,7 +77,7 @@ exit_zlib(z_stream *z, zlibInitState *zlib_init, CURLcode result) static CURLcode inflate_stream(struct connectdata *conn, - struct Curl_transfer_keeper *k) + struct SingleRequest *k) { int allow_restart = 1; z_stream *z = &k->z; /* zlib state structure */ @@ -152,7 +152,7 @@ inflate_stream(struct connectdata *conn, CURLcode Curl_unencode_deflate_write(struct connectdata *conn, - struct Curl_transfer_keeper *k, + struct SingleRequest *k, ssize_t nread) { z_stream *z = &k->z; /* zlib state structure */ @@ -265,7 +265,7 @@ static enum { CURLcode Curl_unencode_gzip_write(struct connectdata *conn, - struct Curl_transfer_keeper *k, + struct SingleRequest *k, ssize_t nread) { z_stream *z = &k->z; /* zlib state structure */ -- cgit v1.2.1 From 59e378f48fed849e8e41f0bc6a10bf7a1732ae8a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Sep 2008 05:29:05 +0000 Subject: remove unnecessary typecasting of malloc() --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 1d2852b5a..9cd5b0734 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -89,7 +89,7 @@ inflate_stream(struct connectdata *conn, /* Dynamically allocate a buffer for decompression because it's uncommonly large to hold on the stack */ - decomp = (char*)malloc(DSIZ); + decomp = malloc(DSIZ); if(decomp == NULL) { return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); } -- cgit v1.2.1 From d315d41a12b3273b258ea7823b73c3c7bab3a4e9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 14 Feb 2009 09:09:09 +0000 Subject: - Andre Guibert de Bruet found and fixed a memory leak in the content encoding code, which could happen on libz errors. --- lib/content_encoding.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 9cd5b0734..0de1c15d6 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, 2009, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -133,8 +133,9 @@ inflate_stream(struct connectdata *conn, /* some servers seem to not generate zlib headers, so this is an attempt to fix and continue anyway */ - (void) inflateEnd(z); /* don't care about the return code */ + (void) inflateEnd(z); /* don't care about the return code */ if(inflateInit2(z, -MAX_WBITS) != Z_OK) { + free(decomp); return process_zlib_error(conn, z); } z->next_in = orig_in; -- cgit v1.2.1 From 8cdc220bc0392214507f86a6a6ca5d32bcd9bd11 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 14 Feb 2009 09:12:55 +0000 Subject: nah, use the simpler year - year range syntax only, no matter what emacs' copyright-update script thinks --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 0de1c15d6..d2ad3f49f 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, 2009, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From 4ad296c60b1188e21e861e800a84eee32f986a9e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 17 Feb 2009 12:14:41 +0000 Subject: - A second follow-up change by Andre Guibert de Bruet to fix a related memory leak like that fixed on the 14th. When zlib returns failure, we need to cleanup properly before returning error. --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index d2ad3f49f..9163f0bab 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -136,7 +136,7 @@ inflate_stream(struct connectdata *conn, (void) inflateEnd(z); /* don't care about the return code */ if(inflateInit2(z, -MAX_WBITS) != Z_OK) { free(decomp); - return process_zlib_error(conn, z); + return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); } z->next_in = orig_in; z->avail_in = nread; -- cgit v1.2.1 From 33a3753c3f41d546ebf3350685eb7201d25783f4 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 21 Apr 2009 11:46:16 +0000 Subject: libcurl's memory.h renamed to curl_memory.h --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 9163f0bab..411f21337 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -32,7 +32,7 @@ #include #include "sendf.h" #include "content_encoding.h" -#include "memory.h" +#include "curl_memory.h" #include "memdebug.h" -- cgit v1.2.1 From 242a17b9e0e430ba5933f7b2ae5586233ec35f33 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 11 May 2009 09:55:28 +0000 Subject: - Balint Szilakszi reported a memory leak when libcurl did gzip decompression of streams that had some parts (legitimately) missing. We now provide and use a proper cleanup function for the content encoding submodule. http://curl.haxx.se/mail/lib-2009-05/0092.html --- lib/content_encoding.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 411f21337..08cf1dccc 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -414,4 +414,14 @@ Curl_unencode_gzip_write(struct connectdata *conn, return inflate_stream(conn, k); #endif } + +void Curl_unencode_cleanup(struct connectdata *conn) +{ + struct SessionHandle *data = conn->data; + struct SingleRequest *k = &data->req; + z_stream *z = &k->z; + if(k->zlib_init != ZLIB_UNINIT) + (void) exit_zlib(z, &k->zlib_init, CURLE_OK); +} + #endif /* HAVE_LIBZ */ -- cgit v1.2.1 From fa2ea23c962bf106db1b177bee36a21165e2bb5f Mon Sep 17 00:00:00 2001 From: Gunter Knauf Date: Sat, 29 Aug 2009 03:42:13 +0000 Subject: add cast to silient compiler warning with 64bit systems. --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 08cf1dccc..3b7d90c6f 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -365,7 +365,7 @@ Curl_unencode_gzip_write(struct connectdata *conn, ssize_t hlen; unsigned char *oldblock = z->next_in; - z->avail_in += nread; + z->avail_in += (uInt)nread; z->next_in = realloc(z->next_in, z->avail_in); if(z->next_in == NULL) { free(oldblock); -- cgit v1.2.1 From 33ce0ec1f1951bc1a8f4d475381c1b7c95d4a03a Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 22 Jan 2010 23:21:39 +0000 Subject: wrap long lines and do some indent policing --- lib/content_encoding.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 3b7d90c6f..85362da41 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -280,27 +280,27 @@ Curl_unencode_gzip_write(struct connectdata *conn, z->avail_in = 0; if(strcmp(zlibVersion(), "1.2.0.4") >= 0) { - /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ - if(inflateInit2(z, MAX_WBITS+32) != Z_OK) { - return process_zlib_error(conn, z); - } - k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ - - } else { - /* we must parse the gzip header ourselves */ - if(inflateInit2(z, -MAX_WBITS) != Z_OK) { - return process_zlib_error(conn, z); - } - k->zlib_init = ZLIB_INIT; /* Initial call state */ + /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ + if(inflateInit2(z, MAX_WBITS+32) != Z_OK) { + return process_zlib_error(conn, z); + } + k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ + } + else { + /* we must parse the gzip header ourselves */ + if(inflateInit2(z, -MAX_WBITS) != Z_OK) { + return process_zlib_error(conn, z); + } + k->zlib_init = ZLIB_INIT; /* Initial call state */ } } if(k->zlib_init == ZLIB_INIT_GZIP) { - /* Let zlib handle the gzip decompression entirely */ - z->next_in = (Bytef *)k->str; - z->avail_in = (uInt)nread; - /* Now uncompress the data */ - return inflate_stream(conn, k); + /* Let zlib handle the gzip decompression entirely */ + z->next_in = (Bytef *)k->str; + z->avail_in = (uInt)nread; + /* Now uncompress the data */ + return inflate_stream(conn, k); } #ifndef OLD_ZLIB_SUPPORT -- cgit v1.2.1 From 06ae8ca5a6e452e5cb555c1a511a9df8dec6657c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 9 Feb 2010 09:35:48 +0000 Subject: - When downloading compressed content over HTTP and the app as asked libcurl to automatically uncompress it with the CURLOPT_ENCODING option, libcurl could wrongly provide the callback with more data than what the maximum documented amount. An application could thus get tricked into badness if the maximum limit was trusted to be enforced by libcurl itself (as it is documented). This is further detailed and explained in the libcurl security advisory 20100209 at http://curl.haxx.se/docs/adv_20100209.html --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 85362da41..b8f57d001 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -40,7 +40,7 @@ (doing so will reduce code size slightly). */ #define OLD_ZLIB_SUPPORT 1 -#define DSIZ 0x10000 /* buffer size for decompressed data */ +#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */ #define GZIP_MAGIC_0 0x1f #define GZIP_MAGIC_1 0x8b -- cgit v1.2.1 From 2309b4e330b96bc2e1f8e36b6184015e59544037 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Mar 2010 11:02:54 +0100 Subject: remove the CVSish $Id$ lines --- lib/content_encoding.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index b8f57d001..69aa7bcc6 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -18,7 +18,6 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id$ ***************************************************************************/ #include "setup.h" -- cgit v1.2.1 From 99ec359b4d07bb3468aa617a2f13ad302ded0da3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 17 Apr 2010 18:55:52 +0200 Subject: check_gzip_header: Value stored to 'data' is never read --- lib/content_encoding.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 69aa7bcc6..a7511af7e 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -255,7 +255,6 @@ static enum { return GZIP_UNDERFLOW; len -= 2; - data += 2; } *headerlen = totallen - len; -- cgit v1.2.1 From 5b40c11c2f3db2f4de4969ebabca45b42ad405cc Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Apr 2010 12:37:11 +0200 Subject: gzip: Value stored to 'data' is never read --- lib/content_encoding.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index a7511af7e..a44aad7d0 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -247,7 +247,6 @@ static enum { /* Skip over the NUL */ --len; - ++data; } if(flags & HEAD_CRC) { -- cgit v1.2.1 From 7764795c06a4eae99c9cded5b121946d9ecec84b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 14 May 2010 22:12:07 +0200 Subject: follow redirect: ignore response-body on redirect even if compressed Sebastian V reported bug #3000056 identifying a problem with redirect following. It showed that when curl followed redirects it didn't properly ignore the response body of the 30X response if that response was using compressed Content-Encoding! (http://curl.haxx.se/bug/view.cgi?id=3000056) --- lib/content_encoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index a44aad7d0..f8c9234d9 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -103,7 +103,7 @@ inflate_stream(struct connectdata *conn, status = inflate(z, Z_SYNC_FLUSH); if(status == Z_OK || status == Z_STREAM_END) { allow_restart = 0; - if(DSIZ - z->avail_out) { + if((DSIZ - z->avail_out) && (!k->ignorebody)) { result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp, DSIZ - z->avail_out); /* if !CURLE_OK, clean up, return */ -- cgit v1.2.1 From 22085f7d6e8592b771dafd57673d875c73303f4f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 12 Sep 2010 16:34:16 +0200 Subject: inflate_stream: remove redundant check that is always true --- lib/content_encoding.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index f8c9234d9..6fb7c8d3a 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -123,7 +123,9 @@ inflate_stream(struct connectdata *conn, } /* Done with these bytes, exit */ - if(status == Z_OK && z->avail_in == 0) { + + /* status is always Z_OK at this point! */ + if(z->avail_in == 0) { free(decomp); return result; } -- cgit v1.2.1 From b903186fa0189ff241d756d25d07fdfe9885ae49 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Apr 2011 15:17:42 +0200 Subject: source cleanup: unify look, style and indent levels By the use of a the new lib/checksrc.pl script that checks that our basic source style rules are followed. --- lib/content_encoding.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 6fb7c8d3a..876115a32 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -95,7 +95,7 @@ inflate_stream(struct connectdata *conn, /* because the buffer size is fixed, iteratively decompress and transfer to the client via client_write. */ - for (;;) { + for(;;) { /* (re)set buffer for decompressed output for every iteration */ z->next_out = (Bytef *)decomp; z->avail_out = DSIZ; -- cgit v1.2.1 From f1586cb4775681810afd8e6626e7842d459f3b85 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 26 Jul 2011 17:23:27 +0200 Subject: stdio.h, stdlib.h, string.h, stdarg.h and ctype.h inclusion done in setup_once.h --- lib/content_encoding.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 876115a32..63bc2433c 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -24,9 +24,6 @@ #ifdef HAVE_LIBZ -#include -#include - #include "urldata.h" #include #include "sendf.h" -- cgit v1.2.1 From 9afb343368280b76135889976b5f351c94f58823 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 18 Aug 2011 20:09:26 +0200 Subject: zlib: enforce full initialization of our data space z_stream structs --- lib/content_encoding.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 63bc2433c..84d76f4b9 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -158,11 +158,7 @@ Curl_unencode_deflate_write(struct connectdata *conn, /* Initialize zlib? */ if(k->zlib_init == ZLIB_UNINIT) { - z->zalloc = (alloc_func)Z_NULL; - z->zfree = (free_func)Z_NULL; - z->opaque = 0; - z->next_in = NULL; - z->avail_in = 0; + memset(z, 0, sizeof(z_stream)); if(inflateInit(z) != Z_OK) return process_zlib_error(conn, z); k->zlib_init = ZLIB_INIT; @@ -269,11 +265,7 @@ Curl_unencode_gzip_write(struct connectdata *conn, /* Initialize zlib? */ if(k->zlib_init == ZLIB_UNINIT) { - z->zalloc = (alloc_func)Z_NULL; - z->zfree = (free_func)Z_NULL; - z->opaque = 0; - z->next_in = NULL; - z->avail_in = 0; + memset(z, 0, sizeof(z_stream)); if(strcmp(zlibVersion(), "1.2.0.4") >= 0) { /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ -- cgit v1.2.1 From 1c400b4e5e8ec2e5f787c950e20209d0811b57e6 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 21 Aug 2011 13:15:34 +0200 Subject: zlib: ensure user provided memory functions are used by zlib, when given As a bonus, this lets our MemoryTracking subsystem track zlib operations. And also fixes a shortcut some zlib 1.2.x versions took using malloc() instead of calloc(), which would trigger memory debuggers warnings on memory being used without having been initialized. --- lib/content_encoding.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib/content_encoding.c') diff --git a/lib/content_encoding.c b/lib/content_encoding.c index 84d76f4b9..3276ef988 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -49,6 +49,21 @@ #define COMMENT 0x10 /* bit 4 set: file comment present */ #define RESERVED 0xE0 /* bits 5..7: reserved */ +static voidpf +zalloc_cb(voidpf opaque, unsigned int items, unsigned int size) +{ + (void) opaque; + /* not a typo, keep it calloc() */ + return (voidpf) calloc(items, size); +} + +static void +zfree_cb(voidpf opaque, voidpf ptr) +{ + (void) opaque; + free(ptr); +} + static CURLcode process_zlib_error(struct connectdata *conn, z_stream *z) { @@ -159,6 +174,9 @@ Curl_unencode_deflate_write(struct connectdata *conn, /* Initialize zlib? */ if(k->zlib_init == ZLIB_UNINIT) { memset(z, 0, sizeof(z_stream)); + z->zalloc = (alloc_func)zalloc_cb; + z->zfree = (free_func)zfree_cb; + if(inflateInit(z) != Z_OK) return process_zlib_error(conn, z); k->zlib_init = ZLIB_INIT; @@ -266,6 +284,8 @@ Curl_unencode_gzip_write(struct connectdata *conn, /* Initialize zlib? */ if(k->zlib_init == ZLIB_UNINIT) { memset(z, 0, sizeof(z_stream)); + z->zalloc = (alloc_func)zalloc_cb; + z->zfree = (free_func)zfree_cb; if(strcmp(zlibVersion(), "1.2.0.4") >= 0) { /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ -- cgit v1.2.1