Socket
Socket
Sign inDemoInstall

tar-fs

Package Overview
Dependencies
11
Maintainers
2
Versions
62
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.1.1 to 3.0.0

370

index.js

@@ -1,77 +0,26 @@

var chownr = require('chownr')
var tar = require('tar-stream')
var pump = require('pump')
var mkdirp = require('mkdirp-classic')
var fs = require('fs')
var path = require('path')
var os = require('os')
const tar = require('tar-stream')
const pump = require('pump')
const mkdirp = require('mkdirp-classic')
const fs = require('fs')
const path = require('path')
var win32 = os.platform() === 'win32'
const win32 = process.platform === 'win32'
var noop = function () {}
var echo = function (name) {
return name
}
var normalize = !win32 ? echo : function (name) {
return name.replace(/\\/g, '/').replace(/[:?<>|]/g, '_')
}
var statAll = function (fs, stat, cwd, ignore, entries, sort) {
var queue = entries || ['.']
return function loop (callback) {
if (!queue.length) return callback()
var next = queue.shift()
var nextAbs = path.join(cwd, next)
stat.call(fs, nextAbs, function (err, stat) {
if (err) return callback(err)
if (!stat.isDirectory()) return callback(null, next, stat)
fs.readdir(nextAbs, function (err, files) {
if (err) return callback(err)
if (sort) files.sort()
for (var i = 0; i < files.length; i++) {
if (!ignore(path.join(cwd, next, files[i]))) queue.push(path.join(next, files[i]))
}
callback(null, next, stat)
})
})
}
}
var strip = function (map, level) {
return function (header) {
header.name = header.name.split('/').slice(level).join('/')
var linkname = header.linkname
if (linkname && (header.type === 'link' || path.isAbsolute(linkname))) {
header.linkname = linkname.split('/').slice(level).join('/')
}
return map(header)
}
}
exports.pack = function (cwd, opts) {
exports.pack = function pack (cwd, opts) {
if (!cwd) cwd = '.'
if (!opts) opts = {}
var xfs = opts.fs || fs
var ignore = opts.ignore || opts.filter || noop
var map = opts.map || noop
var mapStream = opts.mapStream || echo
var statNext = statAll(xfs, opts.dereference ? xfs.stat : xfs.lstat, cwd, ignore, opts.entries, opts.sort)
var strict = opts.strict !== false
var umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask()
var dmode = typeof opts.dmode === 'number' ? opts.dmode : 0
var fmode = typeof opts.fmode === 'number' ? opts.fmode : 0
var pack = opts.pack || tar.pack()
var finish = opts.finish || noop
const xfs = opts.fs || fs
const ignore = opts.ignore || opts.filter || noop
const mapStream = opts.mapStream || echo
const statNext = statAll(xfs, opts.dereference ? xfs.stat : xfs.lstat, cwd, ignore, opts.entries, opts.sort)
const strict = opts.strict !== false
const umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask()
const pack = opts.pack || tar.pack()
const finish = opts.finish || noop
let map = opts.map || noop
let dmode = typeof opts.dmode === 'number' ? opts.dmode : 0
let fmode = typeof opts.fmode === 'number' ? opts.fmode : 0
if (opts.strip) map = strip(map, opts.strip)

@@ -88,3 +37,5 @@

var onsymlink = function (filename, header) {
onnextentry()
function onsymlink (filename, header) {
xfs.readlink(path.join(cwd, filename), function (err, linkname) {

@@ -97,3 +48,3 @@ if (err) return pack.destroy(err)

var onstat = function (err, filename, stat) {
function onstat (err, filename, stat) {
if (err) return pack.destroy(err)

@@ -107,3 +58,3 @@ if (!filename) {

var header = {
let header = {
name: normalize(filename),

@@ -141,7 +92,5 @@ mode: (stat.mode | (stat.isDirectory() ? dmode : fmode)) & umask,

var entry = pack.entry(header, onnextentry)
if (!entry) return
const entry = pack.entry(header, onnextentry)
const rs = mapStream(xfs.createReadStream(path.join(cwd, filename), { start: 0, end: header.size > 0 ? header.size - 1 : header.size }), header)
var rs = mapStream(xfs.createReadStream(path.join(cwd, filename), { start: 0, end: header.size > 0 ? header.size - 1 : header.size }), header)
rs.on('error', function (err) { // always forward errors on destroy

@@ -154,3 +103,3 @@ entry.destroy(err)

var onnextentry = function (err) {
function onnextentry (err) {
if (err) return pack.destroy(err)

@@ -160,36 +109,35 @@ statNext(onstat)

onnextentry()
return pack
}
var head = function (list) {
function head (list) {
return list.length ? list[list.length - 1] : null
}
var processGetuid = function () {
function processGetuid () {
return process.getuid ? process.getuid() : -1
}
var processUmask = function () {
function processUmask () {
return process.umask ? process.umask() : 0
}
exports.extract = function (cwd, opts) {
exports.extract = function extract (cwd, opts) {
if (!cwd) cwd = '.'
if (!opts) opts = {}
var xfs = opts.fs || fs
var ignore = opts.ignore || opts.filter || noop
var map = opts.map || noop
var mapStream = opts.mapStream || echo
var own = opts.chown !== false && !win32 && processGetuid() === 0
var extract = opts.extract || tar.extract()
var stack = []
var now = new Date()
var umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask()
var dmode = typeof opts.dmode === 'number' ? opts.dmode : 0
var fmode = typeof opts.fmode === 'number' ? opts.fmode : 0
var strict = opts.strict !== false
const xfs = opts.fs || fs
const ignore = opts.ignore || opts.filter || noop
const mapStream = opts.mapStream || echo
const own = opts.chown !== false && !win32 && processGetuid() === 0
const extract = opts.extract || tar.extract()
const stack = []
const now = new Date()
const umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask()
const strict = opts.strict !== false
let map = opts.map || noop
let dmode = typeof opts.dmode === 'number' ? opts.dmode : 0
let fmode = typeof opts.fmode === 'number' ? opts.fmode : 0
if (opts.strip) map = strip(map, opts.strip)

@@ -206,54 +154,62 @@

var utimesParent = function (name, cb) { // we just set the mtime on the parent dir again everytime we write an entry
var top
while ((top = head(stack)) && name.slice(0, top[0].length) !== top[0]) stack.pop()
if (!top) return cb()
xfs.utimes(top[0], now, top[1], cb)
}
extract.on('entry', onentry)
var utimes = function (name, header, cb) {
if (opts.utimes === false) return cb()
if (opts.finish) extract.on('finish', opts.finish)
if (header.type === 'directory') return xfs.utimes(name, now, header.mtime, cb)
if (header.type === 'symlink') return utimesParent(name, cb) // TODO: how to set mtime on link?
return extract
xfs.utimes(name, now, header.mtime, function (err) {
if (err) return cb(err)
utimesParent(name, cb)
})
}
function onentry (header, stream, next) {
header = map(header) || header
header.name = normalize(header.name)
var chperm = function (name, header, cb) {
var link = header.type === 'symlink'
const name = path.join(cwd, path.join('/', header.name))
/* eslint-disable node/no-deprecated-api */
var chmod = link ? xfs.lchmod : xfs.chmod
var chown = link ? xfs.lchown : xfs.chown
/* eslint-enable node/no-deprecated-api */
if (ignore(name, header)) {
stream.resume()
return next()
}
if (!chmod) return cb()
if (header.type === 'directory') {
stack.push([name, header.mtime])
return mkdirfix(name, {
fs: xfs,
own,
uid: header.uid,
gid: header.gid,
mode: header.mode
}, stat)
}
var mode = (header.mode | (header.type === 'directory' ? dmode : fmode)) & umask
const dir = path.dirname(name)
if (chown && own) chown.call(xfs, name, header.uid, header.gid, onchown)
else onchown(null)
validate(xfs, dir, path.join(cwd, '.'), function (err, valid) {
if (err) return next(err)
if (!valid) return next(new Error(dir + ' is not a valid path'))
function onchown (err) {
if (err) return cb(err)
if (!chmod) return cb()
chmod.call(xfs, name, mode, cb)
}
}
mkdirfix(dir, {
fs: xfs,
own,
uid: header.uid,
gid: header.gid,
// normally, the folders with rights and owner should be part of the TAR file
// if this is not the case, create folder for same user as file and with
// standard permissions of 0o755 (rwxr-xr-x)
mode: 0o755
}, function (err) {
if (err) return next(err)
extract.on('entry', function (header, stream, next) {
header = map(header) || header
header.name = normalize(header.name)
var name = path.join(cwd, path.join('/', header.name))
switch (header.type) {
case 'file': return onfile()
case 'link': return onlink()
case 'symlink': return onsymlink()
}
if (ignore(name, header)) {
stream.resume()
return next()
}
if (strict) return next(new Error('unsupported type for ' + name + ' (' + header.type + ')'))
var stat = function (err) {
stream.resume()
next()
})
})
function stat (err) {
if (err) return next(err)

@@ -267,3 +223,3 @@ utimes(name, header, function (err) {

var onsymlink = function () {
function onsymlink () {
if (win32) return next() // skip symlinks on win for now before it can be tested

@@ -275,6 +231,6 @@ xfs.unlink(name, function () {

var onlink = function () {
function onlink () {
if (win32) return next() // skip links on win for now before it can be tested
xfs.unlink(name, function () {
var srcpath = path.join(cwd, path.join('/', header.linkname))
const srcpath = path.join(cwd, path.join('/', header.linkname))

@@ -292,5 +248,5 @@ xfs.link(srcpath, name, function (err) {

var onfile = function () {
var ws = xfs.createWriteStream(name)
var rs = mapStream(stream, header)
function onfile () {
const ws = xfs.createWriteStream(name)
const rs = mapStream(stream, header)

@@ -306,38 +262,57 @@ ws.on('error', function (err) { // always forward errors on destroy

}
}
if (header.type === 'directory') {
stack.push([name, header.mtime])
return mkdirfix(name, {
fs: xfs, own: own, uid: header.uid, gid: header.gid
}, stat)
}
function utimesParent (name, cb) { // we just set the mtime on the parent dir again everytime we write an entry
let top
while ((top = head(stack)) && name.slice(0, top[0].length) !== top[0]) stack.pop()
if (!top) return cb()
xfs.utimes(top[0], now, top[1], cb)
}
var dir = path.dirname(name)
function utimes (name, header, cb) {
if (opts.utimes === false) return cb()
validate(xfs, dir, path.join(cwd, '.'), function (err, valid) {
if (err) return next(err)
if (!valid) return next(new Error(dir + ' is not a valid path'))
if (header.type === 'directory') return xfs.utimes(name, now, header.mtime, cb)
if (header.type === 'symlink') return utimesParent(name, cb) // TODO: how to set mtime on link?
mkdirfix(dir, {
fs: xfs, own: own, uid: header.uid, gid: header.gid
}, function (err) {
if (err) return next(err)
xfs.utimes(name, now, header.mtime, function (err) {
if (err) return cb(err)
utimesParent(name, cb)
})
}
switch (header.type) {
case 'file': return onfile()
case 'link': return onlink()
case 'symlink': return onsymlink()
}
function chperm (name, header, cb) {
const link = header.type === 'symlink'
if (strict) return next(new Error('unsupported type for ' + name + ' (' + header.type + ')'))
/* eslint-disable n/no-deprecated-api */
const chmod = link ? xfs.lchmod : xfs.chmod
const chown = link ? xfs.lchown : xfs.chown
/* eslint-enable n/no-deprecated-api */
stream.resume()
next()
if (!chmod) return cb()
const mode = (header.mode | (header.type === 'directory' ? dmode : fmode)) & umask
if (chown && own) chown.call(xfs, name, header.uid, header.gid, onchown)
else onchown(null)
function onchown (err) {
if (err) return cb(err)
if (!chmod) return cb()
chmod.call(xfs, name, mode, cb)
}
}
function mkdirfix (name, opts, cb) {
// when mkdir is called on an existing directory, the permissions
// will be overwritten (?), to avoid this we check for its existance first
xfs.stat(name, function (err) {
if (!err) return cb(null)
if (err.code !== 'ENOENT') return cb(err)
mkdirp(name, { fs: opts.fs, mode: opts.mode }, function (err, made) {
if (err) return cb(err)
chperm(name, opts, cb)
})
})
})
if (opts.finish) extract.on('finish', opts.finish)
return extract
}
}

@@ -354,10 +329,53 @@

function mkdirfix (name, opts, cb) {
mkdirp(name, { fs: opts.fs }, function (err, made) {
if (!err && made && opts.own) {
chownr(made, opts.uid, opts.gid, cb)
} else {
cb(err)
function noop () {}
function echo (name) {
return name
}
function normalize (name) {
return win32 ? name.replace(/\\/g, '/').replace(/[:?<>|]/g, '_') : name
}
function statAll (fs, stat, cwd, ignore, entries, sort) {
const queue = (entries || ['.']).slice(0)
return function loop (callback) {
if (!queue.length) return callback(null)
const next = queue.shift()
const nextAbs = path.join(cwd, next)
stat.call(fs, nextAbs, function (err, stat) {
// ignore errors if the files were deleted while buffering
if (err) return callback(err.code === 'ENOENT' ? null : err)
if (!stat.isDirectory()) return callback(null, next, stat)
fs.readdir(nextAbs, function (err, files) {
if (err) return callback(err)
if (sort) files.sort()
for (let i = 0; i < files.length; i++) {
if (!ignore(path.join(cwd, next, files[i]))) queue.push(path.join(next, files[i]))
}
callback(null, next, stat)
})
})
}
}
function strip (map, level) {
return function (header) {
header.name = header.name.split('/').slice(level).join('/')
const linkname = header.linkname
if (linkname && (header.type === 'link' || path.isAbsolute(linkname))) {
header.linkname = linkname.split('/').slice(level).join('/')
}
})
return map(header)
}
}
{
"name": "tar-fs",
"version": "2.1.1",
"version": "3.0.0",
"description": "filesystem bindings for tar-stream",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
"tar-stream": "^3.1.0"
},
"files": [
"index.js"
],
"standard": {
"ignore": [
"test/fixtures/**"
]
},
"keywords": [

@@ -20,8 +27,8 @@ "tar",

"devDependencies": {
"brittle": "^3.1.3",
"rimraf": "^2.6.3",
"standard": "^13.0.1",
"tape": "^4.9.2"
"standard": "^17.0.1"
},
"scripts": {
"test": "standard && tape test/index.js"
"test": "standard && brittle test/index.js"
},

@@ -28,0 +35,0 @@ "bugs": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc