Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Buffer api compatibility for Node 0.10 #49

Merged
merged 1 commit into from
Dec 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 69 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ ZipFile.prototype.addEmptyDirectory = function(metadataPath, options) {
pumpEntries(self);
};

var eocdrSignatureBuffer = Buffer.from([0x50, 0x4b, 0x05, 0x06]);
var eocdrSignatureBuffer = bufferFrom([0x50, 0x4b, 0x05, 0x06]);

ZipFile.prototype.end = function(options, finalSizeCallback) {
if (typeof options === "function") {
Expand All @@ -129,7 +129,7 @@ ZipFile.prototype.end = function(options, finalSizeCallback) {
}
if (this.comment.length > 0xffff) throw new Error("comment is too large");
// gotta check for this, because the zipfile format is actually ambiguous.
if (this.comment.includes(eocdrSignatureBuffer)) throw new Error("comment contains end of central directory record signature");
if (bufferIncludes(this.comment, eocdrSignatureBuffer)) throw new Error("comment contains end of central directory record signature");
} else {
// no comment.
this.comment = EMPTY_BUFFER;
Expand Down Expand Up @@ -293,7 +293,7 @@ function getEndOfCentralDirectoryRecord(self, actuallyJustTellMeHowLongItWouldBe
}
}

var eocdrBuffer = Buffer.allocUnsafe(END_OF_CENTRAL_DIRECTORY_RECORD_SIZE + self.comment.length);
var eocdrBuffer = bufferAlloc(END_OF_CENTRAL_DIRECTORY_RECORD_SIZE + self.comment.length);
// end of central dir signature 4 bytes (0x06054b50)
eocdrBuffer.writeUInt32LE(0x06054b50, 0);
// number of this disk 2 bytes
Expand All @@ -317,7 +317,7 @@ function getEndOfCentralDirectoryRecord(self, actuallyJustTellMeHowLongItWouldBe

// ZIP64 format
// ZIP64 End of Central Directory Record
var zip64EocdrBuffer = Buffer.allocUnsafe(ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIZE);
var zip64EocdrBuffer = bufferAlloc(ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIZE);
// zip64 end of central dir signature 4 bytes (0x06064b50)
zip64EocdrBuffer.writeUInt32LE(0x06064b50, 0);
// size of zip64 end of central directory record 8 bytes
Expand All @@ -343,7 +343,7 @@ function getEndOfCentralDirectoryRecord(self, actuallyJustTellMeHowLongItWouldBe


// ZIP64 End of Central Directory Locator
var zip64EocdlBuffer = Buffer.allocUnsafe(ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIZE);
var zip64EocdlBuffer = bufferAlloc(ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIZE);
// zip64 end of central dir locator signature 4 bytes (0x07064b50)
zip64EocdlBuffer.writeUInt32LE(0x07064b50, 0);
// number of the disk with the start of the zip64 end of central directory 4 bytes
Expand Down Expand Up @@ -376,11 +376,11 @@ function validateMetadataPath(metadataPath, isDirectory) {
return metadataPath;
}

var EMPTY_BUFFER = Buffer.allocUnsafe(0);
var EMPTY_BUFFER = bufferAlloc(0);

// this class is not part of the public API
function Entry(metadataPath, isDirectory, options) {
this.utf8FileName = Buffer.from(metadataPath);
this.utf8FileName = bufferFrom(metadataPath);
if (this.utf8FileName.length > 0xffff) throw new Error("utf8 file name too long. " + utf8FileName.length + " > " + 0xffff);
this.isDirectory = isDirectory;
this.state = Entry.WAITING_FOR_METADATA;
Expand Down Expand Up @@ -412,7 +412,7 @@ function Entry(metadataPath, isDirectory, options) {
this.forceZip64Format = !!options.forceZip64Format;
if (options.fileComment) {
if (typeof options.fileComment === "string") {
this.fileComment = Buffer.from(options.fileComment, "utf-8");
this.fileComment = bufferFrom(options.fileComment, "utf-8");
} else {
// It should be a Buffer
this.fileComment = options.fileComment;
Expand Down Expand Up @@ -467,7 +467,7 @@ Entry.prototype.getLocalFileHeader = function() {
uncompressedSize = this.uncompressedSize;
}

var fixedSizeStuff = Buffer.allocUnsafe(LOCAL_FILE_HEADER_FIXED_SIZE);
var fixedSizeStuff = bufferAlloc(LOCAL_FILE_HEADER_FIXED_SIZE);
var generalPurposeBitFlag = FILE_NAME_IS_UTF8;
if (!this.crcAndFileSizeKnown) generalPurposeBitFlag |= UNKNOWN_CRC32_AND_FILE_SIZES;

Expand Down Expand Up @@ -506,10 +506,10 @@ var ZIP64_DATA_DESCRIPTOR_SIZE = 24;
Entry.prototype.getDataDescriptor = function() {
if (this.crcAndFileSizeKnown) {
// the Mac Archive Utility requires this not be present unless we set general purpose bit 3
return Buffer.allocUnsafe(0);
return EMPTY_BUFFER;
}
if (!this.useZip64Format()) {
var buffer = Buffer.allocUnsafe(DATA_DESCRIPTOR_SIZE);
var buffer = bufferAlloc(DATA_DESCRIPTOR_SIZE);
// optional signature (required according to Archive Utility)
buffer.writeUInt32LE(0x08074b50, 0);
// crc-32 4 bytes
Expand All @@ -521,7 +521,7 @@ Entry.prototype.getDataDescriptor = function() {
return buffer;
} else {
// ZIP64 format
var buffer = Buffer.allocUnsafe(ZIP64_DATA_DESCRIPTOR_SIZE);
var buffer = bufferAlloc(ZIP64_DATA_DESCRIPTOR_SIZE);
// optional signature (unknown if anyone cares about this)
buffer.writeUInt32LE(0x08074b50, 0);
// crc-32 4 bytes
Expand All @@ -536,7 +536,7 @@ Entry.prototype.getDataDescriptor = function() {
var CENTRAL_DIRECTORY_RECORD_FIXED_SIZE = 46;
var ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE = 28;
Entry.prototype.getCentralDirectoryRecord = function() {
var fixedSizeStuff = Buffer.allocUnsafe(CENTRAL_DIRECTORY_RECORD_FIXED_SIZE);
var fixedSizeStuff = bufferAlloc(CENTRAL_DIRECTORY_RECORD_FIXED_SIZE);
var generalPurposeBitFlag = FILE_NAME_IS_UTF8;
if (!this.crcAndFileSizeKnown) generalPurposeBitFlag |= UNKNOWN_CRC32_AND_FILE_SIZES;

Expand All @@ -552,7 +552,7 @@ Entry.prototype.getCentralDirectoryRecord = function() {
versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT_ZIP64;

// ZIP64 extended information extra field
zeiefBuffer = Buffer.allocUnsafe(ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE);
zeiefBuffer = bufferAlloc(ZIP64_EXTENDED_INFORMATION_EXTRA_FIELD_SIZE);
// 0x0001 2 bytes Tag for this "extra" block type
zeiefBuffer.writeUInt16LE(0x0001, 0);
// Size 2 bytes Size of this "extra" block
Expand All @@ -567,7 +567,7 @@ Entry.prototype.getCentralDirectoryRecord = function() {
// (omit)
} else {
versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT_UTF8;
zeiefBuffer = Buffer.allocUnsafe(0);
zeiefBuffer = EMPTY_BUFFER;
}

// central file header signature 4 bytes (0x02014b50)
Expand Down Expand Up @@ -674,7 +674,7 @@ var reverseCp437 = null;
function encodeCp437(string) {
if (/^[\x20-\x7e]*$/.test(string)) {
// CP437, ASCII, and UTF-8 overlap in this range.
return Buffer.from(string, "utf-8");
return bufferFrom(string, "utf-8");
}

// This is the slow path.
Expand All @@ -686,7 +686,7 @@ function encodeCp437(string) {
}
}

var result = Buffer.allocUnsafe(string.length);
var result = bufferAlloc(string.length);
for (var i = 0; i < string.length; i++) {
var b = reverseCp437[string[i]];
if (b == null) throw new Error("character not encodable in CP437: " + JSON.stringify(string[i]));
Expand All @@ -695,3 +695,55 @@ function encodeCp437(string) {

return result;
}

function bufferAlloc(size) {
bufferAlloc = modern;
try {
return bufferAlloc(size);
} catch (e) {
bufferAlloc = legacy;
return bufferAlloc(size);
}
function modern(size) {
return Buffer.allocUnsafe(size);
}
function legacy(size) {
return new Buffer(size);
}
}
function bufferFrom(something, encoding) {
bufferFrom = modern;
try {
return bufferFrom(something, encoding);
} catch (e) {
bufferFrom = legacy;
return bufferFrom(something, encoding);
}
function modern(something, encoding) {
return Buffer.from(something, encoding);
}
function legacy(something, encoding) {
return new Buffer(something, encoding);
}
}
function bufferIncludes(buffer, content) {
bufferIncludes = modern;
try {
return bufferIncludes(buffer, content);
} catch (e) {
bufferIncludes = legacy;
return bufferIncludes(buffer, content);
}
function modern(buffer, content) {
return buffer.includes(content);
}
function legacy(buffer, content) {
for (var i = 0; i <= buffer.length - content.length; i++) {
for (var j = 0;; j++) {
if (j === content.length) return true;
if (buffer[i + j] !== content[j]) break;
}
}
return false;
}
}
32 changes: 24 additions & 8 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var BufferList = require("bl");
options.forceZip64Format = !!zip64Config[1];
zipfile.addFile(__filename, "fdsa.txt", options);
options.forceZip64Format = !!zip64Config[2];
zipfile.addBuffer(Buffer.from("buffer"), "buffer.txt", options);
zipfile.addBuffer(bufferFrom("buffer"), "buffer.txt", options);
options.forceZip64Format = !!zip64Config[3];
options.size = "stream".length;
zipfile.addReadStream(new BufferList().append("stream"), "stream.txt", options);
Expand All @@ -76,7 +76,7 @@ var BufferList = require("bl");
var zipfile = new yazl.ZipFile();
// all options parameters are optional
zipfile.addFile(__filename, "a.txt");
zipfile.addBuffer(Buffer.from("buffer"), "b.txt");
zipfile.addBuffer(bufferFrom("buffer"), "b.txt");
zipfile.addReadStream(new BufferList().append("stream"), "c.txt");
zipfile.addEmptyDirectory("d/");
zipfile.addEmptyDirectory("e");
Expand Down Expand Up @@ -104,7 +104,7 @@ var BufferList = require("bl");
(function() {
var zipfile = new yazl.ZipFile();
// all options parameters are optional
zipfile.addBuffer(Buffer.from("hello"), "hello.txt", {compress: false});
zipfile.addBuffer(bufferFrom("hello"), "hello.txt", {compress: false});
zipfile.end(function(finalSize) {
if (finalSize === -1) throw new Error("finalSize should be known");
zipfile.outputStream.pipe(new BufferList(function(err, data) {
Expand All @@ -131,7 +131,7 @@ var weirdChars = '\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕
(function() {
var testCases = [
["Hello World", "Hello World"],
[Buffer.from("Hello"), "Hello"],
[bufferFrom("Hello"), "Hello"],
[weirdChars, weirdChars],
];
testCases.forEach(function(testCase, i) {
Expand Down Expand Up @@ -159,10 +159,10 @@ var weirdChars = '\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕
var zipfile = new yazl.ZipFile();
try {
zipfile.end({
comment: Buffer.from("\x50\x4b\x05\x06" + "01234567890123456789")
comment: bufferFrom("01234567890123456789" + "\x50\x4b\x05\x06" + "01234567890123456789")
});
} catch (e) {
if (e.toString().indexOf("comment contains end of central directory record signature")) {
if (e.toString().indexOf("comment contains end of central directory record signature") !== -1) {
console.log("block eocdr signature in comment: pass");
return;
}
Expand All @@ -173,13 +173,13 @@ var weirdChars = '\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕
(function() {
var testCases = [
["Hello World!", "Hello World!"],
[Buffer.from("Hello!"), "Hello!"],
[bufferFrom("Hello!"), "Hello!"],
[weirdChars, weirdChars],
];
testCases.forEach(function(testCase, i) {
var zipfile = new yazl.ZipFile();
// all options parameters are optional
zipfile.addBuffer(Buffer.from("hello"), "hello.txt", {compress: false, fileComment: testCase[0]});
zipfile.addBuffer(bufferFrom("hello"), "hello.txt", {compress: false, fileComment: testCase[0]});
zipfile.end(function(finalSize) {
if (finalSize === -1) throw new Error("finalSize should be known");
zipfile.outputStream.pipe(new BufferList(function(err, data) {
Expand All @@ -202,3 +202,19 @@ var weirdChars = '\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕
});
});
})();

function bufferFrom(something, encoding) {
bufferFrom = modern;
try {
return bufferFrom(something, encoding);
} catch (e) {
bufferFrom = legacy;
return bufferFrom(something, encoding);
}
function modern(something, encoding) {
return Buffer.from(something, encoding);
}
function legacy(something, encoding) {
return new Buffer(something, encoding);
}
}