From e8c8872952fdb60dcf2ad0a486e9d47dfa96b838 Mon Sep 17 00:00:00 2001 From: Mathias Buus Date: Sat, 18 Apr 2015 12:31:03 -0700 Subject: [PATCH] support gnu long path. fixes #35 --- extract.js | 36 ++++++++++++++++++++++++++++++++ headers.js | 9 ++++++++ test/extract.js | 18 ++++++++++++++++ test/fixtures/gnu-long-path.tar | Bin 0 -> 7594 bytes test/fixtures/index.js | 1 + 5 files changed, 64 insertions(+) create mode 100644 test/fixtures/gnu-long-path.tar diff --git a/extract.js b/extract.js index f656d49..d685bb3 100644 --- a/extract.js +++ b/extract.js @@ -53,6 +53,8 @@ var Extract = function(opts) { this._destroyed = false this._pax = null this._paxGlobal = null + this._gnuLongPath = null + this._gnuLongLinkPath = null var self = this var b = self._buffer @@ -96,6 +98,20 @@ var Extract = function(opts) { onstreamend() } + var ongnulongpath = function() { + var size = self._header.size + this._gnuLongPath = headers.decodeLongPath(b.slice(0, size)) + b.consume(size) + onstreamend() + } + + var ongnulonglinkpath = function() { + var size = self._header.size + this._gnuLongLinkPath = headers.decodeLongPath(b.slice(0, size)) + b.consume(size) + onstreamend() + } + var onheader = function() { var offset = self._offset var header @@ -111,6 +127,16 @@ var Extract = function(opts) { oncontinue() return } + if (header.type === 'gnu-long-path') { + self._parse(header.size, ongnulongpath) + oncontinue() + return + } + if (header.type === 'gnu-long-link-path') { + self._parse(header.size, ongnulonglinkpath) + oncontinue() + return + } if (header.type === 'pax-global-header') { self._parse(header.size, onpaxglobalheader) oncontinue() @@ -122,6 +148,16 @@ var Extract = function(opts) { return } + if (self._gnuLongPath) { + header.name = self._gnuLongPath + self._gnuLongPath = null + } + + if (self._gnuLongLinkPath) { + header.linkname = self._gnuLongLinkPath + self._gnuLongLinkPath = null + } + if (self._pax) { self._header = header = mixinPax(header, self._pax) self._pax = null diff --git a/headers.js b/headers.js index df8deae..19c8bf1 100644 --- a/headers.js +++ b/headers.js @@ -34,6 +34,11 @@ var toType = function(flag) { return 'pax-header' case 55: return 'pax-global-header' + case 27: + return 'gnu-long-link-path' + case 28: + case 30: + return 'gnu-long-path' } return null @@ -110,6 +115,10 @@ var addLength = function(str) { return (len+digits)+str } +exports.decodeLongPath = function(buf) { + return decodeStr(buf, 0, buf.length) +} + exports.encodePax = function(opts) { // TODO: encode more stuff in pax var result = '' if (opts.name) result += addLength(' path='+opts.name+'\n') diff --git a/test/extract.js b/test/extract.js index 4bec7a4..d5ac947 100644 --- a/test/extract.js +++ b/test/extract.js @@ -435,3 +435,21 @@ test('space prefixed', function(t) { extract.end(fs.readFileSync(fixtures.SPACE_TAR_GZ)) }) + +test('gnu long path', function(t) { + t.plan(2) + + var extract = tar.extract() + + extract.on('entry', function(header, stream, callback) { + t.ok(header.name.length > 100) + callback() + }) + + extract.on('finish', function() { + t.ok(true) + }) + + extract.end(fs.readFileSync(fixtures.GNU_LONG_PATH)) + +}) \ No newline at end of file diff --git a/test/fixtures/gnu-long-path.tar b/test/fixtures/gnu-long-path.tar new file mode 100644 index 0000000000000000000000000000000000000000..efb204c4e341d2805c646513cbf61014d113b41f GIT binary patch literal 7594 zcmeHLS#RS;685uyMO!-vsfV{irrmRT~%LIS9KIe@z?LF^75T1Zw`K+XKtQ@J@5JA<#RVjOAh9X z#miSO4%oZjXFEf#t!fg<*nzC7W;iqa`qcbz^`GXetTH~kokxpBw0IF`yjF2puVWhi z*SgBuf~#1RqM6l6dXrr8*|n<5;dCvl^}iFD#r!^5*99jAGomqsqO98{x>kQ0lYCYi z{UiKOLH!B=O>aD-_u~1hm(LCs&t5F%ub#hrJzpHmpFdl?etp2^e}pGK^Z36-^2-%F zWs?8c3dzGDSHbjQB&jF#YQA(By@P-`ACFi1w#L#wKO5<`Z_pC>_*I7|?fc zj2Xt7hniP8qY-v`ddh;f%y=$Jo&|dTjI9#IX*!a;E|Qdo@kfo!$Ma}*ajl-jm&Ys! zrYD-ml(gY;V&>EGpc)x< z^R`UsgN0LV17as~7FvCK%k>U=YO^oCV7=*%oWT)IE6e_@-R{P|$v3x2(ekhCKqDW# zc-jIjP%?#Mas`7X+22ILKRlFa82t0?H*fy_Hd<$}QP4K|U&*0FV;;>GbfAt@T?n{w zSq9T67e&KmPu~L0>u=hS+pWh-^)!weu9{G<>j`jzpgv7SjTCDbkNmR_0{M=*hJ^-6q-9XrBPG8tM0h`4hV)Oo3ZQ; z(aY$`mM(5*&bKM)z`}uT$L@_|_CwVcSs64;G;GCLDN;_rYp#-p!B?EY7H}BP&U!i# zEV5moh%Rwf_t4m3!&7fqZ)a|^2JD%0B7AzJ0W>x6gs99ia1<6GE=3Gw8d|c*W*VA+ zTPH#Xcn^6Fb)-$M+4t>}clu>QYRuzJnPmrvbH|HNX}6X;7%fqnt^B^UEfrXpi&%s3wd&+|SjK-^a{OnK0wE0|o zjC`&ajU32JGJai&vH@sv_W0OSnM~n5xiXII1<}e`-zF*eDYU*KMPg78PoHABJZ71r zVGL1FRt$@j-934R%c*l@x(b~yu=Ej0h}!6r3|jNFsifeFPP0zsbeD~SXxl8%r?bqqAz&7( z4n>XR`pkAQ3F#`zEBQ7-_UvT$OwE|O6FM&q1{rb!&>YyZKR6kFD-2lcK_aRJ-5m6i z0!5wSKu3iqr;iaW4ecb%s?^ir_lOK5JE_)5Ioult1`C~O22uZhbqy~?H~c|`P-q$z zyu73e31`=wU`JN-IUowMq`QAyG$KDQ*IUZ#SM)v)gOAKw2XsuPLY0(=G;*#(!O zXPq0IjH5cTb?kmK!ZUE=d3FI=!Ox_TC-S}{em0P|_Ua>qQoX0}S%lX2i(|L7*$g;w zaih!KF2Q0y9Ve%iWp48&zkSm~KjlmxGlQ9(VKZ3qi;;tKLs83;s6n)`Rf{SM$3(_& zwfU^x|GR;9^#4esmhAJ3G?P4aRnjXBTtY*9q*pw>VNJyp=j=|m9}*#RSIHYD6cZ(D z6>2J^yrg{4abj}Ys29QUVEWU+0fmI8NqVh^ZeY$Y>;!S4Gss52-R<~_ft}%yLXNQ0 zhnlB3KYSfOI4rh`c@^PwsoPZ{6y1op_GQ(IB4cT_M*V<>+NJ@@aof*;1(nH0B6ZsF zmy!LLRp^RWxPH;BNV~GKwNJp)tBOtDN?A$Vf>cb8tD2`G7d)HLg#y1vJGd}cDn11_ z_qdNh{p6hHbGc@Kofr{X;-<6BkPlOj@>QWp?EZ$I=gAf-fS!Y znN|meKqrOEn|pTv_;xAlS}u3g{}xG(R*U@;~?4|gDNtMuDm z8^ud`wk&=7Oi&hx9J9nn-MQpz0Gv(G`&^)iBsEM>U?xk*x+u**wWN`EyZTHEnK#I zjsL55g|J_r^y|&&Bp~-KgOdcYk^c!?jot0H|jf;UWV0MeN(q(E>nV}vRB|*iFWR#?r=I3nguHRY}6V0q;5PSws_=;YeRR8xJG%d++%R>islb3ZHOXyA=B* t=*i%sw;Vv*w-{4_!<&J{N!KP4i%Eg&yHX7<&+QOA7JU2R4Gg$B{0|{46`244 literal 0 HcmV?d00001 diff --git a/test/fixtures/index.js b/test/fixtures/index.js index d058613..1e5d37e 100644 --- a/test/fixtures/index.js +++ b/test/fixtures/index.js @@ -9,3 +9,4 @@ exports.UNICODE_TAR = path.join(__dirname, 'unicode.tar') exports.NAME_IS_100_TAR = path.join(__dirname, 'name-is-100.tar') exports.INVALID_TGZ = path.join(__dirname, 'invalid.tgz') exports.SPACE_TAR_GZ = path.join(__dirname, 'space.tar') +exports.GNU_LONG_PATH = path.join(__dirname, 'gnu-long-path.tar') \ No newline at end of file