Skip to content

Commit

Permalink
only validate / separator in package names
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Jun 17, 2018
1 parent 9b20fa7 commit 2b9539a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 90 deletions.
24 changes: 1 addition & 23 deletions package-name-map/src/package-name-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,11 @@ function validateScope(scope: Scope) {
}
function validatePackage([pkgName, pkg]: [string, Package]) {
// package name validation
if (pkgName.match(/(^|\/|\\)\.\.?[\/\\]/)) {
throw new Error(
`Invalid package name ${pkgName}, package names must not contain dot segments.`
);
}
if (pkgName.match(/^\/\\|\/\\$/)) {
if (pkgName.startsWith('/') || pkgName.endsWith('/')) {
throw new Error(
`Invalid package name ${pkgName}, package names cannot start or end with a path separator.`
);
}
if (pkgName.indexOf(':') !== -1 && isURL(pkgName)) {
throw new Error(
`Invalid package name ${pkgName}, package names cannot be URLs.`
);
}
if (pkg.path !== undefined && typeof pkg.path !== 'string') {
throw new Error(
`Invalid package for ${pkgName}, path expected to be a string.`
Expand Down Expand Up @@ -185,18 +175,6 @@ export class PackageNameMap {
}
}

/**
* Returns true iff `s` parses as a URL.
*/
const isURL = (s: string): boolean => {
try {
new URL(s);
return true;
} catch (e) {
return false;
}
};

const ensureTrailingSlash = (s: string) => (s.length === 0 || s.endsWith('/') ? s : s + '/');

/**
Expand Down
141 changes: 74 additions & 67 deletions package-name-map/src/test/package-name-map_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const {assert} = chai;

suite('PackageNameMap', () => {
suite('resolve', () => {
const referrerURL = 'http://foo.com/bar/baz.html';
const referrerURL = 'http://bar.com/bar/baz.html';
const baseURL = 'http://foo.com/resources/package-name-map.json';

suite('does not modify already valid specifiers', () => {
Expand All @@ -42,13 +42,13 @@ suite('PackageNameMap', () => {
});

test('does not modify valid paths', () => {
assert.equal(map.resolve('/foo', referrerURL), 'http://foo.com/foo');
assert.equal(map.resolve('/foo', referrerURL), 'http://bar.com/foo');
assert.equal(
map.resolve('./foo', referrerURL),
'http://foo.com/bar/foo'
'http://bar.com/bar/foo'
);
assert.equal(map.resolve('./foo', referrerURL), 'http://foo.com/bar/foo');
assert.equal(map.resolve('../foo', referrerURL), 'http://foo.com/foo');
assert.equal(map.resolve('./foo', referrerURL), 'http://bar.com/bar/foo');
assert.equal(map.resolve('../foo', referrerURL), 'http://bar.com/foo');
});
});

Expand Down Expand Up @@ -285,6 +285,7 @@ suite('isPathSegmentPrefix', () => {
suite('some pathological cases', () => {

const referrerURL = 'http://foo.com/bar/baz.html';
const baseURL = 'http://foo.com/resources/package-name-map.json';

suite('package map init validations', () => {
test('Invalid path_prefix type', () => {
Expand All @@ -302,7 +303,7 @@ suite('some pathological cases', () => {
},
},
},
referrerURL
baseURL
);
assert.fail();
}
Expand All @@ -322,7 +323,7 @@ suite('some pathological cases', () => {
},
},
},
referrerURL
baseURL
);
assert.fail();
}
Expand All @@ -337,7 +338,7 @@ suite('some pathological cases', () => {
{
scopes: <any>'asdf'
},
referrerURL
baseURL
);
assert.fail();
}
Expand All @@ -358,7 +359,7 @@ suite('some pathological cases', () => {
},
},
},
referrerURL
baseURL
);
assert.fail();
}
Expand All @@ -378,7 +379,7 @@ suite('some pathological cases', () => {
},
},
},
referrerURL
baseURL
);
assert.fail();
}
Expand Down Expand Up @@ -412,60 +413,68 @@ suite('some pathological cases', () => {

suite('package name validations', () => {
test('dot segments at start of package name', () => {
try {
new PackageNameMap(
{
path_prefix: '/node_modules',
packages: {
'..\\moment': {
main: 'moment.js',
},
const map = new PackageNameMap(
{
path_prefix: '/node_modules',
packages: {
'..\\moment': {
main: 'moment.js',
},
},
referrerURL
);
assert.fail();
}
catch (err) {
assert.equal(err.message, `Invalid package name ..\\moment, package names must not contain dot segments.`);
}
},
referrerURL
);
assert.equal(map.resolve('..\\moment', referrerURL), 'http://foo.com/moment/moment.js');
});

test('dot segments and separator at start of package name', () => {
try {
new PackageNameMap(
{
path_prefix: 'baz',
packages: {
'..\\/moment': {
main: 'moment.js',
},
const map = new PackageNameMap(
{
path_prefix: 'baz',
packages: {
'..\\/moment': {
main: 'moment.js',
},
},
referrerURL
);
}
catch (err) {
assert.equal(err.message, `Invalid package name ..\\/moment, package names must not contain dot segments.`);
}
},
referrerURL
);
assert.equal(map.resolve('..\\/moment', referrerURL), 'http://foo.com/bar//moment/moment.js');
});

test('dot segments within package name', () => {
try {
new PackageNameMap(
{
path_prefix: '/node_modules',
packages: {
'moment/../notmoment': {
main: 'moment.js',
},
const map = new PackageNameMap(
{
path_prefix: '/node_modules',
packages: {
'moment/../notmoment': {
main: 'moment.js',
},
},
referrerURL
);
},
baseURL
);
assert.equal(map.resolve('moment/../notmoment', referrerURL), 'http://foo.com/node_modules/notmoment/moment.js');
});

test('dot segments within package name subpath', () => {
const map = new PackageNameMap(
{
path_prefix: '/node_modules',
packages: {
'moment/../notmoment': {
main: 'moment.js',
},
},
},
baseURL
);
try {
assert.equal(map.resolve('moment/../notmoment/x', referrerURL), 'http://foo.com/node_modules');
assert.fail();
}
catch (err) {
assert.equal(err.message, `Invalid package name moment/../notmoment, package names must not contain dot segments.`);
assert.equal(err.message, 'Cannot resolve specifier, no path found for package moment/../notmoment');
}
});

Expand All @@ -481,8 +490,9 @@ suite('some pathological cases', () => {
},
},
},
referrerURL
baseURL
);
assert.fail();
}
catch (err) {
assert.equal(err.message, `Invalid package name moment/, package names cannot start or end with a path separator.`);
Expand All @@ -501,32 +511,29 @@ suite('some pathological cases', () => {
},
},
},
referrerURL
baseURL
);
assert.fail();
}
catch (err) {
assert.equal(err.message, `Invalid package name /moment, package names cannot start or end with a path separator.`);
}
});

test('url', () => {
try {
new PackageNameMap(
{
path_prefix: '/node_modules',
packages: {
'http://foo.com/pkg': {
path: 'y',
main: 'moment.js',
},
const map = new PackageNameMap(
{
path_prefix: '/node_modules',
packages: {
'http://foo.com/pkg': {
path: 'y',
main: 'moment.js',
},
},
referrerURL
);
}
catch (err) {
assert.equal(err.message, `Invalid package name http://foo.com/pkg, package names cannot be URLs.`);
}
},
baseURL
);
assert.equal(map.resolve('http://foo.com/pkg', referrerURL), 'http://foo.com/pkg');
});
});
});

0 comments on commit 2b9539a

Please sign in to comment.