From e7e98952be9bcdd1c7403755d0038f996198653b Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 12 Aug 2019 09:20:51 -0700 Subject: [PATCH] pacote@9.5.5 Infer the ownership of all unpacked files in node_modules, so that we never have user-owned files in root-owned folders, or root-owned files in user-owned folders. This prevents one of the last remaining issues that bites users who use `sudo` unnecessarily. The only remaining issue is to no longer drop perms when running scripts as root, but that is a breaking change which will come in v7. --- node_modules/pacote/CHANGELOG.md | 12 ++++ node_modules/pacote/LICENSE | 2 +- node_modules/pacote/extract.js | 75 ++++++++++++++++-------- node_modules/pacote/lib/fetchers/file.js | 2 - node_modules/pacote/package.json | 23 ++++---- package-lock.json | 9 +-- package.json | 2 +- 7 files changed, 82 insertions(+), 43 deletions(-) diff --git a/node_modules/pacote/CHANGELOG.md b/node_modules/pacote/CHANGELOG.md index 8559760b3eb39..f807fa455ded1 100644 --- a/node_modules/pacote/CHANGELOG.md +++ b/node_modules/pacote/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [9.5.5](https://github.com/npm/pacote/compare/v9.5.4...v9.5.5) (2019-08-12) + + +### Bug Fixes + +* don't pass uid/gid to cacache ([0a0c73c](https://github.com/npm/pacote/commit/0a0c73c)) +* Infer owner of all unpacked files ([f12e7ef](https://github.com/npm/pacote/commit/f12e7ef)) +* invalid arg detection in extract() ([b4dc363](https://github.com/npm/pacote/commit/b4dc363)), closes [#5](https://github.com/npm/pacote/issues/5) [#6](https://github.com/npm/pacote/issues/6) + + + ## [9.5.4](https://github.com/npm/pacote/compare/v9.5.3...v9.5.4) (2019-07-16) diff --git a/node_modules/pacote/LICENSE b/node_modules/pacote/LICENSE index ab41caa64b86c..841ef53a26dff 100644 --- a/node_modules/pacote/LICENSE +++ b/node_modules/pacote/LICENSE @@ -1,5 +1,5 @@ The MIT License (MIT) -Copyright (c) 2017 Kat Marchán +Copyright (c) Kat Marchán, npm, Inc., and Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/node_modules/pacote/extract.js b/node_modules/pacote/extract.js index f49a54420242a..9f740e37c314d 100644 --- a/node_modules/pacote/extract.js +++ b/node_modules/pacote/extract.js @@ -10,41 +10,60 @@ const optCheck = require('./lib/util/opt-check.js') const path = require('path') const rimraf = BB.promisify(require('rimraf')) const withTarballStream = require('./lib/with-tarball-stream.js') +const inferOwner = require('infer-owner') +const chown = BB.promisify(fs.chown) const truncateAsync = BB.promisify(fs.truncate) const readFileAsync = BB.promisify(fs.readFile) const appendFileAsync = BB.promisify(fs.appendFile) +// you used to call me on my... +const selfOwner = process.getuid ? { + uid: process.getuid(), + gid: process.getgid() +} : { + uid: undefined, + gid: undefined +} + module.exports = extract function extract (spec, dest, opts) { opts = optCheck(opts) spec = npa(spec, opts.where) + if (spec.type === 'git' && !opts.cache) { + throw new TypeError('Extracting git packages requires a cache folder') + } + if (typeof dest !== 'string') { + throw new TypeError('Extract requires a destination') + } const startTime = Date.now() - - return withTarballStream(spec, opts, stream => { - return tryExtract(spec, stream, dest, opts) - }) - .then(() => { - if (!opts.resolved) { - const pjson = path.join(dest, 'package.json') - return readFileAsync(pjson, 'utf8') - .then(str => truncateAsync(pjson) - .then(() => appendFileAsync(pjson, str.replace( - /}\s*$/, - `\n,"_resolved": ${ - JSON.stringify(opts.resolved || '') - }\n,"_integrity": ${ - JSON.stringify(opts.integrity || '') - }\n,"_from": ${ - JSON.stringify(spec.toString()) - }\n}` - )))) - } + return inferOwner(dest).then(({ uid, gid }) => { + opts = opts.concat({ uid, gid }) + return withTarballStream(spec, opts, stream => { + return tryExtract(spec, stream, dest, opts) }) - .then(() => opts.log.silly( - 'extract', - `${spec} extracted to ${dest} (${Date.now() - startTime}ms)` - )) + .then(() => { + if (!opts.resolved) { + const pjson = path.join(dest, 'package.json') + return readFileAsync(pjson, 'utf8') + .then(str => truncateAsync(pjson) + .then(() => appendFileAsync(pjson, str.replace( + /}\s*$/, + `\n,"_resolved": ${ + JSON.stringify(opts.resolved || '') + }\n,"_integrity": ${ + JSON.stringify(opts.integrity || '') + }\n,"_from": ${ + JSON.stringify(spec.toString()) + }\n}` + )))) + } + }) + .then(() => opts.log.silly( + 'extract', + `${spec} extracted to ${dest} (${Date.now() - startTime}ms)` + )) + }) } function tryExtract (spec, tarStream, dest, opts) { @@ -53,6 +72,14 @@ function tryExtract (spec, tarStream, dest, opts) { rimraf(dest) .then(() => mkdirp(dest)) + .then(() => { + // respect the current ownership of unpack targets + if (typeof selfOwner.uid === 'number' && + typeof selfOwner.gid === 'number' && + selfOwner.uid !== opts.uid && selfOwner.gid !== opts.gid) { + return chown(dest, opts.uid, opts.gid) + } + }) .then(() => { const xtractor = extractStream(spec, dest, opts) xtractor.on('error', reject) diff --git a/node_modules/pacote/lib/fetchers/file.js b/node_modules/pacote/lib/fetchers/file.js index 7348a7ec634c1..a58e329130987 100644 --- a/node_modules/pacote/lib/fetchers/file.js +++ b/node_modules/pacote/lib/fetchers/file.js @@ -60,8 +60,6 @@ Fetcher.impl(fetchFile, { : (pipe( fs.createReadStream(src), cacache.put.stream(opts.cache, `pacote:tarball:${src}`, { - uid: opts.uid, - gid: opts.gid, integrity: opts.integrity }).on('integrity', d => { integrity = d }) )) diff --git a/node_modules/pacote/package.json b/node_modules/pacote/package.json index 215e5dce843f1..85b5b86f366b8 100644 --- a/node_modules/pacote/package.json +++ b/node_modules/pacote/package.json @@ -1,8 +1,8 @@ { - "_from": "pacote@9.5.4", - "_id": "pacote@9.5.4", + "_from": "pacote@9.5.5", + "_id": "pacote@9.5.5", "_inBundle": false, - "_integrity": "sha512-nWr0ari6E+apbdoN0hToTKZElO5h4y8DGFa2pyNA5GQIdcP0imC96bA0bbPw1gpeguVIiUgHHaAlq/6xfPp8Qw==", + "_integrity": "sha512-jAEP+Nqj4kyMWyNpfTU/Whx1jA7jEc5cCOlurm0/0oL+v8TAp1QSsK83N7bYe+2bEdFzMAtPG5TBebjzzGV0cA==", "_location": "/pacote", "_phantomChildren": { "safe-buffer": "5.1.2", @@ -11,12 +11,12 @@ "_requested": { "type": "version", "registry": true, - "raw": "pacote@9.5.4", + "raw": "pacote@9.5.5", "name": "pacote", "escapedName": "pacote", - "rawSpec": "9.5.4", + "rawSpec": "9.5.5", "saveSpec": null, - "fetchSpec": "9.5.4" + "fetchSpec": "9.5.5" }, "_requiredBy": [ "#USER", @@ -24,9 +24,9 @@ "/libcipm", "/libnpm" ], - "_resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.4.tgz", - "_shasum": "8baa26f3d1326d13dc2fe0fe84040a364ae30aad", - "_spec": "pacote@9.5.4", + "_resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.5.tgz", + "_shasum": "63355a393614c3424e735820c3731e2cbbedaeeb", + "_spec": "pacote@9.5.5", "_where": "/Users/isaacs/dev/npm/cli", "author": { "name": "Kat Marchán", @@ -48,10 +48,11 @@ ], "dependencies": { "bluebird": "^3.5.3", - "cacache": "^12.0.0", + "cacache": "^12.0.2", "figgy-pudding": "^3.5.1", "get-stream": "^4.1.0", "glob": "^7.1.3", + "infer-owner": "^1.0.4", "lru-cache": "^5.1.1", "make-fetch-happen": "^5.0.0", "minimatch": "^3.0.4", @@ -117,5 +118,5 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "9.5.4" + "version": "9.5.5" } diff --git a/package-lock.json b/package-lock.json index 0cc22483e134e..6e759ca5a6aa4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4383,15 +4383,16 @@ } }, "pacote": { - "version": "9.5.4", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.4.tgz", - "integrity": "sha512-nWr0ari6E+apbdoN0hToTKZElO5h4y8DGFa2pyNA5GQIdcP0imC96bA0bbPw1gpeguVIiUgHHaAlq/6xfPp8Qw==", + "version": "9.5.5", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.5.tgz", + "integrity": "sha512-jAEP+Nqj4kyMWyNpfTU/Whx1jA7jEc5cCOlurm0/0oL+v8TAp1QSsK83N7bYe+2bEdFzMAtPG5TBebjzzGV0cA==", "requires": { "bluebird": "^3.5.3", - "cacache": "^12.0.0", + "cacache": "^12.0.2", "figgy-pudding": "^3.5.1", "get-stream": "^4.1.0", "glob": "^7.1.3", + "infer-owner": "^1.0.4", "lru-cache": "^5.1.1", "make-fetch-happen": "^5.0.0", "minimatch": "^3.0.4", diff --git a/package.json b/package.json index 603c200b460ec..0f21d94c4035a 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "once": "~1.4.0", "opener": "^1.5.1", "osenv": "^0.1.5", - "pacote": "^9.5.4", + "pacote": "^9.5.5", "path-is-inside": "~1.0.2", "promise-inflight": "~1.0.1", "qrcode-terminal": "^0.12.0",