UNPKG

playwright

Version:

A high-level API to automate web browsers

1,364 lines (1,360 loc) • 126 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); // packages/utils/third_party/yauzl/pend.js var require_pend = __commonJS({ "packages/utils/third_party/yauzl/pend.js"(exports2, module2) { "use strict"; module2.exports = Pend; function Pend() { this.pending = 0; this.max = Infinity; this.listeners = []; this.waiting = []; this.error = null; } Pend.prototype.go = function(fn) { if (this.pending < this.max) { pendGo(this, fn); } else { this.waiting.push(fn); } }; Pend.prototype.wait = function(cb) { if (this.pending === 0) { cb(this.error); } else { this.listeners.push(cb); } }; Pend.prototype.hold = function() { return pendHold(this); }; function pendHold(self) { self.pending += 1; var called = false; return onCb; function onCb(err) { if (called) throw new Error("callback called twice"); called = true; self.error = self.error || err; self.pending -= 1; if (self.waiting.length > 0 && self.pending < self.max) { pendGo(self, self.waiting.shift()); } else if (self.pending === 0) { var listeners = self.listeners; self.listeners = []; listeners.forEach(cbListener); } } function cbListener(listener) { listener(self.error); } } function pendGo(self, fn) { fn(pendHold(self)); } } }); // packages/utils/third_party/yauzl/fd-slicer.js var require_fd_slicer = __commonJS({ "packages/utils/third_party/yauzl/fd-slicer.js"(exports2) { "use strict"; var fs4 = require("fs"); var util2 = require("util"); var stream = require("stream"); var Readable = stream.Readable; var Writable = stream.Writable; var PassThrough = stream.PassThrough; var Pend = require_pend(); var EventEmitter = require("events").EventEmitter; exports2.createFromBuffer = createFromBuffer; exports2.createFromFd = createFromFd; exports2.BufferSlicer = BufferSlicer; exports2.FdSlicer = FdSlicer; util2.inherits(FdSlicer, EventEmitter); function FdSlicer(fd, options2) { options2 = options2 || {}; EventEmitter.call(this); this.fd = fd; this.pend = new Pend(); this.pend.max = 1; this.refCount = 0; this.autoClose = !!options2.autoClose; } FdSlicer.prototype.read = function(buffer, offset, length, position, callback) { var self = this; self.pend.go(function(cb) { fs4.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer2) { cb(); callback(err, bytesRead, buffer2); }); }); }; FdSlicer.prototype.write = function(buffer, offset, length, position, callback) { var self = this; self.pend.go(function(cb) { fs4.write(self.fd, buffer, offset, length, position, function(err, written, buffer2) { cb(); callback(err, written, buffer2); }); }); }; FdSlicer.prototype.createReadStream = function(options2) { return new ReadStream(this, options2); }; FdSlicer.prototype.createWriteStream = function(options2) { return new WriteStream(this, options2); }; FdSlicer.prototype.ref = function() { this.refCount += 1; }; FdSlicer.prototype.unref = function() { var self = this; self.refCount -= 1; if (self.refCount > 0) return; if (self.refCount < 0) throw new Error("invalid unref"); if (self.autoClose) { fs4.close(self.fd, onCloseDone); } function onCloseDone(err) { if (err) { self.emit("error", err); } else { self.emit("close"); } } }; util2.inherits(ReadStream, Readable); function ReadStream(context, options2) { options2 = options2 || {}; Readable.call(this, options2); this.context = context; this.context.ref(); this.start = options2.start || 0; this.endOffset = options2.end; this.pos = this.start; this._destroyed = false; } ReadStream.prototype._read = function(n) { var self = this; if (self._destroyed) return; var toRead = Math.min(self._readableState.highWaterMark, n); if (self.endOffset != null) { toRead = Math.min(toRead, self.endOffset - self.pos); } if (toRead <= 0) { self._destroyed = true; self.push(null); self.context.unref(); return; } self.context.pend.go(function(cb) { if (self._destroyed) return cb(); var buffer = Buffer.allocUnsafe(toRead); fs4.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) { if (self._destroyed) return cb(); if (err) { self.destroy(err); } else if (bytesRead === 0) { self._destroyed = true; self.push(null); self.context.unref(); } else { self.pos += bytesRead; self.push(buffer.slice(0, bytesRead)); } cb(); }); }); }; ReadStream.prototype.destroy = function(err) { if (err == null && !this.readableEnded) { err = new Error("stream destroyed"); } return Readable.prototype.destroy.call(this, err); }; ReadStream.prototype._destroy = function(err, cb) { if (!this._destroyed) { this._destroyed = true; this.context.unref(); } cb(err); }; util2.inherits(WriteStream, Writable); function WriteStream(context, options2) { options2 = options2 || {}; Writable.call(this, options2); this.context = context; this.context.ref(); this.start = options2.start || 0; this.endOffset = options2.end == null ? Infinity : +options2.end; this.bytesWritten = 0; this.pos = this.start; this._destroyed = false; this.on("finish", this.destroy.bind(this)); } WriteStream.prototype._write = function(buffer, encoding, callback) { var self = this; if (self._destroyed) return; if (self.pos + buffer.length > self.endOffset) { var err = new Error("maximum file length exceeded"); err.code = "ETOOBIG"; self.destroy(); callback(err); return; } self.context.pend.go(function(cb) { if (self._destroyed) return cb(); fs4.write(self.context.fd, buffer, 0, buffer.length, self.pos, function(err2, bytes) { if (err2) { self.destroy(); cb(); callback(err2); } else { self.bytesWritten += bytes; self.pos += bytes; self.emit("progress"); cb(); callback(); } }); }); }; WriteStream.prototype._destroy = function(err, cb) { if (!this._destroyed) { this._destroyed = true; this.context.unref(); } cb(err); }; util2.inherits(BufferSlicer, EventEmitter); function BufferSlicer(buffer, options2) { EventEmitter.call(this); options2 = options2 || {}; this.refCount = 0; this.buffer = buffer; this.maxChunkSize = options2.maxChunkSize || Number.MAX_SAFE_INTEGER; } BufferSlicer.prototype.read = function(buffer, offset, length, position, callback) { if (!(0 <= offset && offset <= buffer.length)) throw new RangeError("offset outside buffer: 0 <= " + offset + " <= " + buffer.length); if (position < 0) throw new RangeError("position is negative: " + position); if (offset + length > buffer.length) { length = buffer.length - offset; } if (position + length > this.buffer.length) { length = this.buffer.length - position; } if (length <= 0) { setImmediate(function() { callback(null, 0); }); return; } this.buffer.copy(buffer, offset, position, position + length); setImmediate(function() { callback(null, length); }); }; BufferSlicer.prototype.write = function(buffer, offset, length, position, callback) { buffer.copy(this.buffer, position, offset, offset + length); setImmediate(function() { callback(null, length, buffer); }); }; BufferSlicer.prototype.createReadStream = function(options2) { options2 = options2 || {}; var readStream = new PassThrough(options2); readStream._destroyed = false; readStream.start = options2.start || 0; readStream.endOffset = options2.end; readStream.pos = readStream.endOffset || this.buffer.length; var entireSlice = this.buffer.slice(readStream.start, readStream.pos); var offset = 0; while (true) { var nextOffset = offset + this.maxChunkSize; if (nextOffset >= entireSlice.length) { if (offset < entireSlice.length) { readStream.write(entireSlice.slice(offset, entireSlice.length)); } break; } readStream.write(entireSlice.slice(offset, nextOffset)); offset = nextOffset; } readStream.end(); readStream._destroy = function(err, cb) { readStream._destroyed = true; PassThrough.prototype._destroy.call(readStream, err, cb); }; return readStream; }; BufferSlicer.prototype.createWriteStream = function(options2) { var bufferSlicer = this; options2 = options2 || {}; var writeStream = new Writable(options2); writeStream.start = options2.start || 0; writeStream.endOffset = options2.end == null ? this.buffer.length : +options2.end; writeStream.bytesWritten = 0; writeStream.pos = writeStream.start; writeStream._destroyed = false; writeStream._write = function(buffer, encoding, callback) { if (writeStream._destroyed) return; var end = writeStream.pos + buffer.length; if (end > writeStream.endOffset) { var err = new Error("maximum file length exceeded"); err.code = "ETOOBIG"; writeStream._destroyed = true; callback(err); return; } buffer.copy(bufferSlicer.buffer, writeStream.pos, 0, buffer.length); writeStream.bytesWritten += buffer.length; writeStream.pos = end; writeStream.emit("progress"); callback(); }; writeStream._destroy = function(err, cb) { writeStream._destroyed = true; cb(err); }; return writeStream; }; BufferSlicer.prototype.ref = function() { this.refCount += 1; }; BufferSlicer.prototype.unref = function() { this.refCount -= 1; if (this.refCount < 0) { throw new Error("invalid unref"); } }; function createFromBuffer(buffer, options2) { return new BufferSlicer(buffer, options2); } function createFromFd(fd, options2) { return new FdSlicer(fd, options2); } } }); // packages/utils/third_party/yauzl/buffer-crc32.js var require_buffer_crc32 = __commonJS({ "packages/utils/third_party/yauzl/buffer-crc32.js"(exports2, module2) { "use strict"; var Buffer2 = require("buffer").Buffer; var CRC_TABLE = [ 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918e3, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117 ]; if (typeof Int32Array !== "undefined") { CRC_TABLE = new Int32Array(CRC_TABLE); } function ensureBuffer(input) { if (Buffer2.isBuffer(input)) { return input; } var hasNewBufferAPI = typeof Buffer2.alloc === "function" && typeof Buffer2.from === "function"; if (typeof input === "number") { return hasNewBufferAPI ? Buffer2.alloc(input) : new Buffer2(input); } else if (typeof input === "string") { return hasNewBufferAPI ? Buffer2.from(input) : new Buffer2(input); } else { throw new Error("input must be buffer, number, or string, received " + typeof input); } } function bufferizeInt(num) { var tmp = ensureBuffer(4); tmp.writeInt32BE(num, 0); return tmp; } function _crc32(buf, previous) { buf = ensureBuffer(buf); if (Buffer2.isBuffer(previous)) { previous = previous.readUInt32BE(0); } var crc = ~~previous ^ -1; for (var n = 0; n < buf.length; n++) { crc = CRC_TABLE[(crc ^ buf[n]) & 255] ^ crc >>> 8; } return crc ^ -1; } function crc32() { return bufferizeInt(_crc32.apply(null, arguments)); } crc32.signed = function() { return _crc32.apply(null, arguments); }; crc32.unsigned = function() { return _crc32.apply(null, arguments) >>> 0; }; module2.exports = crc32; } }); // packages/utils/third_party/yauzl/index.js var require_yauzl = __commonJS({ "packages/utils/third_party/yauzl/index.js"(exports2) { "use strict"; var fs4 = require("fs"); var zlib = require("zlib"); var fd_slicer = require_fd_slicer(); var crc32 = require_buffer_crc32(); var util2 = require("util"); var EventEmitter = require("events").EventEmitter; var Transform = require("stream").Transform; var PassThrough = require("stream").PassThrough; var Writable = require("stream").Writable; exports2.open = open2; exports2.fromFd = fromFd; exports2.fromBuffer = fromBuffer; exports2.fromRandomAccessReader = fromRandomAccessReader; exports2.dosDateTimeToDate = dosDateTimeToDate; exports2.getFileNameLowLevel = getFileNameLowLevel; exports2.validateFileName = validateFileName; exports2.parseExtraFields = parseExtraFields; exports2.ZipFile = ZipFile; exports2.Entry = Entry; exports2.LocalFileHeader = LocalFileHeader; exports2.RandomAccessReader = RandomAccessReader; function open2(path4, options2, callback) { if (typeof options2 === "function") { callback = options2; options2 = null; } if (options2 == null) options2 = {}; if (options2.autoClose == null) options2.autoClose = true; if (options2.lazyEntries == null) options2.lazyEntries = false; if (options2.decodeStrings == null) options2.decodeStrings = true; if (options2.validateEntrySizes == null) options2.validateEntrySizes = true; if (options2.strictFileNames == null) options2.strictFileNames = false; if (callback == null) callback = defaultCallback; fs4.open(path4, "r", function(err, fd) { if (err) return callback(err); fromFd(fd, options2, function(err2, zipfile) { if (err2) fs4.close(fd, defaultCallback); callback(err2, zipfile); }); }); } function fromFd(fd, options2, callback) { if (typeof options2 === "function") { callback = options2; options2 = null; } if (options2 == null) options2 = {}; if (options2.autoClose == null) options2.autoClose = false; if (options2.lazyEntries == null) options2.lazyEntries = false; if (options2.decodeStrings == null) options2.decodeStrings = true; if (options2.validateEntrySizes == null) options2.validateEntrySizes = true; if (options2.strictFileNames == null) options2.strictFileNames = false; if (callback == null) callback = defaultCallback; fs4.fstat(fd, function(err, stats) { if (err) return callback(err); var reader = fd_slicer.createFromFd(fd, { autoClose: true }); fromRandomAccessReader(reader, stats.size, options2, callback); }); } function fromBuffer(buffer, options2, callback) { if (typeof options2 === "function") { callback = options2; options2 = null; } if (options2 == null) options2 = {}; options2.autoClose = false; if (options2.lazyEntries == null) options2.lazyEntries = false; if (options2.decodeStrings == null) options2.decodeStrings = true; if (options2.validateEntrySizes == null) options2.validateEntrySizes = true; if (options2.strictFileNames == null) options2.strictFileNames = false; var reader = fd_slicer.createFromBuffer(buffer, { maxChunkSize: 65536 }); fromRandomAccessReader(reader, buffer.length, options2, callback); } function fromRandomAccessReader(reader, totalSize, options2, callback) { if (typeof options2 === "function") { callback = options2; options2 = null; } if (options2 == null) options2 = {}; if (options2.autoClose == null) options2.autoClose = true; if (options2.lazyEntries == null) options2.lazyEntries = false; if (options2.decodeStrings == null) options2.decodeStrings = true; var decodeStrings = !!options2.decodeStrings; if (options2.validateEntrySizes == null) options2.validateEntrySizes = true; if (options2.strictFileNames == null) options2.strictFileNames = false; if (callback == null) callback = defaultCallback; if (typeof totalSize !== "number") throw new Error("expected totalSize parameter to be a number"); if (totalSize > Number.MAX_SAFE_INTEGER) { throw new Error("zip file too large. only file sizes up to 2^52 are supported due to JavaScript's Number type being an IEEE 754 double."); } reader.ref(); var eocdrWithoutCommentSize = 22; var zip64EocdlSize = 20; var maxCommentSize = 65535; var bufferSize = Math.min(zip64EocdlSize + eocdrWithoutCommentSize + maxCommentSize, totalSize); var buffer = newBuffer(bufferSize); var bufferReadStart = totalSize - buffer.length; readAndAssertNoEof(reader, buffer, 0, bufferSize, bufferReadStart, function(err) { if (err) return callback(err); for (var i = bufferSize - eocdrWithoutCommentSize; i >= 0; i -= 1) { if (buffer.readUInt32LE(i) !== 101010256) continue; var eocdrBuffer = buffer.subarray(i); var diskNumber = eocdrBuffer.readUInt16LE(4); var entryCount = eocdrBuffer.readUInt16LE(10); var centralDirectoryOffset = eocdrBuffer.readUInt32LE(16); var commentLength = eocdrBuffer.readUInt16LE(20); var expectedCommentLength = eocdrBuffer.length - eocdrWithoutCommentSize; if (commentLength !== expectedCommentLength) { return callback(new Error("Invalid comment length. Expected: " + expectedCommentLength + ". Found: " + commentLength + ". Are there extra bytes at the end of the file? Or is the end of central dir signature `PK\u263A\u263B` in the comment?")); } var comment = decodeStrings ? decodeBuffer(eocdrBuffer.subarray(22), false) : eocdrBuffer.subarray(22); if (i - zip64EocdlSize >= 0 && buffer.readUInt32LE(i - zip64EocdlSize) === 117853008) { var zip64EocdlBuffer = buffer.subarray(i - zip64EocdlSize, i - zip64EocdlSize + zip64EocdlSize); var zip64EocdrOffset = readUInt64LE(zip64EocdlBuffer, 8); var zip64EocdrBuffer = newBuffer(56); return readAndAssertNoEof(reader, zip64EocdrBuffer, 0, zip64EocdrBuffer.length, zip64EocdrOffset, function(err2) { if (err2) return callback(err2); if (zip64EocdrBuffer.readUInt32LE(0) !== 101075792) { return callback(new Error("invalid zip64 end of central directory record signature")); } diskNumber = zip64EocdrBuffer.readUInt32LE(16); if (diskNumber !== 0) { return callback(new Error("multi-disk zip files are not supported: found disk number: " + diskNumber)); } entryCount = readUInt64LE(zip64EocdrBuffer, 32); centralDirectoryOffset = readUInt64LE(zip64EocdrBuffer, 48); return callback(null, new ZipFile(reader, centralDirectoryOffset, totalSize, entryCount, comment, options2.autoClose, options2.lazyEntries, decodeStrings, options2.validateEntrySizes, options2.strictFileNames)); }); } if (diskNumber !== 0) { return callback(new Error("multi-disk zip files are not supported: found disk number: " + diskNumber)); } return callback(null, new ZipFile(reader, centralDirectoryOffset, totalSize, entryCount, comment, options2.autoClose, options2.lazyEntries, decodeStrings, options2.validateEntrySizes, options2.strictFileNames)); } callback(new Error("End of central directory record signature not found. Either not a zip file, or file is truncated.")); }); } util2.inherits(ZipFile, EventEmitter); function ZipFile(reader, centralDirectoryOffset, fileSize, entryCount, comment, autoClose, lazyEntries, decodeStrings, validateEntrySizes, strictFileNames) { var self = this; EventEmitter.call(self); self.reader = reader; self.reader.on("error", function(err) { emitError(self, err); }); self.reader.once("close", function() { self.emit("close"); }); self.readEntryCursor = centralDirectoryOffset; self.fileSize = fileSize; self.entryCount = entryCount; self.comment = comment; self.entriesRead = 0; self.autoClose = !!autoClose; self.lazyEntries = !!lazyEntries; self.decodeStrings = !!decodeStrings; self.validateEntrySizes = !!validateEntrySizes; self.strictFileNames = !!strictFileNames; self.isOpen = true; self.emittedError = false; if (!self.lazyEntries) self._readEntry(); } ZipFile.prototype.close = function() { if (!this.isOpen) return; this.isOpen = false; this.reader.unref(); }; function emitErrorAndAutoClose(self, err) { if (self.autoClose) self.close(); emitError(self, err); } function emitError(self, err) { if (self.emittedError) return; self.emittedError = true; self.emit("error", err); } ZipFile.prototype.readEntry = function() { if (!this.lazyEntries) throw new Error("readEntry() called without lazyEntries:true"); this._readEntry(); }; ZipFile.prototype._readEntry = function() { var self = this; if (self.entryCount === self.entriesRead) { setImmediate(function() { if (self.autoClose) self.close(); if (self.emittedError) return; self.emit("end"); }); return; } if (self.emittedError) return; var buffer = newBuffer(46); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, self.readEntryCursor, function(err) { if (err) return emitErrorAndAutoClose(self, err); if (self.emittedError) return; var entry = new Entry(); var signature = buffer.readUInt32LE(0); if (signature !== 33639248) return emitErrorAndAutoClose(self, new Error("invalid central directory file header signature: 0x" + signature.toString(16))); entry.versionMadeBy = buffer.readUInt16LE(4); entry.versionNeededToExtract = buffer.readUInt16LE(6); entry.generalPurposeBitFlag = buffer.readUInt16LE(8); entry.compressionMethod = buffer.readUInt16LE(10); entry.lastModFileTime = buffer.readUInt16LE(12); entry.lastModFileDate = buffer.readUInt16LE(14); entry.crc32 = buffer.readUInt32LE(16); entry.compressedSize = buffer.readUInt32LE(20); entry.uncompressedSize = buffer.readUInt32LE(24); entry.fileNameLength = buffer.readUInt16LE(28); entry.extraFieldLength = buffer.readUInt16LE(30); entry.fileCommentLength = buffer.readUInt16LE(32); entry.internalFileAttributes = buffer.readUInt16LE(36); entry.externalFileAttributes = buffer.readUInt32LE(38); entry.relativeOffsetOfLocalHeader = buffer.readUInt32LE(42); if (entry.generalPurposeBitFlag & 64) return emitErrorAndAutoClose(self, new Error("strong encryption is not supported")); self.readEntryCursor += 46; buffer = newBuffer(entry.fileNameLength + entry.extraFieldLength + entry.fileCommentLength); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, self.readEntryCursor, function(err2) { if (err2) return emitErrorAndAutoClose(self, err2); if (self.emittedError) return; entry.fileNameRaw = buffer.subarray(0, entry.fileNameLength); var fileCommentStart = entry.fileNameLength + entry.extraFieldLength; entry.extraFieldRaw = buffer.subarray(entry.fileNameLength, fileCommentStart); entry.fileCommentRaw = buffer.subarray(fileCommentStart, fileCommentStart + entry.fileCommentLength); try { entry.extraFields = parseExtraFields(entry.extraFieldRaw); } catch (err3) { return emitErrorAndAutoClose(self, err3); } if (self.decodeStrings) { var isUtf8 = (entry.generalPurposeBitFlag & 2048) !== 0; entry.fileComment = decodeBuffer(entry.fileCommentRaw, isUtf8); entry.fileName = getFileNameLowLevel(entry.generalPurposeBitFlag, entry.fileNameRaw, entry.extraFields, self.strictFileNames); var errorMessage = validateFileName(entry.fileName); if (errorMessage != null) return emitErrorAndAutoClose(self, new Error(errorMessage)); } else { entry.fileComment = entry.fileCommentRaw; entry.fileName = entry.fileNameRaw; } entry.comment = entry.fileComment; self.readEntryCursor += buffer.length; self.entriesRead += 1; for (var i = 0; i < entry.extraFields.length; i++) { var extraField = entry.extraFields[i]; if (extraField.id !== 1) continue; var zip64EiefBuffer = extraField.data; var index = 0; if (entry.uncompressedSize === 4294967295) { if (index + 8 > zip64EiefBuffer.length) { return emitErrorAndAutoClose(self, new Error("zip64 extended information extra field does not include uncompressed size")); } entry.uncompressedSize = readUInt64LE(zip64EiefBuffer, index); index += 8; } if (entry.compressedSize === 4294967295) { if (index + 8 > zip64EiefBuffer.length) { return emitErrorAndAutoClose(self, new Error("zip64 extended information extra field does not include compressed size")); } entry.compressedSize = readUInt64LE(zip64EiefBuffer, index); index += 8; } if (entry.relativeOffsetOfLocalHeader === 4294967295) { if (index + 8 > zip64EiefBuffer.length) { return emitErrorAndAutoClose(self, new Error("zip64 extended information extra field does not include relative header offset")); } entry.relativeOffsetOfLocalHeader = readUInt64LE(zip64EiefBuffer, index); index += 8; } break; } if (self.validateEntrySizes && entry.compressionMethod === 0) { var expectedCompressedSize = entry.uncompressedSize; if (entry.isEncrypted()) { expectedCompressedSize += 12; } if (entry.compressedSize !== expectedCompressedSize) { var msg = "compressed/uncompressed size mismatch for stored file: " + entry.compressedSize + " != " + entry.uncompressedSize; return emitErrorAndAutoClose(self, new Error(msg)); } } self.emit("entry", entry); if (!self.lazyEntries) self._readEntry(); }); }); }; ZipFile.prototype.openReadStream = function(entry, options2, callback) { var self = this; var relativeStart = 0; var relativeEnd = entry.compressedSize; if (callback == null) { callback = options2; options2 = null; } if (options2 == null) { options2 = {}; } else { if (options2.decrypt != null) { if (!entry.isEncrypted()) { throw new Error("options.decrypt can only be specified for encrypted entries"); } if (options2.decrypt !== false) throw new Error("invalid options.decrypt value: " + options2.decrypt); if (entry.isCompressed()) { if (options2.decompress !== false) throw new Error("entry is encrypted and compressed, and options.decompress !== false"); } } if (options2.decompress != null) { if (!entry.isCompressed()) { throw new Error("options.decompress can only be specified for compressed entries"); } if (!(options2.decompress === false || options2.decompress === true)) { throw new Error("invalid options.decompress value: " + options2.decompress); } } if (options2.start != null || options2.end != null) { if (entry.isCompressed() && options2.decompress !== false) { throw new Error("start/end range not allowed for compressed entry without options.decompress === false"); } if (entry.isEncrypted() && options2.decrypt !== false) { throw new Error("start/end range not allowed for encrypted entry without options.decrypt === false"); } } if (options2.start != null) { relativeStart = options2.start; if (relativeStart < 0) throw new Error("options.start < 0"); if (relativeStart > entry.compressedSize) throw new Error("options.start > entry.compressedSize"); } if (options2.end != null) { relativeEnd = options2.end; if (relativeEnd < 0) throw new Error("options.end < 0"); if (relativeEnd > entry.compressedSize) throw new Error("options.end > entry.compressedSize"); if (relativeEnd < relativeStart) throw new Error("options.end < options.start"); } } if (!self.isOpen) return callback(new Error("closed")); if (entry.isEncrypted()) { if (options2.decrypt !== false) return callback(new Error("entry is encrypted, and options.decrypt !== false")); } var decompress; if (entry.compressionMethod === 0) { decompress = false; } else if (entry.compressionMethod === 8) { decompress = options2.decompress != null ? options2.decompress : true; } else { return callback(new Error("unsupported compression method: " + entry.compressionMethod)); } self.readLocalFileHeader(entry, { minimal: true }, function(err, localFileHeader) { if (err) return callback(err); self.openReadStreamLowLevel( localFileHeader.fileDataStart, entry.compressedSize, relativeStart, relativeEnd, decompress, entry.uncompressedSize, callback ); }); }; ZipFile.prototype.openReadStreamLowLevel = function(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize, callback) { var self = this; var fileDataEnd = fileDataStart + compressedSize; var readStream = self.reader.createReadStream({ start: fileDataStart + relativeStart, end: fileDataStart + relativeEnd }); var endpointStream = readStream; if (decompress) { var destroyed = false; var inflateFilter = zlib.createInflateRaw(); readStream.on("error", function(err) { setImmediate(function() { if (!destroyed) inflateFilter.emit("error", err); }); }); readStream.pipe(inflateFilter); if (self.validateEntrySizes) { endpointStream = new AssertByteCountStream(uncompressedSize); inflateFilter.on("error", function(err) { setImmediate(function() { if (!destroyed) endpointStream.emit("error", err); }); }); inflateFilter.pipe(endpointStream); } else { endpointStream = inflateFilter; } installDestroyFn(endpointStream, function() { destroyed = true; if (inflateFilter !== endpointStream) inflateFilter.unpipe(endpointStream); readStream.unpipe(inflateFilter); readStream.destroy(); }); } callback(null, endpointStream); }; ZipFile.prototype.readLocalFileHeader = function(entry, options2, callback) { var self = this; if (callback == null) { callback = options2; options2 = null; } if (options2 == null) options2 = {}; self.reader.ref(); var buffer = newBuffer(30); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, entry.relativeOffsetOfLocalHeader, function(err) { try { if (err) return callback(err); var signature = buffer.readUInt32LE(0); if (signature !== 67324752) { return callback(new Error("invalid local file header signature: 0x" + signature.toString(16))); } var fileNameLength = buffer.readUInt16LE(26); var extraFieldLength = buffer.readUInt16LE(28); var fileDataStart = entry.relativeOffsetOfLocalHeader + 30 + fileNameLength + extraFieldLength; if (fileDataStart + entry.compressedSize > self.fileSize) { return callback(new Error("file data overflows file bounds: " + fileDataStart + " + " + entry.compressedSize + " > " + self.fileSize)); } if (options2.minimal) { return callback(null, { fileDataStart }); } var localFileHeader = new LocalFileHeader(); localFileHeader.fileDataStart = fileDataStart; localFileHeader.versionNeededToExtract = buffer.readUInt16LE(4); localFileHeader.generalPurposeBitFlag = buffer.readUInt16LE(6); localFileHeader.compressionMethod = buffer.readUInt16LE(8); localFileHeader.lastModFileTime = buffer.readUInt16LE(10); localFileHeader.lastModFileDate = buffer.readUInt16LE(12); localFileHeader.crc32 = buffer.readUInt32LE(14); localFileHeader.compressedSize = buffer.readUInt32LE(18); localFileHeader.uncompressedSize = buffer.readUInt32LE(22); localFileHeader.fileNameLength = fileNameLength; localFileHeader.extraFieldLength = extraFieldLength; buffer = newBuffer(fileNameLength + extraFieldLength); self.reader.ref(); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, entry.relativeOffsetOfLocalHeader + 30, function(err2) { try { if (err2) return callback(err2); localFileHeader.fileName = buffer.subarray(0, fileNameLength); localFileHeader.extraField = buffer.subarray(fileNameLength); return callback(null, localFileHeader); } finally { self.reader.unref(); } }); } finally { self.reader.unref(); } }); }; function Entry() { } Entry.prototype.getLastModDate = function(options2) { if (options2 == null) options2 = {}; if (!options2.forceDosFormat) { for (var i = 0; i < this.extraFields.length; i++) { var extraField = this.extraFields[i]; if (extraField.id === 21589) { var data = extraField.data; if (data.length < 5) continue; var flags = data[0]; var HAS_MTIME = 1; if (!(flags & HAS_MTIME)) continue; var posixTimestamp = data.readInt32LE(1); return new Date(posixTimestamp * 1e3); } else if (extraField.id === 10) { var data = extraField.data; if (data.length !== 32) continue; if (data.readUInt16LE(4) !== 1) continue; if (data.readUInt16LE(6) !== 24) continue; var hundredNanoSecondsSince1601 = data.readUInt32LE(8) + 4294967296 * data.readInt32LE(12); var millisecondsSince1970 = hundredNanoSecondsSince1601 / 1e4 - 116444736e5; return new Date(millisecondsSince1970); } } } return dosDateTimeToDate(this.lastModFileDate, this.lastModFileTime, options2.timezone); }; Entry.prototype.isEncrypted = function() { return (this.generalPurposeBitFlag & 1) !== 0; }; Entry.prototype.isCompressed = function() { return this.compressionMethod === 8; }; function LocalFileHeader() { } function dosDateTimeToDate(date, time, timezone) { var day = date & 31; var month = (date >> 5 & 15) - 1; var year = (date >> 9 & 127) + 1980; var millisecond = 0; var second = (time & 31) * 2; var minute = time >> 5 & 63; var hour = time >> 11 & 31; if (timezone == null || timezone === "local") { return new Date(year, month, day, hour, minute, second, millisecond); } else if (timezone === "UTC") { return new Date(Date.UTC(year, month, day, hour, minute, second, millisecond)); } else { throw new Error("unrecognized options.timezone: " + options.timezone); } } function getFileNameLowLevel(generalPurposeBitFlag, fileNameBuffer, extraFields, strictFileNames) { var fileName = null; for (var i = 0; i < extraFields.length; i++) { var extraField = extraFields[i]; if (extraField.id === 28789) { if (extraField.data.length < 6) { continue; } if (extraField.data.readUInt8(0) !== 1) { continue; } var oldNameCrc32 = extraField.data.readUInt32LE(1); if (crc32.unsigned(fileNameBuffer) !== oldNameCrc32) { continue; } fileName = decodeBuffer(extraField.data.subarray(5), true); break; } } if (fileName == null) { var isUtf8 = (generalPurposeBitFlag & 2048) !== 0; fileName = decodeBuffer(fileNameBuffer, isUtf8); } if (!strictFileNames) { fileName = fileName.replace(/\\/g, "/"); } return fileName; } function validateFileName(fileName) { if (fileName.indexOf("\\") !== -1) { return "invalid characters in fileName: " + fileName; } if (/^[a-zA-Z]:/.test(fileName) || /^\//.test(fileName)) { return "absolute path: " + fileName; } if (fileName.split("/").indexOf("..") !== -1) { return "invalid relative path: " + fileName; } return null; } function parseExtraFields(extraFieldBuffer) { var extraFields = []; var i = 0; while (i < extraFieldBuffer.length - 3) { var headerId = extraFieldBuffer.readUInt16LE(i + 0); var dataSize = extraFieldBuffer.readUInt16LE(i + 2); var dataStart = i + 4; var dataEnd = dataStart + dataSize; if (dataEnd > extraFieldBuffer.length) throw new Error("extra field length exceeds extra field buffer size"); var dataBuffer = extraFieldBuffer.subarray(dataStart, dataEnd); extraFields.push({ id: headerId, data: dataBuffer }); i = dataEnd; } return extraFields; } function readAndAssertNoEof(reader, buffer, offset, length, position, callback) { if (length === 0) { return setImmediate(function() { callback(null, newBuffer(0)); }); } reader.read(buffer, offset, length, position, function(err, bytesRead) { if (err) return callback(err); if (bytesRead < length) { return callback(new Error("unexpected EOF")); } callback(); }); } util2.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(); }; util2.inherits(RandomAccessReader, EventEmitter); function RandomAccessReader() { EventEmitter.call(this); this.refCount = 0; } RandomAccessReader.prototype.ref = function() { this.refCount += 1; }; RandomAccessReader.prototype.unref = function() { var self = this; self.refCount -= 1; if (self.refCount > 0) return; if (self.refCount < 0) throw new Error("invalid unref"); self.close(onCloseDone); function onCloseDone(err) { if (err) return self.emit("error", err); self.emit("close"); } }; RandomAccessReader.prototype.createReadStream = function(options2) { if (options2 == null) options2 = {}; var start = options2.start; var end = options2.end; if (start === end) { var emptyStream = new PassThrough(); setImmediate(function() { emptyStream.end(); }); return emptyStream; } var stream = this._readStreamForRange(start, end); var destroyed = false; var refUnrefFilter = new RefUnrefFilter(this); stream.on("error", function(err) { setImmediate(function() { if (!destroyed) refUnrefFilter.emit("error", err); }); }); installDestroyFn(refUnrefFilter, function() { stream.unpipe(refUnrefFilter); refUnrefFilter.unref(); stream.destroy(); }); var byteCounter = new AssertByteCountStream(end - start); refUnrefFilter.on("error", function(err) { setImmediate(function() { if (!destroyed) byteCounter.emit("error", err); }); }); installDestroyFn(byteCounter, function() { destroyed = true; refUnrefFilter.unpipe(byteCounter); refUnrefFilter.destroy(); }); return stream.pipe(refUnrefFilter).pipe(byteCounter); }; RandomAccessReader.prototype._readStreamForRange = function(start, end) { throw new Error("not implemented"); }; RandomAccessReader.prototype.read = function(buffer, offset, length, position, callback) { var readStream = this.createReadStream({ start: position, end: position + length }); var writeStream = new Writable(); var written = 0; writeStream._write = function(chunk, encoding, cb) { chunk.copy(buffer, offset + written, 0, chunk.length); written += chunk.length; cb(); }; writeStream.on("finish", callback); readStream.on("error", function(error) { callback(error); }); readStream.pipe(writeStream); }; RandomAccessReader.prototype.close = function(callback) { setImmediate(callback); }; util2.inherits(RefUnrefFilter, PassThrough); function RefUnrefFilter(context) { PassThrough.call(this); this.context = context; this.context.ref(); this.unreffedYet = false; } RefUnrefFilter.prototype._flush = function(cb) { this.unref(); cb(); }; RefUnrefFilter.prototype.unref = function(cb) { if (this.unreffedYet) return; this.unreffedYet = true; this.context.unref(); }; var cp437 = "\0\u263A\u263B\u2665\u2666\u2663\u2660\u2022\u25D8\u25CB\u25D9\u2642\u2640\u266A\u266B\u263C\u25BA\u25C4\u2195\u203C\xB6\xA7\u25AC\u21A8\u2191\u2193\u2192\u2190\u221F\u2194\u25B2\u25BC !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u2302\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\x