1
1
'use strict'
2
+ /* eslint camelcase: "off" */
2
3
3
4
var assert = require ( 'assert' )
4
5
@@ -23,17 +24,15 @@ exports.UNZIP = 7
23
24
24
25
var GZIP_HEADER_ID1 = 0x1f
25
26
var GZIP_HEADER_ID2 = 0x8b
26
- var GZIP_MIN_HEADER_SIZE = 10
27
27
28
28
/**
29
29
* Emulate Node's zlib C++ layer for use by the JS layer in index.js
30
30
*/
31
31
function Zlib ( mode ) {
32
- if ( mode == null || mode < exports . DEFLATE || mode > exports . UNZIP ) {
32
+ if ( typeof mode ! == 'number' || mode < exports . DEFLATE || mode > exports . UNZIP ) {
33
33
throw new TypeError ( 'Bad argument' )
34
34
}
35
35
36
- this . chunk_size = 0
37
36
this . dictionary = null
38
37
this . err = 0
39
38
this . flush = 0
@@ -45,6 +44,7 @@ function Zlib (mode) {
45
44
this . windowBits = 0
46
45
this . write_in_progress = false
47
46
this . pending_close = false
47
+ this . gzip_id_bytes_read = 0
48
48
}
49
49
50
50
Zlib . prototype . close = function ( ) {
@@ -60,15 +60,14 @@ Zlib.prototype.close = function () {
60
60
61
61
if ( this . mode === exports . DEFLATE || this . mode === exports . GZIP || this . mode === exports . DEFLATERAW ) {
62
62
zlib_deflate . deflateEnd ( this . strm )
63
- } else {
63
+ } else if ( this . mode === exports . INFLATE || this . mode === exports . GUNZIP ||
64
+ this . mode === exports . INFLATERAW || this . mode === exports . UNZIP ) {
64
65
zlib_inflate . inflateEnd ( this . strm )
65
66
}
66
67
67
68
this . mode = exports . NONE
68
69
69
- if ( this . dictionary != null ) {
70
- this . dictionary = null
71
- }
70
+ this . dictionary = null
72
71
}
73
72
74
73
Zlib . prototype . write = function ( flush , input , in_off , in_len , out , out_off , out_len ) {
@@ -108,12 +107,6 @@ Zlib.prototype._write = function (async, flush, input, in_off, in_len, out, out_
108
107
in_off = 0
109
108
}
110
109
111
- if ( out . _set ) {
112
- out . set = out . _set
113
- } else {
114
- out . set = bufferSet
115
- }
116
-
117
110
this . strm . avail_in = in_len
118
111
this . strm . input = input
119
112
this . strm . next_in = in_off
@@ -122,8 +115,6 @@ Zlib.prototype._write = function (async, flush, input, in_off, in_len, out, out_
122
115
this . strm . next_out = out_off
123
116
this . flush = flush
124
117
125
- this . chunk_size = out_len
126
-
127
118
if ( ! async ) {
128
119
// sync version
129
120
this . _process ( )
@@ -154,6 +145,8 @@ Zlib.prototype._afterSync = function () {
154
145
}
155
146
156
147
Zlib . prototype . _process = function ( ) {
148
+ var next_expected_header_byte = null
149
+
157
150
// If the avail_out is left at 0, then it means that it ran out
158
151
// of room. If there was avail_out left over, then it means
159
152
// that all of the input was consumed.
@@ -164,6 +157,50 @@ Zlib.prototype._process = function () {
164
157
this . err = zlib_deflate . deflate ( this . strm , this . flush )
165
158
break
166
159
case exports . UNZIP :
160
+ if ( this . strm . avail_in > 0 ) {
161
+ next_expected_header_byte = this . strm . next_in
162
+ }
163
+
164
+ switch ( this . gzip_id_bytes_read ) {
165
+ case 0 :
166
+ if ( next_expected_header_byte === null ) {
167
+ break
168
+ }
169
+
170
+ if ( this . strm . input [ next_expected_header_byte ] === GZIP_HEADER_ID1 ) {
171
+ this . gzip_id_bytes_read = 1
172
+ next_expected_header_byte ++
173
+
174
+ if ( this . strm . avail_in === 1 ) {
175
+ // The only available byte was already read.
176
+ break
177
+ }
178
+ } else {
179
+ this . mode = exports . INFLATE
180
+ break
181
+ }
182
+
183
+ // fallthrough
184
+ case 1 :
185
+ if ( next_expected_header_byte === null ) {
186
+ break
187
+ }
188
+
189
+ if ( this . strm . input [ next_expected_header_byte ] === GZIP_HEADER_ID2 ) {
190
+ this . gzip_id_bytes_read = 2
191
+ this . mode = exports . GUNZIP
192
+ } else {
193
+ // There is no actual difference between INFLATE and INFLATERAW
194
+ // (after initialization).
195
+ this . mode = exports . INFLATE
196
+ }
197
+
198
+ break
199
+ default :
200
+ throw new Error ( 'invalid number of gzip magic number bytes read' )
201
+ }
202
+
203
+ // fallthrough
167
204
case exports . INFLATE :
168
205
case exports . GUNZIP :
169
206
case exports . INFLATERAW :
@@ -183,16 +220,15 @@ Zlib.prototype._process = function () {
183
220
this . err = exports . Z_NEED_DICT
184
221
}
185
222
}
186
- while ( this . strm . avail_in >= GZIP_MIN_HEADER_SIZE &&
187
- this . mode === exports . GUNZIP ) {
223
+ while ( this . strm . avail_in > 0 &&
224
+ this . mode === exports . GUNZIP &&
225
+ this . err === exports . Z_STREAM_END &&
226
+ this . strm . next_in [ 0 ] !== 0x00 ) {
188
227
// Bytes remain in input buffer. Perhaps this is another compressed
189
228
// member in the same archive, or just trailing garbage.
190
- // Check the header to find out.
191
- if ( this . strm . next_in [ 0 ] !== GZIP_HEADER_ID1 ||
192
- this . strm . next_in [ 1 ] !== GZIP_HEADER_ID2 ) {
193
- // Not a valid gzip member
194
- break
195
- }
229
+ // Trailing zero bytes are okay, though, since they are frequently
230
+ // used for padding.
231
+
196
232
this . reset ( )
197
233
this . err = zlib_inflate . inflate ( this . strm , this . flush )
198
234
}
@@ -250,6 +286,9 @@ Zlib.prototype._after = function () {
250
286
}
251
287
252
288
Zlib . prototype . _error = function ( message ) {
289
+ if ( this . strm . msg ) {
290
+ message = this . strm . msg
291
+ }
253
292
this . onerror ( message , this . err )
254
293
255
294
// no hope of rescue.
@@ -262,7 +301,7 @@ Zlib.prototype._error = function (message) {
262
301
Zlib . prototype . init = function ( windowBits , level , memLevel , strategy , dictionary ) {
263
302
assert ( arguments . length === 4 || arguments . length === 5 , 'init(windowBits, level, memLevel, strategy, [dictionary])' )
264
303
265
- assert ( windowBits >= 6 && windowBits <= 15 , 'invalid windowBits' )
304
+ assert ( windowBits >= 8 && windowBits <= 15 , 'invalid windowBits' )
266
305
assert ( level >= - 1 && level <= 9 , 'invalid compression level' )
267
306
268
307
assert ( memLevel >= 1 && memLevel <= 9 , 'invalid memlevel' )
@@ -390,11 +429,4 @@ Zlib.prototype._reset = function () {
390
429
}
391
430
}
392
431
393
- // set method for Node buffers, used by pako
394
- function bufferSet ( data , offset ) {
395
- for ( var i = 0 ; i < data . length ; i ++ ) {
396
- this [ offset + i ] = data [ i ]
397
- }
398
- }
399
-
400
432
exports . Zlib = Zlib
0 commit comments