Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIonică Bizău <bizauionica@gmail.com>2016-09-19 09:11:19 +0300
committerRebecca Turner <me@re-becca.org>2016-10-07 01:14:04 +0300
commit952f1e109a070ab4066179f6104ba9394300e342 (patch)
tree948179dfcabdf8709b8e50e9c994cbcbec1fb4b6
parent1089878f58977559414c8a9addfc69a9c68905b0 (diff)
deps: Guard against null "bin" values in package.json
Fixes: #13997 Credit: @IonicaBizau PR-URL: https://github.com/npm/npm/pull/13999 Reviewed-By: @iarna
-rw-r--r--lib/install/deps.js6
-rw-r--r--test/tap/install-bin-null.js91
2 files changed, 94 insertions, 3 deletions
diff --git a/lib/install/deps.js b/lib/install/deps.js
index 96b88f84c..4d315ab18 100644
--- a/lib/install/deps.js
+++ b/lib/install/deps.js
@@ -612,13 +612,13 @@ var earliestInstallable = exports.earliestInstallable = function (requiredBy, tr
// If any of the children of this tree have conflicting
// binaries then we need to decline to install this package here.
- var binaryMatches = typeof pkg.bin === 'object' && tree.children.some(function (child) {
- if (child.removed) return false
- if (typeof child.package.bin !== 'object') return false
+ var binaryMatches = pkg.bin && tree.children.some(function (child) {
+ if (child.removed || !child.package.bin) return false
return Object.keys(child.package.bin).some(function (bin) {
return pkg.bin[bin]
})
})
+
if (binaryMatches) return null
// if this tree location requested the same module then we KNOW it
diff --git a/test/tap/install-bin-null.js b/test/tap/install-bin-null.js
new file mode 100644
index 000000000..f45528a75
--- /dev/null
+++ b/test/tap/install-bin-null.js
@@ -0,0 +1,91 @@
+var fs = require('graceful-fs')
+var path = require('path')
+
+var mkdirp = require('mkdirp')
+var osenv = require('osenv')
+var rimraf = require('rimraf')
+var test = require('tap').test
+
+var common = require('../common-tap.js')
+
+var pkg = path.join(__dirname, 'install-bin-null')
+
+var EXEC_OPTS = { cwd: pkg }
+
+var parentPkg = {
+ name: 'parent-package',
+ version: '0.0.0',
+ dependencies: {
+ 'child-package-a': 'file:./child-package-a',
+ 'child-package-b': 'file:./child-package-b'
+ }
+}
+
+var childPkgA = {
+ name: 'child-package-a',
+ version: '0.0.0',
+ bin: 'index.js'
+}
+
+var childPkgB = {
+ name: 'child-package-b',
+ version: '0.0.0',
+ dependencies: {
+ 'grandchild-package': 'file:../grandchild-package'
+ }
+}
+
+var grandchildPkg = {
+ name: 'grandchild-package',
+ version: '0.0.0',
+ bin: null
+}
+
+var pkgs = [childPkgA, childPkgB, grandchildPkg]
+
+test('the grandchild has bin:null', function (t) {
+ setup()
+ common.npm(['install'], EXEC_OPTS, function (err, code, stdout, stderr) {
+ t.ifErr(err, 'npm link finished without error')
+ t.equal(code, 0, 'exited ok')
+ t.ok(stdout, 'output indicating success')
+ t.notOk(stderr, 'no output stderr')
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(pkg)
+}
+
+function setup () {
+ cleanup()
+ mkdirp.sync(pkg)
+ fs.writeFileSync(
+ path.join(pkg, 'package.json'),
+ JSON.stringify(parentPkg, null, 2)
+ )
+ pkgs.forEach(function (json) {
+ process.chdir(mkPkg(json))
+ })
+ fs.writeFileSync(
+ path.join(pkg, childPkgA.name, 'index.js'),
+ ''
+ )
+}
+
+function mkPkg (json) {
+ var pkgPath = path.resolve(pkg, json.name)
+ mkdirp.sync(pkgPath)
+ fs.writeFileSync(
+ path.join(pkgPath, 'package.json'),
+ JSON.stringify(json, null, 2)
+ )
+ return pkgPath
+}