summaryrefslogtreecommitdiff
path: root/src/node_zlib.cc
diff options
context:
space:
mode:
authorKári Tristan Helgason <kthelgason@gmail.com>2016-02-03 18:29:26 +0000
committerBen Noordhuis <info@bnoordhuis.nl>2016-03-15 16:47:10 +0100
commitf380db237b2a6b73fe52b6929fa842cb62e3fa81 (patch)
tree795fee75dfed0961e09a630815f24ebf74a8ebd7 /src/node_zlib.cc
parent3b2094152e7be6fa6b1f9d57221a3b033b1bb7d3 (diff)
downloadandroid-node-v8-f380db237b2a6b73fe52b6929fa842cb62e3fa81.tar.gz
android-node-v8-f380db237b2a6b73fe52b6929fa842cb62e3fa81.tar.bz2
android-node-v8-f380db237b2a6b73fe52b6929fa842cb62e3fa81.zip
zlib: add support for concatenated members
According to the spec gzipped archives can contain more than one compressed member. Previously Node's gzip implementation would only unzip the first member and throw away the rest of the compressed data. Issue #4306 is an example of this occurring in daily use. Fixes: https://github.com/nodejs/node/issues/4306 PR-URL: https://github.com/nodejs/node/pull/5120 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_zlib.cc')
-rw-r--r--src/node_zlib.cc18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/node_zlib.cc b/src/node_zlib.cc
index f7e808cf1b..4984989bb4 100644
--- a/src/node_zlib.cc
+++ b/src/node_zlib.cc
@@ -41,6 +41,9 @@ enum node_zlib_mode {
UNZIP
};
+#define GZIP_HEADER_ID1 0x1f
+#define GZIP_HEADER_ID2 0x8b
+#define GZIP_MIN_HEADER_SIZE 10
void InitZlib(v8::Local<v8::Object> target);
@@ -254,6 +257,19 @@ class ZCtx : public AsyncWrap {
ctx->err_ = Z_NEED_DICT;
}
}
+ while (ctx->strm_.avail_in >= GZIP_MIN_HEADER_SIZE &&
+ ctx->mode_ == GUNZIP) {
+ // Bytes remain in input buffer. Perhaps this is another compressed
+ // member in the same archive, or just trailing garbage.
+ // Check the header to find out.
+ if (ctx->strm_.next_in[0] != GZIP_HEADER_ID1 ||
+ ctx->strm_.next_in[1] != GZIP_HEADER_ID2) {
+ // Not a valid gzip member
+ break;
+ }
+ Reset(ctx);
+ ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
+ }
break;
default:
CHECK(0 && "wtf?");
@@ -524,10 +540,12 @@ class ZCtx : public AsyncWrap {
switch (ctx->mode_) {
case DEFLATE:
case DEFLATERAW:
+ case GZIP:
ctx->err_ = deflateReset(&ctx->strm_);
break;
case INFLATE:
case INFLATERAW:
+ case GUNZIP:
ctx->err_ = inflateReset(&ctx->strm_);
break;
default: