Show More
Commit Description:
prevent multiple place login using uuid cookie
Commit Description:
prevent multiple place login using uuid cookie
References:
File last commit:
Show/Diff file:
Action:
node_modules/jszip/lib/zipEntry.js
| 292 lines
| 11.0 KiB
| application/javascript
| JavascriptLexer
|
r789 | 'use strict'; | |||
var readerFor = require('./reader/readerFor'); | ||||
var utils = require('./utils'); | ||||
var CompressedObject = require('./compressedObject'); | ||||
var crc32fn = require('./crc32'); | ||||
var utf8 = require('./utf8'); | ||||
var compressions = require('./compressions'); | ||||
var support = require('./support'); | ||||
var MADE_BY_DOS = 0x00; | ||||
var MADE_BY_UNIX = 0x03; | ||||
/** | ||||
* Find a compression registered in JSZip. | ||||
* @param {string} compressionMethod the method magic to find. | ||||
* @return {Object|null} the JSZip compression object, null if none found. | ||||
*/ | ||||
var findCompression = function(compressionMethod) { | ||||
for (var method in compressions) { | ||||
if (!compressions.hasOwnProperty(method)) { | ||||
continue; | ||||
} | ||||
if (compressions[method].magic === compressionMethod) { | ||||
return compressions[method]; | ||||
} | ||||
} | ||||
return null; | ||||
}; | ||||
// class ZipEntry {{{ | ||||
/** | ||||
* An entry in the zip file. | ||||
* @constructor | ||||
* @param {Object} options Options of the current file. | ||||
* @param {Object} loadOptions Options for loading the stream. | ||||
*/ | ||||
function ZipEntry(options, loadOptions) { | ||||
this.options = options; | ||||
this.loadOptions = loadOptions; | ||||
} | ||||
ZipEntry.prototype = { | ||||
/** | ||||
* say if the file is encrypted. | ||||
* @return {boolean} true if the file is encrypted, false otherwise. | ||||
*/ | ||||
isEncrypted: function() { | ||||
// bit 1 is set | ||||
return (this.bitFlag & 0x0001) === 0x0001; | ||||
}, | ||||
/** | ||||
* say if the file has utf-8 filename/comment. | ||||
* @return {boolean} true if the filename/comment is in utf-8, false otherwise. | ||||
*/ | ||||
useUTF8: function() { | ||||
// bit 11 is set | ||||
return (this.bitFlag & 0x0800) === 0x0800; | ||||
}, | ||||
/** | ||||
* Read the local part of a zip file and add the info in this object. | ||||
* @param {DataReader} reader the reader to use. | ||||
*/ | ||||
readLocalPart: function(reader) { | ||||
var compression, localExtraFieldsLength; | ||||
// we already know everything from the central dir ! | ||||
// If the central dir data are false, we are doomed. | ||||
// On the bright side, the local part is scary : zip64, data descriptors, both, etc. | ||||
// The less data we get here, the more reliable this should be. | ||||
// Let's skip the whole header and dash to the data ! | ||||
reader.skip(22); | ||||
// in some zip created on windows, the filename stored in the central dir contains \ instead of /. | ||||
// Strangely, the filename here is OK. | ||||
// I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes | ||||
// or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... | ||||
// Search "unzip mismatching "local" filename continuing with "central" filename version" on | ||||
// the internet. | ||||
// | ||||
// I think I see the logic here : the central directory is used to display | ||||
// content and the local directory is used to extract the files. Mixing / and \ | ||||
// may be used to display \ to windows users and use / when extracting the files. | ||||
// Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 | ||||
this.fileNameLength = reader.readInt(2); | ||||
localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir | ||||
// the fileName is stored as binary data, the handleUTF8 method will take care of the encoding. | ||||
this.fileName = reader.readData(this.fileNameLength); | ||||
reader.skip(localExtraFieldsLength); | ||||
if (this.compressedSize === -1 || this.uncompressedSize === -1) { | ||||
throw new Error("Bug or corrupted zip : didn't get enough information from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)"); | ||||
} | ||||
compression = findCompression(this.compressionMethod); | ||||
if (compression === null) { // no compression found | ||||
throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")"); | ||||
} | ||||
this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize)); | ||||
}, | ||||
/** | ||||
* Read the central part of a zip file and add the info in this object. | ||||
* @param {DataReader} reader the reader to use. | ||||
*/ | ||||
readCentralPart: function(reader) { | ||||
this.versionMadeBy = reader.readInt(2); | ||||
reader.skip(2); | ||||
// this.versionNeeded = reader.readInt(2); | ||||
this.bitFlag = reader.readInt(2); | ||||
this.compressionMethod = reader.readString(2); | ||||
this.date = reader.readDate(); | ||||
this.crc32 = reader.readInt(4); | ||||
this.compressedSize = reader.readInt(4); | ||||
this.uncompressedSize = reader.readInt(4); | ||||
var fileNameLength = reader.readInt(2); | ||||
this.extraFieldsLength = reader.readInt(2); | ||||
this.fileCommentLength = reader.readInt(2); | ||||
this.diskNumberStart = reader.readInt(2); | ||||
this.internalFileAttributes = reader.readInt(2); | ||||
this.externalFileAttributes = reader.readInt(4); | ||||
this.localHeaderOffset = reader.readInt(4); | ||||
if (this.isEncrypted()) { | ||||
throw new Error("Encrypted zip are not supported"); | ||||
} | ||||
// will be read in the local part, see the comments there | ||||
reader.skip(fileNameLength); | ||||
this.readExtraFields(reader); | ||||
this.parseZIP64ExtraField(reader); | ||||
this.fileComment = reader.readData(this.fileCommentLength); | ||||
}, | ||||
/** | ||||
* Parse the external file attributes and get the unix/dos permissions. | ||||
*/ | ||||
processAttributes: function () { | ||||
this.unixPermissions = null; | ||||
this.dosPermissions = null; | ||||
var madeBy = this.versionMadeBy >> 8; | ||||
// Check if we have the DOS directory flag set. | ||||
// We look for it in the DOS and UNIX permissions | ||||
// but some unknown platform could set it as a compatibility flag. | ||||
this.dir = this.externalFileAttributes & 0x0010 ? true : false; | ||||
if(madeBy === MADE_BY_DOS) { | ||||
// first 6 bits (0 to 5) | ||||
this.dosPermissions = this.externalFileAttributes & 0x3F; | ||||
} | ||||
if(madeBy === MADE_BY_UNIX) { | ||||
this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; | ||||
// the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); | ||||
} | ||||
// fail safe : if the name ends with a / it probably means a folder | ||||
if (!this.dir && this.fileNameStr.slice(-1) === '/') { | ||||
this.dir = true; | ||||
} | ||||
}, | ||||
/** | ||||
* Parse the ZIP64 extra field and merge the info in the current ZipEntry. | ||||
* @param {DataReader} reader the reader to use. | ||||
*/ | ||||
parseZIP64ExtraField: function(reader) { | ||||
if (!this.extraFields[0x0001]) { | ||||
return; | ||||
} | ||||
// should be something, preparing the extra reader | ||||
var extraReader = readerFor(this.extraFields[0x0001].value); | ||||
// I really hope that these 64bits integer can fit in 32 bits integer, because js | ||||
// won't let us have more. | ||||
if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { | ||||
this.uncompressedSize = extraReader.readInt(8); | ||||
} | ||||
if (this.compressedSize === utils.MAX_VALUE_32BITS) { | ||||
this.compressedSize = extraReader.readInt(8); | ||||
} | ||||
if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { | ||||
this.localHeaderOffset = extraReader.readInt(8); | ||||
} | ||||
if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { | ||||
this.diskNumberStart = extraReader.readInt(4); | ||||
} | ||||
}, | ||||
/** | ||||
* Read the central part of a zip file and add the info in this object. | ||||
* @param {DataReader} reader the reader to use. | ||||
*/ | ||||
readExtraFields: function(reader) { | ||||
var end = reader.index + this.extraFieldsLength, | ||||
extraFieldId, | ||||
extraFieldLength, | ||||
extraFieldValue; | ||||
if (!this.extraFields) { | ||||
this.extraFields = {}; | ||||
} | ||||
while (reader.index < end) { | ||||
extraFieldId = reader.readInt(2); | ||||
extraFieldLength = reader.readInt(2); | ||||
extraFieldValue = reader.readData(extraFieldLength); | ||||
this.extraFields[extraFieldId] = { | ||||
id: extraFieldId, | ||||
length: extraFieldLength, | ||||
value: extraFieldValue | ||||
}; | ||||
} | ||||
}, | ||||
/** | ||||
* Apply an UTF8 transformation if needed. | ||||
*/ | ||||
handleUTF8: function() { | ||||
var decodeParamType = support.uint8array ? "uint8array" : "array"; | ||||
if (this.useUTF8()) { | ||||
this.fileNameStr = utf8.utf8decode(this.fileName); | ||||
this.fileCommentStr = utf8.utf8decode(this.fileComment); | ||||
} else { | ||||
var upath = this.findExtraFieldUnicodePath(); | ||||
if (upath !== null) { | ||||
this.fileNameStr = upath; | ||||
} else { | ||||
// ASCII text or unsupported code page | ||||
var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName); | ||||
this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray); | ||||
} | ||||
var ucomment = this.findExtraFieldUnicodeComment(); | ||||
if (ucomment !== null) { | ||||
this.fileCommentStr = ucomment; | ||||
} else { | ||||
// ASCII text or unsupported code page | ||||
var commentByteArray = utils.transformTo(decodeParamType, this.fileComment); | ||||
this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray); | ||||
} | ||||
} | ||||
}, | ||||
/** | ||||
* Find the unicode path declared in the extra field, if any. | ||||
* @return {String} the unicode path, null otherwise. | ||||
*/ | ||||
findExtraFieldUnicodePath: function() { | ||||
var upathField = this.extraFields[0x7075]; | ||||
if (upathField) { | ||||
var extraReader = readerFor(upathField.value); | ||||
// wrong version | ||||
if (extraReader.readInt(1) !== 1) { | ||||
return null; | ||||
} | ||||
// the crc of the filename changed, this field is out of date. | ||||
if (crc32fn(this.fileName) !== extraReader.readInt(4)) { | ||||
return null; | ||||
} | ||||
return utf8.utf8decode(extraReader.readData(upathField.length - 5)); | ||||
} | ||||
return null; | ||||
}, | ||||
/** | ||||
* Find the unicode comment declared in the extra field, if any. | ||||
* @return {String} the unicode comment, null otherwise. | ||||
*/ | ||||
findExtraFieldUnicodeComment: function() { | ||||
var ucommentField = this.extraFields[0x6375]; | ||||
if (ucommentField) { | ||||
var extraReader = readerFor(ucommentField.value); | ||||
// wrong version | ||||
if (extraReader.readInt(1) !== 1) { | ||||
return null; | ||||
} | ||||
// the crc of the comment changed, this field is out of date. | ||||
if (crc32fn(this.fileComment) !== extraReader.readInt(4)) { | ||||
return null; | ||||
} | ||||
return utf8.utf8decode(extraReader.readData(ucommentField.length - 5)); | ||||
} | ||||
return null; | ||||
} | ||||
}; | ||||
module.exports = ZipEntry; | ||||