using pax headers for long/unicode filenames
This commit is contained in:
parent
baf5ea9b90
commit
6af6a7123c
2 changed files with 63 additions and 3 deletions
24
extract.js
24
extract.js
|
@ -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
42
pack.js
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue