From 1834b3aaa743f23b1144d29983b41256f7548cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Tue, 21 Feb 2017 16:22:00 -0800 Subject: [PATCH] fix(extract-stream): compensate for bug in tar-fs chowning --- lib/extract-stream.js | 47 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/extract-stream.js b/lib/extract-stream.js index 4d5a513..a11a904 100644 --- a/lib/extract-stream.js +++ b/lib/extract-stream.js @@ -1,20 +1,65 @@ 'use strict' +var chownr = require('chownr') var gunzip = require('./util/gunzip-maybe') var path = require('path') var pipeline = require('mississippi').pipeline var tar = require('tar-fs') +var to = require('mississippi').to module.exports = extractStream function extractStream (dest, opts) { opts = opts || {} + var errEmitted = false + var tarStream = makeTarStream(dest, opts) + var target = to(function (chunk, enc, cb) { + tarStream.write(chunk, enc, cb) + }, function flush (cb) { + // TODO - there's a bug in tar-fs so we have to do this manually. + // This code ms.to() stunt can be removed afer the issue is fixed: + // https://github.com/mafintosh/tar-fs/issues/59 + tarStream.end(function () { + if ( + process.platform !== 'win32' && + process.getuid && + process.getuid() === 0 && + (typeof opts.uid === 'number' || typeof opts.gid === 'number') + ) { + chownr( + dest, + typeof opts.uid === 'number' ? opts.uid : process.getuid(), + typeof opts.gid === 'number' ? opts.gid : process.getgid(), + cb + ) + } else { + cb() + } + }) + }) + target.on('error', function (err) { + if (!errEmitted) { + errEmitted = true + tarStream.emit('error', err) + } + }) + tarStream.on('error', function (err) { + if (!errEmitted) { + errEmitted = true + target.emit('error', err) + } + }) + return target +} + +function makeTarStream (dest, opts) { var sawIgnores = {} return pipeline(gunzip(), tar.extract(dest, { map: function (header) { - if (process.platform !== 'win32') { + if (process.getuid && process.getuid() === 0) { header.uid = opts.uid == null ? header.uid : opts.uid header.gid = opts.gid == null ? header.gid : opts.gid } + // Note: This mirrors logic in the fs read operations that are // employed during tarball creation, in the fstream-npm module. // It is duplicated here to handle tarballs that are created