Skip to content

Commit 4b2b392

Browse files
committed
[Fix] sync/async: when package.json main is not a string, throw an error
Fixes #178.
1 parent d652f01 commit 4b2b392

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

lib/async.js

+5
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ module.exports = function resolve(x, options, callback) {
161161
}
162162

163163
if (pkg.main) {
164+
if (typeof pkg.main !== 'string') {
165+
var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
166+
mainError.code = 'INVALID_PACKAGE_MAIN';
167+
return cb(mainError);
168+
}
164169
if (pkg.main === '.' || pkg.main === './') {
165170
pkg.main = 'index';
166171
}

lib/sync.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,28 @@ module.exports = function (x, options) {
101101
try {
102102
var body = readFileSync(pkgfile, 'UTF8');
103103
var pkg = JSON.parse(body);
104+
} catch (e) {}
104105

105-
if (opts.packageFilter) {
106-
pkg = opts.packageFilter(pkg, x);
107-
}
106+
if (opts.packageFilter) {
107+
pkg = opts.packageFilter(pkg, x);
108+
}
108109

109-
if (pkg.main) {
110-
if (pkg.main === '.' || pkg.main === './') {
111-
pkg.main = 'index';
112-
}
110+
if (pkg.main) {
111+
if (typeof pkg.main !== 'string') {
112+
var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
113+
mainError.code = 'INVALID_PACKAGE_MAIN';
114+
throw mainError;
115+
}
116+
if (pkg.main === '.' || pkg.main === './') {
117+
pkg.main = 'index';
118+
}
119+
try {
113120
var m = loadAsFileSync(path.resolve(x, pkg.main));
114121
if (m) return m;
115122
var n = loadAsDirectorySync(path.resolve(x, pkg.main));
116123
if (n) return n;
117-
}
118-
} catch (e) {}
124+
} catch (e) {}
125+
}
119126
}
120127

121128
return loadAsFileSync(path.join(x, '/index'));

test/resolver.js

+13
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,19 @@ test('not a directory', function (t) {
376376
});
377377
});
378378

379+
test('non-string "main" field in package.json', function (t) {
380+
t.plan(5);
381+
382+
var dir = path.join(__dirname, 'resolver');
383+
resolve('./invalid_main', { basedir: dir }, function (err, res, pkg) {
384+
t.ok(err, 'errors on non-string main');
385+
t.equal(err.message, 'package “invalid main” `main` must be a string');
386+
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
387+
t.equal(res, undefined, 'res is undefined');
388+
t.equal(pkg, undefined, 'pkg is undefined');
389+
});
390+
});
391+
379392
test('browser field in package.json', function (t) {
380393
t.plan(3);
381394

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "invalid main",
3+
"main": [
4+
"why is this a thing",
5+
"srsly omg wtf"
6+
]
7+
}

test/resolver_sync.js

+14
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,20 @@ test('not a directory', function (t) {
294294
t.end();
295295
});
296296

297+
test('non-string "main" field in package.json', function (t) {
298+
var dir = path.join(__dirname, 'resolver');
299+
try {
300+
var result = resolve.sync('./invalid_main', { basedir: dir });
301+
t.equal(result, undefined, 'result should not exist');
302+
t.fail('should not get here');
303+
} catch (err) {
304+
t.ok(err, 'errors on non-string main');
305+
t.equal(err.message, 'package “invalid main” `main` must be a string');
306+
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
307+
}
308+
t.end();
309+
});
310+
297311
test('browser field in package.json', function (t) {
298312
var dir = path.join(__dirname, 'resolver');
299313
var res = resolve.sync('./browser_field', {

0 commit comments

Comments
 (0)