Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Commit

Permalink
Support absolute local paths in sourceRoot and sourceMappingURL to fix
Browse files Browse the repository at this point in the history
  • Loading branch information
roblourens committed Jul 16, 2018
1 parent 387267c commit eb552d6
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 7 deletions.
21 changes: 14 additions & 7 deletions src/sourceMaps/sourceMapUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ export function getComputedSourceRoot(sourceRoot: string, generatedPath: string,
if (sourceRoot.startsWith('file:///')) {
// sourceRoot points to a local path like "file:///c:/project/src", make it an absolute path
absSourceRoot = utils.canonicalizeUrl(sourceRoot);
} else if (sourceRoot.startsWith('/')) {
// sourceRoot is like "/src", would be like http://localhost/src, resolve to a local path under webRoot
// note that C:/src (or /src as an absolute local path) is not a valid sourceroot
absSourceRoot = chromeUtils.applyPathMappingsToTargetUrlPath(sourceRoot, pathMapping);
} else if (utils.isAbsolute(sourceRoot)) {
// sourceRoot is like "/src", should be like http://localhost/src, resolve to a local path using pathMaping.
// If path mappings do not apply (e.g. node), assume that sourceRoot is actually a local absolute path.
// Technically not valid but it's easy to end up with paths like this.
absSourceRoot = chromeUtils.applyPathMappingsToTargetUrlPath(sourceRoot, pathMapping) || sourceRoot;

// If no pathMapping (node), use sourceRoot as is.
// But we also should handle an absolute sourceRoot for chrome? Does CDT handle that? No it does not, it interprets it as "localhost/full path here"
} else if (path.isAbsolute(generatedPath)) {
// sourceRoot is like "src" or "../src", relative to the script
absSourceRoot = resolveRelativeToFile(generatedPath, sourceRoot);
Expand Down Expand Up @@ -120,10 +124,13 @@ export function resolveMapPath(pathToGenerated: string, mapPath: string, pathMap
}

// runtime script is not on disk, map won't be either, resolve a URL for the map relative to the script
const mapUrlPathSegment = mapPath.startsWith('/') ? mapPath : path.posix.join(path.dirname(scriptPath), mapPath);
// handle c:/ here too
const mapUrlPathSegment = utils.isAbsolute(mapPath) ?
mapPath :
path.posix.join(path.dirname(scriptPath), mapPath);
mapPath = `${scriptUrl.protocol}//${scriptUrl.host}${mapUrlPathSegment}`;
} else if (mapPath.startsWith('/')) {
mapPath = chromeUtils.applyPathMappingsToTargetUrlPath(mapPath, pathMapping);
} else if (utils.isAbsolute(mapPath)) {
mapPath = chromeUtils.applyPathMappingsToTargetUrlPath(mapPath, pathMapping) || mapPath;
} else if (path.isAbsolute(pathToGenerated)) {
// mapPath needs to be resolved to an absolute path or a URL
// runtime script is on disk, so map should be too
Expand Down
8 changes: 8 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,14 @@ export function isURL(urlOrPath: string): boolean {
return urlOrPath && !path.isAbsolute(urlOrPath) && !!url.parse(urlOrPath).protocol;
}

export function isAbsolute(_path: string): boolean {
return _path.startsWith('/') || isAbsolute_win(_path);
}

export function isAbsolute_win(_path: string): boolean {
return /^[a-zA-Z]\:[\\\/]/.test(_path);
}

/**
* Strip a string from the left side of a string
*/
Expand Down
24 changes: 24 additions & 0 deletions test/sourceMaps/sourceMapUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ suite('SourceMapUtils', () => {
testUtils.pathResolve('/project/webroot/src'));
});

test('handles /src style without matching pathMapping', () => {
assert.equal(
getComputedSourceRoot('/foo/bar', GEN_PATH, { }),
testUtils.pathResolve('/foo/bar'));
});

test('handles c:/src style without matching pathMapping', () => {
assert.equal(
getComputedSourceRoot('c:\\foo\\bar', GEN_PATH, { }),
'c:\\foo\\bar');
});

test('handles ../../src style sourceRoot', () => {
assert.equal(
getComputedSourceRoot('../../src', GEN_PATH, PATH_MAPPING),
Expand Down Expand Up @@ -223,6 +235,18 @@ suite('SourceMapUtils', () => {
assert.equal(resolveMapPath(scriptUrl, slashPath, { '/' : testUtils.pathResolve('/foo/bar') }), testUtils.pathResolve('/foo/bar/maps/app.js.map'));
});

test('works for /local path without valid pathMapping', () => {
const slashPath = '/maps/app.js.map';
const scriptUrl = testUtils.pathResolve('/foo/bar/project/app.js');
assert.equal(resolveMapPath(scriptUrl, slashPath, { }), '/maps/app.js.map');
});

test('works for c:/local path without valid pathMapping', () => {
const slashPath = 'c:/maps/app.js.map';
const scriptUrl = testUtils.pathResolve('/foo/bar/project/app.js');
assert.equal(resolveMapPath(scriptUrl, slashPath, { }), 'c:/maps/app.js.map');
});

test('works for a file:/// url', () => {
const winFileUrl = 'file:///c:/project/app.js.map';
const notWinFileUrl = 'file:///project/app.js.map';
Expand Down
24 changes: 24 additions & 0 deletions test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,4 +430,28 @@ suite('Utils', () => {
});
});
});

suite('isAbsolute_win', () => {
test('true for windows-style absolute paths', () => {
[
'c:/foo/bar/blah.js',
'c:/',
'z:/foo',
'z:\\',
'z:\\foo',
].forEach(testPath => assert(getUtils().isAbsolute_win(testPath)))
});

test('false for everything else', () => {
[
'c :/foo/bar/blah.js',
'c:',
'ö:/foo',
'/foo/bar',
'foo/bar',
'',
'file:///foo/bar/blah.js',
].forEach(testPath => assert.equal(getUtils().isAbsolute_win(testPath), false))
});
});
});

0 comments on commit eb552d6

Please sign in to comment.