You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					414 lines
				
				8.3 KiB
			
		
		
			
		
	
	
					414 lines
				
				8.3 KiB
			| 
											2 years ago
										 | /** | ||
|  |  * node-compress-commons | ||
|  |  * | ||
|  |  * Copyright (c) 2014 Chris Talkington, contributors. | ||
|  |  * Licensed under the MIT license. | ||
|  |  * https://github.com/archiverjs/node-compress-commons/blob/master/LICENSE-MIT
 | ||
|  |  */ | ||
|  | var inherits = require('util').inherits; | ||
|  | var normalizePath = require('normalize-path'); | ||
|  | 
 | ||
|  | var ArchiveEntry = require('../archive-entry'); | ||
|  | var GeneralPurposeBit = require('./general-purpose-bit'); | ||
|  | var UnixStat = require('./unix-stat'); | ||
|  | 
 | ||
|  | var constants = require('./constants'); | ||
|  | var zipUtil = require('./util'); | ||
|  | 
 | ||
|  | var ZipArchiveEntry = module.exports = function(name) { | ||
|  |   if (!(this instanceof ZipArchiveEntry)) { | ||
|  |     return new ZipArchiveEntry(name); | ||
|  |   } | ||
|  | 
 | ||
|  |   ArchiveEntry.call(this); | ||
|  | 
 | ||
|  |   this.platform = constants.PLATFORM_FAT; | ||
|  |   this.method = -1; | ||
|  | 
 | ||
|  |   this.name = null; | ||
|  |   this.size = 0; | ||
|  |   this.csize = 0; | ||
|  |   this.gpb = new GeneralPurposeBit(); | ||
|  |   this.crc = 0; | ||
|  |   this.time = -1; | ||
|  | 
 | ||
|  |   this.minver = constants.MIN_VERSION_INITIAL; | ||
|  |   this.mode = -1; | ||
|  |   this.extra = null; | ||
|  |   this.exattr = 0; | ||
|  |   this.inattr = 0; | ||
|  |   this.comment = null; | ||
|  | 
 | ||
|  |   if (name) { | ||
|  |     this.setName(name); | ||
|  |   } | ||
|  | }; | ||
|  | 
 | ||
|  | inherits(ZipArchiveEntry, ArchiveEntry); | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the extra fields related to the entry. | ||
|  |  * | ||
|  |  * @returns {Buffer} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getCentralDirectoryExtra = function() { | ||
|  |   return this.getExtra(); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the comment set for the entry. | ||
|  |  * | ||
|  |  * @returns {string} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getComment = function() { | ||
|  |   return this.comment !== null ? this.comment : ''; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the compressed size of the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getCompressedSize = function() { | ||
|  |   return this.csize; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the CRC32 digest for the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getCrc = function() { | ||
|  |   return this.crc; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the external file attributes for the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getExternalAttributes = function() { | ||
|  |   return this.exattr; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the extra fields related to the entry. | ||
|  |  * | ||
|  |  * @returns {Buffer} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getExtra = function() { | ||
|  |   return this.extra !== null ? this.extra : constants.EMPTY; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the general purpose bits related to the entry. | ||
|  |  * | ||
|  |  * @returns {GeneralPurposeBit} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getGeneralPurposeBit = function() { | ||
|  |   return this.gpb; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the internal file attributes for the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getInternalAttributes = function() { | ||
|  |   return this.inattr; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the last modified date of the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getLastModifiedDate = function() { | ||
|  |   return this.getTime(); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the extra fields related to the entry. | ||
|  |  * | ||
|  |  * @returns {Buffer} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getLocalFileDataExtra = function() { | ||
|  |   return this.getExtra(); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the compression method used on the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getMethod = function() { | ||
|  |   return this.method; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the filename of the entry. | ||
|  |  * | ||
|  |  * @returns {string} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getName = function() { | ||
|  |   return this.name; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the platform on which the entry was made. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getPlatform = function() { | ||
|  |   return this.platform; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the size of the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getSize = function() { | ||
|  |   return this.size; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns a date object representing the last modified date of the entry. | ||
|  |  * | ||
|  |  * @returns {number|Date} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getTime = function() { | ||
|  |   return this.time !== -1 ? zipUtil.dosToDate(this.time) : -1; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the DOS timestamp for the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getTimeDos = function() { | ||
|  |   return this.time !== -1 ? this.time : 0; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the UNIX file permissions for the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getUnixMode = function() { | ||
|  |   return this.platform !== constants.PLATFORM_UNIX ? 0 : ((this.getExternalAttributes() >> constants.SHORT_SHIFT) & constants.SHORT_MASK); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns the version of ZIP needed to extract the entry. | ||
|  |  * | ||
|  |  * @returns {number} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.getVersionNeededToExtract = function() { | ||
|  |   return this.minver; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the comment of the entry. | ||
|  |  * | ||
|  |  * @param comment | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setComment = function(comment) { | ||
|  |   if (Buffer.byteLength(comment) !== comment.length) { | ||
|  |     this.getGeneralPurposeBit().useUTF8ForNames(true); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.comment = comment; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the compressed size of the entry. | ||
|  |  * | ||
|  |  * @param size | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setCompressedSize = function(size) { | ||
|  |   if (size < 0) { | ||
|  |     throw new Error('invalid entry compressed size'); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.csize = size; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the checksum of the entry. | ||
|  |  * | ||
|  |  * @param crc | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setCrc = function(crc) { | ||
|  |   if (crc < 0) { | ||
|  |     throw new Error('invalid entry crc32'); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.crc = crc; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the external file attributes of the entry. | ||
|  |  * | ||
|  |  * @param attr | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setExternalAttributes = function(attr) { | ||
|  |   this.exattr = attr >>> 0; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the extra fields related to the entry. | ||
|  |  * | ||
|  |  * @param extra | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setExtra = function(extra) { | ||
|  |   this.extra = extra; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the general purpose bits related to the entry. | ||
|  |  * | ||
|  |  * @param gpb | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setGeneralPurposeBit = function(gpb) { | ||
|  |   if (!(gpb instanceof GeneralPurposeBit)) { | ||
|  |     throw new Error('invalid entry GeneralPurposeBit'); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.gpb = gpb; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the internal file attributes of the entry. | ||
|  |  * | ||
|  |  * @param attr | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setInternalAttributes = function(attr) { | ||
|  |   this.inattr = attr; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the compression method of the entry. | ||
|  |  * | ||
|  |  * @param method | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setMethod = function(method) { | ||
|  |   if (method < 0) { | ||
|  |     throw new Error('invalid entry compression method'); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.method = method; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the name of the entry. | ||
|  |  * | ||
|  |  * @param name | ||
|  |  * @param prependSlash | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setName = function(name, prependSlash = false) { | ||
|  |   name = normalizePath(name, false) | ||
|  |     .replace(/^\w+:/, '') | ||
|  |     .replace(/^(\.\.\/|\/)+/, ''); | ||
|  | 
 | ||
|  |   if (prependSlash) { | ||
|  |     name = `/${name}`; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (Buffer.byteLength(name) !== name.length) { | ||
|  |     this.getGeneralPurposeBit().useUTF8ForNames(true); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.name = name; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the platform on which the entry was made. | ||
|  |  * | ||
|  |  * @param platform | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setPlatform = function(platform) { | ||
|  |   this.platform = platform; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the size of the entry. | ||
|  |  * | ||
|  |  * @param size | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setSize = function(size) { | ||
|  |   if (size < 0) { | ||
|  |     throw new Error('invalid entry size'); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.size = size; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the time of the entry. | ||
|  |  * | ||
|  |  * @param time | ||
|  |  * @param forceLocalTime | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setTime = function(time, forceLocalTime) { | ||
|  |   if (!(time instanceof Date)) { | ||
|  |     throw new Error('invalid entry time'); | ||
|  |   } | ||
|  | 
 | ||
|  |   this.time = zipUtil.dateToDos(time, forceLocalTime); | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the UNIX file permissions for the entry. | ||
|  |  * | ||
|  |  * @param mode | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setUnixMode = function(mode) { | ||
|  |   mode |= this.isDirectory() ? constants.S_IFDIR : constants.S_IFREG; | ||
|  | 
 | ||
|  |   var extattr = 0; | ||
|  |   extattr |= (mode << constants.SHORT_SHIFT) | (this.isDirectory() ? constants.S_DOS_D : constants.S_DOS_A); | ||
|  | 
 | ||
|  |   this.setExternalAttributes(extattr); | ||
|  |   this.mode = mode & constants.MODE_MASK; | ||
|  |   this.platform = constants.PLATFORM_UNIX; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Sets the version of ZIP needed to extract this entry. | ||
|  |  * | ||
|  |  * @param minver | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.setVersionNeededToExtract = function(minver) { | ||
|  |   this.minver = minver; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns true if this entry represents a directory. | ||
|  |  * | ||
|  |  * @returns {boolean} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.isDirectory = function() { | ||
|  |   return this.getName().slice(-1) === '/'; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns true if this entry represents a unix symlink, | ||
|  |  * in which case the entry's content contains the target path | ||
|  |  * for the symlink. | ||
|  |  * | ||
|  |  * @returns {boolean} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.isUnixSymlink = function() { | ||
|  |   return (this.getUnixMode() & UnixStat.FILE_TYPE_FLAG) === UnixStat.LINK_FLAG; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Returns true if this entry is using the ZIP64 extension of ZIP. | ||
|  |  * | ||
|  |  * @returns {boolean} | ||
|  |  */ | ||
|  | ZipArchiveEntry.prototype.isZip64 = function() { | ||
|  |   return this.csize > constants.ZIP64_MAGIC || this.size > constants.ZIP64_MAGIC; | ||
|  | }; |