using pax headers for long/unicode filenames

This commit is contained in:
Mathias Buus 2013-12-23 01:35:28 +01:00
parent baf5ea9b90
commit 6af6a7123c
2 changed files with 63 additions and 3 deletions

View file

@ -16,6 +16,12 @@ var emptyStream = function() {
return s; return s;
}; };
var mixinPax = function(header, pax) {
if (pax.path) header.name = pax.path;
if (pax.linkpath) header.linkname = pax.linkpath;
return header;
};
var Extract = function(opts) { var Extract = function(opts) {
if (!(this instanceof Extract)) return new Extract(opts); if (!(this instanceof Extract)) return new Extract(opts);
stream.Writable.call(this, opts); stream.Writable.call(this, opts);
@ -29,6 +35,7 @@ var Extract = function(opts) {
this._cb = null; this._cb = null;
this._locked = false; this._locked = false;
this._destroyed = false; this._destroyed = false;
this._pax = null;
var self = this; var self = this;
var b = self._buffer; var b = self._buffer;
@ -57,6 +64,13 @@ var Extract = function(opts) {
oncontinue(); oncontinue();
}; };
var onpaxheader = function() {
var size = self._header.size;
self._pax = headers.decodePax(b.slice(0, size));
b.consume(size);
onstreamend();
};
var onheader = function() { var onheader = function() {
var header = self._header = headers.decode(b.slice(0, 512)); var header = self._header = headers.decode(b.slice(0, 512));
b.consume(512); b.consume(512);
@ -66,6 +80,16 @@ var Extract = function(opts) {
oncontinue(); oncontinue();
return; return;
} }
if (header.type === 'pax-header') {
self._parse(header.size, onpaxheader);
oncontinue();
return;
}
if (self._pax) {
self._header = header = mixinPax(header, self._pax);
self._pax = null;
}
self._locked = true; self._locked = true;

42
pack.js
View file

@ -70,19 +70,19 @@ Pack.prototype.entry = function(header, buffer, callback) {
if (typeof buffer === 'string') buffer = new Buffer(buffer); if (typeof buffer === 'string') buffer = new Buffer(buffer);
if (Buffer.isBuffer(buffer)) { if (Buffer.isBuffer(buffer)) {
header.size = buffer.length; header.size = buffer.length;
this.push(headers.encode(header)); this._encode(header);
this.push(buffer); this.push(buffer);
overflow(self, header.size); overflow(self, header.size);
process.nextTick(callback); process.nextTick(callback);
return; return;
} }
if (header.type !== 'file' && header.type !== 'contigious-file') { if (header.type !== 'file' && header.type !== 'contigious-file') {
this.push(headers.encode(header)); this._encode(header);
process.nextTick(callback); process.nextTick(callback);
return; return;
} }
this.push(headers.encode(header)); this._encode(header);
this._stream = stream; this._stream = stream;
var sink = new Sink(this); var sink = new Sink(this);
@ -129,6 +129,42 @@ Pack.prototype.destroy = function(err) {
if (this._stream && this._stream.destroy) this._stream.destroy(); if (this._stream && this._stream.destroy) this._stream.destroy();
}; };
Pack.prototype._encode = function(header) {
var buf = headers.encode(header);
if (buf) this.push(buf);
else this._encodePax(header);
};
Pack.prototype._encodePax = function(header) {
var paxHeader = headers.encodePax({
name: header.name,
linkname: header.linkname
});
var newHeader = {
name: 'PaxHeader',
mode: header.mode,
uid: header.uid,
gid: header.gid,
size: paxHeader.length,
mtime: header.mtime,
type: 'pax-header',
linkname: header.linkname && 'PaxHeader',
uname: header.uname,
gname: header.gname,
devmajor: header.devmajor,
devminor: header.devminor
};
this.push(headers.encode(newHeader));
this.push(paxHeader);
overflow(this, paxHeader.length);
newHeader.size = header.size;
newHeader.type = header.type;
this.push(headers.encode(newHeader));
};
Pack.prototype._read = function(n) { Pack.prototype._read = function(n) {
var drain = this._drain; var drain = this._drain;
this._drain = noop; this._drain = noop;