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
			| 
								 
											3 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;
							 | 
						||
| 
								 | 
							
								}
							 |