Comparing version 2.2.1 to 2.3.0
44
index.js
@@ -6,2 +6,3 @@ var fs = require("fs"); | ||
var EventEmitter = require("events").EventEmitter; | ||
var Transform = require("stream").Transform; | ||
var PassThrough = require("stream").PassThrough; | ||
@@ -192,2 +193,8 @@ | ||
// validate file size | ||
if (entry.compressionMethod === 0) { | ||
var msg = "compressed/uncompressed size mismatch for stored file: " + entry.compressedSize + " != " + entry.uncompressedSize; | ||
if (entry.compressedSize !== entry.uncompressedSize) return emitErrorAndAutoClose(self, new Error(msg)); | ||
} | ||
buffer = new Buffer(entry.fileNameLength + entry.extraFieldLength + entry.fileCommentLength); | ||
@@ -272,8 +279,9 @@ readFdSlicerNoEof(self.fdSlicer, buffer, 0, buffer.length, self.readEntryCursor, function(err) { | ||
var localFileHeaderEnd = entry.relativeOffsetOfLocalHeader + buffer.length + fileNameLength + extraFieldLength; | ||
var filterStream = null; | ||
var compressed; | ||
if (entry.compressionMethod === 0) { | ||
// 0 - The file is stored (no compression) | ||
compressed = false; | ||
} else if (entry.compressionMethod === 8) { | ||
// 8 - The file is Deflated | ||
filterStream = zlib.createInflateRaw(); | ||
compressed = true; | ||
} else { | ||
@@ -294,4 +302,10 @@ return callback(new Error("unsupported compression method: " + entry.compressionMethod)); | ||
var stream = self.fdSlicer.createReadStream({start: fileDataStart, end: fileDataEnd}); | ||
if (filterStream != null) { | ||
stream = stream.pipe(filterStream); | ||
if (compressed) { | ||
var deflateFilter = zlib.createInflateRaw(); | ||
var checkerStream = new AssertByteCountStream(entry.uncompressedSize); | ||
deflateFilter.on("error", function(err) { | ||
// forward zlib errors to the client-visible stream | ||
checkerStream.emit("error", err); | ||
}); | ||
stream = stream.pipe(deflateFilter).pipe(checkerStream); | ||
} | ||
@@ -336,2 +350,24 @@ callback(null, stream); | ||
util.inherits(AssertByteCountStream, Transform); | ||
function AssertByteCountStream(byteCount) { | ||
Transform.call(this); | ||
this.actualByteCount = 0; | ||
this.expectedByteCount = byteCount; | ||
} | ||
AssertByteCountStream.prototype._transform = function(chunk, encoding, cb) { | ||
this.actualByteCount += chunk.length; | ||
if (this.actualByteCount > this.expectedByteCount) { | ||
var msg = "too many bytes in the stream. expected " + this.expectedByteCount + ". got at least " + this.actualByteCount; | ||
return cb(new Error(msg)); | ||
} | ||
cb(null, chunk); | ||
}; | ||
AssertByteCountStream.prototype._flush = function(cb) { | ||
if (this.actualByteCount < this.expectedByteCount) { | ||
var msg = "not enough bytes in the stream. expected " + this.expectedByteCount + ". got only " + this.actualByteCount; | ||
return cb(new Error(msg)); | ||
} | ||
cb(); | ||
}; | ||
var cp437 = '\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ '; | ||
@@ -338,0 +374,0 @@ function bufferToString(buffer, start, end, isUtf8) { |
{ | ||
"name": "yauzl", | ||
"version": "2.2.1", | ||
"version": "2.3.0", | ||
"description": "yet another unzip library for node", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -135,2 +135,15 @@ # yauzl | ||
It's possible for the `readStream` to emit errors for several reasons. | ||
For example, if zlib cannot decompress the data, the zlib error will be emitted from the `readStream`. | ||
Two more error cases are if the decompressed data has too many or too few actual bytes | ||
compared to the reported byte count from the entry's `uncompressedSize` field. | ||
yauzl notices this false information and emits an error from the `readStream` | ||
after some number of bytes have already been piped through the stream. | ||
Because of this check, clients can always trust the `uncompressedSize` field in `Entry` objects. | ||
Guarding against [zip bomb](http://en.wikipedia.org/wiki/Zip_bomb) attacks can be accomplished by | ||
doing some heuristic checks on the size metadata and then watching out for the above errors. | ||
Such heuristics are outside the scope of this library, | ||
but enforcing the `uncompressedSize` is implemented here as a security feature. | ||
#### close() | ||
@@ -242,4 +255,3 @@ | ||
and is not to be trusted. | ||
There may be conflicts between the Central Directory information and the Local File Header, | ||
but the Local File Header is always ignored. | ||
Aside from checking the signature, yauzl ignores the content of the Local File Header. | ||
@@ -246,0 +258,0 @@ ### No CRC-32 Checking |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
292
27877
6
360