Skip to content
This repository was archived by the owner on Aug 11, 2022. It is now read-only.

Commit 952f1e1

Browse files
IonicaBizauiarna
authored andcommitted
deps: Guard against null "bin" values in package.json
Fixes: #13997 Credit: @IonicaBizau PR-URL: #13999 Reviewed-By: @iarna
1 parent 1089878 commit 952f1e1

File tree

2 files changed

+94
-3
lines changed

2 files changed

+94
-3
lines changed

lib/install/deps.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -612,13 +612,13 @@ var earliestInstallable = exports.earliestInstallable = function (requiredBy, tr
612612

613613
// If any of the children of this tree have conflicting
614614
// binaries then we need to decline to install this package here.
615-
var binaryMatches = typeof pkg.bin === 'object' && tree.children.some(function (child) {
616-
if (child.removed) return false
617-
if (typeof child.package.bin !== 'object') return false
615+
var binaryMatches = pkg.bin && tree.children.some(function (child) {
616+
if (child.removed || !child.package.bin) return false
618617
return Object.keys(child.package.bin).some(function (bin) {
619618
return pkg.bin[bin]
620619
})
621620
})
621+
622622
if (binaryMatches) return null
623623

624624
// if this tree location requested the same module then we KNOW it

test/tap/install-bin-null.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
var fs = require('graceful-fs')
2+
var path = require('path')
3+
4+
var mkdirp = require('mkdirp')
5+
var osenv = require('osenv')
6+
var rimraf = require('rimraf')
7+
var test = require('tap').test
8+
9+
var common = require('../common-tap.js')
10+
11+
var pkg = path.join(__dirname, 'install-bin-null')
12+
13+
var EXEC_OPTS = { cwd: pkg }
14+
15+
var parentPkg = {
16+
name: 'parent-package',
17+
version: '0.0.0',
18+
dependencies: {
19+
'child-package-a': 'file:./child-package-a',
20+
'child-package-b': 'file:./child-package-b'
21+
}
22+
}
23+
24+
var childPkgA = {
25+
name: 'child-package-a',
26+
version: '0.0.0',
27+
bin: 'index.js'
28+
}
29+
30+
var childPkgB = {
31+
name: 'child-package-b',
32+
version: '0.0.0',
33+
dependencies: {
34+
'grandchild-package': 'file:../grandchild-package'
35+
}
36+
}
37+
38+
var grandchildPkg = {
39+
name: 'grandchild-package',
40+
version: '0.0.0',
41+
bin: null
42+
}
43+
44+
var pkgs = [childPkgA, childPkgB, grandchildPkg]
45+
46+
test('the grandchild has bin:null', function (t) {
47+
setup()
48+
common.npm(['install'], EXEC_OPTS, function (err, code, stdout, stderr) {
49+
t.ifErr(err, 'npm link finished without error')
50+
t.equal(code, 0, 'exited ok')
51+
t.ok(stdout, 'output indicating success')
52+
t.notOk(stderr, 'no output stderr')
53+
t.end()
54+
})
55+
})
56+
57+
test('cleanup', function (t) {
58+
cleanup()
59+
t.end()
60+
})
61+
62+
function cleanup () {
63+
process.chdir(osenv.tmpdir())
64+
rimraf.sync(pkg)
65+
}
66+
67+
function setup () {
68+
cleanup()
69+
mkdirp.sync(pkg)
70+
fs.writeFileSync(
71+
path.join(pkg, 'package.json'),
72+
JSON.stringify(parentPkg, null, 2)
73+
)
74+
pkgs.forEach(function (json) {
75+
process.chdir(mkPkg(json))
76+
})
77+
fs.writeFileSync(
78+
path.join(pkg, childPkgA.name, 'index.js'),
79+
''
80+
)
81+
}
82+
83+
function mkPkg (json) {
84+
var pkgPath = path.resolve(pkg, json.name)
85+
mkdirp.sync(pkgPath)
86+
fs.writeFileSync(
87+
path.join(pkgPath, 'package.json'),
88+
JSON.stringify(json, null, 2)
89+
)
90+
return pkgPath
91+
}

0 commit comments

Comments
 (0)