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.
		
		
		
		
		
			
		
			
				
					56 lines
				
				1.5 KiB
			
		
		
			
		
	
	
					56 lines
				
				1.5 KiB
			| 
											2 years ago
										 | module.exports = Extract; | ||
|  | 
 | ||
|  | var Parse = require('./parse'); | ||
|  | var Writer = require('fstream').Writer; | ||
|  | var path = require('path'); | ||
|  | var stream = require('stream'); | ||
|  | var duplexer2 = require('duplexer2'); | ||
|  | var Promise = require('bluebird'); | ||
|  | 
 | ||
|  | function Extract (opts) { | ||
|  |   // make sure path is normalized before using it
 | ||
|  |   opts.path = path.resolve(path.normalize(opts.path)); | ||
|  | 
 | ||
|  |   var parser = new Parse(opts); | ||
|  | 
 | ||
|  |   var outStream = new stream.Writable({objectMode: true}); | ||
|  |   outStream._write = function(entry, encoding, cb) { | ||
|  | 
 | ||
|  |     if (entry.type == 'Directory') return cb(); | ||
|  | 
 | ||
|  |     // to avoid zip slip (writing outside of the destination), we resolve
 | ||
|  |     // the target path, and make sure it's nested in the intended
 | ||
|  |     // destination, or not extract it otherwise.
 | ||
|  |     var extractPath = path.join(opts.path, entry.path); | ||
|  |     if (extractPath.indexOf(opts.path) != 0) { | ||
|  |       return cb(); | ||
|  |     } | ||
|  | 
 | ||
|  |     const writer = opts.getWriter ? opts.getWriter({path: extractPath}) :  Writer({ path: extractPath }); | ||
|  | 
 | ||
|  |     entry.pipe(writer) | ||
|  |       .on('error', cb) | ||
|  |       .on('close', cb); | ||
|  |   }; | ||
|  | 
 | ||
|  |   var extract = duplexer2(parser,outStream); | ||
|  |   parser.once('crx-header', function(crxHeader) { | ||
|  |     extract.crxHeader = crxHeader; | ||
|  |   }); | ||
|  | 
 | ||
|  |   parser | ||
|  |     .pipe(outStream) | ||
|  |     .on('finish',function() { | ||
|  |       extract.emit('close'); | ||
|  |     }); | ||
|  |    | ||
|  |   extract.promise = function() { | ||
|  |     return new Promise(function(resolve, reject) { | ||
|  |       extract.on('close', resolve); | ||
|  |       extract.on('error',reject); | ||
|  |     }); | ||
|  |   }; | ||
|  | 
 | ||
|  |   return extract; | ||
|  | } |