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;
};
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) {
if (!(this instanceof Extract)) return new Extract(opts);
stream.Writable.call(this, opts);
@ -29,6 +35,7 @@ var Extract = function(opts) {
this._cb = null;
this._locked = false;
this._destroyed = false;
this._pax = null;
var self = this;
var b = self._buffer;
@ -57,6 +64,13 @@ var Extract = function(opts) {
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 header = self._header = headers.decode(b.slice(0, 512));
b.consume(512);
@ -66,6 +80,16 @@ var Extract = function(opts) {
oncontinue();
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;

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 (Buffer.isBuffer(buffer)) {
header.size = buffer.length;
this.push(headers.encode(header));
this._encode(header);
this.push(buffer);
overflow(self, header.size);
process.nextTick(callback);
return;
}
if (header.type !== 'file' && header.type !== 'contigious-file') {
this.push(headers.encode(header));
this._encode(header);
process.nextTick(callback);
return;
}
this.push(headers.encode(header));
this._encode(header);
this._stream = stream;
var sink = new Sink(this);
@ -129,6 +129,42 @@ Pack.prototype.destroy = function(err) {
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) {
var drain = this._drain;
this._drain = noop;