mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 849069 - relative source map URLs should be resolved according to the spec's rules; r=past
This commit is contained in:
parent
6de4bef71a
commit
c1e0cabf5f
@ -24,7 +24,6 @@
|
||||
|
||||
}).call(this);
|
||||
|
||||
// TODO bug 849069: this should just be "binary_search.map", not a full path.
|
||||
/*
|
||||
//@ sourceMappingURL=http://example.com/browser/browser/devtools/debugger/test/binary_search.map
|
||||
//@ sourceMappingURL=binary_search.map
|
||||
*/
|
||||
|
@ -1,8 +1,9 @@
|
||||
{
|
||||
"version": 3,
|
||||
"file": "binary_search.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"http://example.com/browser/browser/devtools/debugger/test/binary_search.coffee"
|
||||
"binary_search.coffee"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";AACA;CAAA;CAAA,CAAA,CAAuB,EAAA,CAAjB,GAAkB,IAAxB;CAEE,OAAA,UAAA;CAAA,EAAQ,CAAR,CAAA;CAAA,EACQ,CAAR,CAAa,CAAL;CADR,EAEQ,CAAR,CAAA;CAEA,EAA0C,CAAR,CAAtB,MAAN;CAGJ,EAA6B,CAAR,CAAA,CAArB;CAAA,EAAQ,CAAR,CAAQ,GAAR;QAAA;CACA,EAA6B,CAAR,CAAA,CAArB;CAAA,EAAQ,EAAR,GAAA;QADA;CAAA,EAIQ,CAAI,CAAZ,CAAA;CAXF,IAIA;CAUA,GAAA,CAAS;CAAT,YAA8B;MAA9B;AAA0C,CAAD,YAAA;MAhBpB;CAAvB,EAAuB;CAAvB"
|
||||
|
@ -525,7 +525,9 @@ ThreadActor.prototype = {
|
||||
originalLine)
|
||||
return locationPromise.then((aLocation) => {
|
||||
let line = aLocation.line;
|
||||
if (this.dbg.findScripts({ url: aLocation.url }).length == 0 || line < 0) {
|
||||
if (this.dbg.findScripts({ url: aLocation.url }).length == 0 ||
|
||||
line < 0 ||
|
||||
line == null) {
|
||||
return { error: "noScript" };
|
||||
}
|
||||
|
||||
@ -2405,7 +2407,7 @@ ThreadSources.prototype = {
|
||||
];
|
||||
}, (e) => {
|
||||
reportError(e);
|
||||
delete this._sourceMaps[aScript.sourceMapURL];
|
||||
delete this._sourceMaps[this._normalize(aScript.sourceMapURL, aScript.url)];
|
||||
delete this._sourceMapsByGeneratedSource[aScript.url];
|
||||
return [this.source(aScript.url)];
|
||||
})
|
||||
@ -2422,7 +2424,9 @@ ThreadSources.prototype = {
|
||||
return this._sourceMapsByGeneratedSource[aScript.url];
|
||||
}
|
||||
dbg_assert(aScript.sourceMapURL);
|
||||
let map = this._fetchSourceMap(aScript.sourceMapURL)
|
||||
let sourceMapURL = this._normalize(aScript.sourceMapURL,
|
||||
aScript.url);
|
||||
let map = this._fetchSourceMap(sourceMapURL)
|
||||
.then((aSourceMap) => {
|
||||
for (let s of aSourceMap.sources) {
|
||||
this._generatedUrlsByOriginalUrl[s] = aScript.url;
|
||||
@ -2437,14 +2441,21 @@ ThreadSources.prototype = {
|
||||
/**
|
||||
* Fetch the source map located at the given url.
|
||||
*/
|
||||
_fetchSourceMap: function TS__featchSourceMap(aSourceMapURL) {
|
||||
if (aSourceMapURL in this._sourceMaps) {
|
||||
return this._sourceMaps[aSourceMapURL];
|
||||
_fetchSourceMap: function TS__fetchSourceMap(aAbsSourceMapURL) {
|
||||
if (aAbsSourceMapURL in this._sourceMaps) {
|
||||
return this._sourceMaps[aAbsSourceMapURL];
|
||||
} else {
|
||||
let promise = fetch(aSourceMapURL).then(function (rawSourceMap) {
|
||||
return new SourceMapConsumer(rawSourceMap);
|
||||
let promise = fetch(aAbsSourceMapURL).then((rawSourceMap) => {
|
||||
let map = new SourceMapConsumer(rawSourceMap);
|
||||
let base = aAbsSourceMapURL.replace(/\/[^\/]+$/, '/');
|
||||
if (base.indexOf("data:") !== 0) {
|
||||
map.sourceRoot = map.sourceRoot
|
||||
? this._normalize(map.sourceRoot, base)
|
||||
: base;
|
||||
}
|
||||
return map;
|
||||
});
|
||||
this._sourceMaps[aSourceMapURL] = promise;
|
||||
this._sourceMaps[aAbsSourceMapURL] = promise;
|
||||
return promise;
|
||||
}
|
||||
},
|
||||
@ -2507,6 +2518,19 @@ ThreadSources.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Normalize multiple relative paths towards the base paths on the right.
|
||||
*/
|
||||
_normalize: function TS__normalize(...aURLs) {
|
||||
dbg_assert(aURLs.length > 1);
|
||||
let base = Services.io.newURI(aURLs.pop(), null, null);
|
||||
let url;
|
||||
while ((url = aURLs.pop())) {
|
||||
base = Services.io.newURI(url, null, base);
|
||||
}
|
||||
return base.spec;
|
||||
},
|
||||
|
||||
iter: function TS_iter() {
|
||||
for (let url in this._sourceActors) {
|
||||
yield this._sourceActors[url];
|
||||
|
@ -175,6 +175,14 @@ function finishClient(aClient)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a relative file path and returns the absolute file url for it.
|
||||
*/
|
||||
function getFileUrl(aName) {
|
||||
let file = do_get_file(aName);
|
||||
return Services.io.newFileURI(file).spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full path of the file with the specified name in a
|
||||
* platform-independent and URL-like form.
|
||||
@ -190,3 +198,20 @@ function getFilePath(aName)
|
||||
}
|
||||
return path.slice(filePrePath.length);
|
||||
}
|
||||
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
/**
|
||||
* Returns the full text contents of the given file.
|
||||
*/
|
||||
function readFile(aFileName) {
|
||||
let f = do_get_file(aFileName);
|
||||
let s = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
s.init(f, -1, -1, false);
|
||||
try {
|
||||
return NetUtil.readInputStreamToString(s, s.available());
|
||||
} finally {
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
foo = (n) ->
|
||||
return "foo" + i for i in [0...n]
|
||||
|
||||
[first, second, third] = foo(3)
|
||||
|
||||
debugger
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 3,
|
||||
"file": "sourcemapped.js",
|
||||
"sourceRoot": "",
|
||||
"sources": [
|
||||
"sourcemapped.coffee"
|
||||
],
|
||||
"names": [],
|
||||
"mappings": ";AAAA;CAAA,KAAA,yBAAA;CAAA;CAAA,CAAA,CAAA,MAAO;CACL,IAAA,GAAA;AAAA,CAAA,EAAA,MAA0B,qDAA1B;CAAA,EAAe,EAAR,QAAA;CAAP,IADI;CAAN,EAAM;;CAAN,CAGA,CAAyB,IAAA;;CAEzB,UALA;CAAA"
|
||||
}
|
16
toolkit/devtools/debugger/tests/unit/sourcemapped.js
Normal file
16
toolkit/devtools/debugger/tests/unit/sourcemapped.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Generated by CoffeeScript 1.6.1
|
||||
(function() {
|
||||
var first, foo, second, third, _ref;
|
||||
|
||||
foo = function(n) {
|
||||
var i, _i;
|
||||
for (i = _i = 0; 0 <= n ? _i < n : _i > n; i = 0 <= n ? ++_i : --_i) {
|
||||
return "foo" + i;
|
||||
}
|
||||
};
|
||||
|
||||
_ref = foo(3), first = _ref[0], second = _ref[1], third = _ref[2];
|
||||
|
||||
debugger;
|
||||
|
||||
}).call(this);
|
@ -10,8 +10,6 @@ var gThreadClient;
|
||||
// and that they can communicate over the protocol to fetch the source text for
|
||||
// a given script.
|
||||
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
function run_test()
|
||||
{
|
||||
initTestDebuggerServer();
|
||||
@ -60,15 +58,9 @@ function test_source()
|
||||
do_check_true(!aResponse.error);
|
||||
do_check_true(!!aResponse.source);
|
||||
|
||||
let f = do_get_file("test_source-01.js", false);
|
||||
let s = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
s.init(f, -1, -1, false);
|
||||
|
||||
do_check_eq(NetUtil.readInputStreamToString(s, s.available()),
|
||||
do_check_eq(readFile("test_source-01.js"),
|
||||
aResponse.source);
|
||||
|
||||
s.close();
|
||||
gThreadClient.resume(function () {
|
||||
finishClient(gClient);
|
||||
});
|
||||
|
48
toolkit/devtools/debugger/tests/unit/test_sourcemaps-04.js
Normal file
48
toolkit/devtools/debugger/tests/unit/test_sourcemaps-04.js
Normal file
@ -0,0 +1,48 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check that absolute source map urls work.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
Components.utils.import('resource:///modules/devtools/SourceMap.jsm');
|
||||
|
||||
function run_test()
|
||||
{
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-source-map");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function() {
|
||||
attachTestGlobalClientAndResume(gClient, "test-source-map", function(aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_absolute_source_map();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_absolute_source_map()
|
||||
{
|
||||
gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
|
||||
do_check_eq(aEvent, "newSource");
|
||||
do_check_eq(aPacket.type, "newSource");
|
||||
do_check_true(!!aPacket.source);
|
||||
|
||||
do_check_true(aPacket.source.url.indexOf("sourcemapped.coffee") !== -1,
|
||||
"The new source should be a coffee file.");
|
||||
do_check_eq(aPacket.source.url.indexOf("sourcemapped.js"), -1,
|
||||
"The new source should not be a js file.");
|
||||
|
||||
finishClient(gClient);
|
||||
});
|
||||
|
||||
code = readFile("sourcemapped.js")
|
||||
+ "\n//@ sourceMappingURL=" + getFileUrl("source-map-data/sourcemapped.map");
|
||||
|
||||
Components.utils.evalInSandbox(code, gDebuggee, "1.8",
|
||||
getFileUrl("sourcemapped.js"), 1);
|
||||
}
|
48
toolkit/devtools/debugger/tests/unit/test_sourcemaps-05.js
Normal file
48
toolkit/devtools/debugger/tests/unit/test_sourcemaps-05.js
Normal file
@ -0,0 +1,48 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Check that relative source map urls work.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
Components.utils.import('resource:///modules/devtools/SourceMap.jsm');
|
||||
|
||||
function run_test()
|
||||
{
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-source-map");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect(function() {
|
||||
attachTestGlobalClientAndResume(gClient, "test-source-map", function(aResponse, aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
test_relative_source_map();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_relative_source_map()
|
||||
{
|
||||
gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
|
||||
do_check_eq(aEvent, "newSource");
|
||||
do_check_eq(aPacket.type, "newSource");
|
||||
do_check_true(!!aPacket.source);
|
||||
|
||||
do_check_true(aPacket.source.url.indexOf("sourcemapped.coffee") !== -1,
|
||||
"The new source should be a coffee file.");
|
||||
do_check_eq(aPacket.source.url.indexOf("sourcemapped.js"), -1,
|
||||
"The new source should not be a js file.");
|
||||
|
||||
finishClient(gClient);
|
||||
});
|
||||
|
||||
code = readFile("sourcemapped.js")
|
||||
+ "\n//@ sourceMappingURL=source-map-data/sourcemapped.map";
|
||||
|
||||
Components.utils.evalInSandbox(code, gDebuggee, "1.8",
|
||||
getFileUrl("sourcemapped.js"), 1);
|
||||
}
|
@ -81,6 +81,12 @@ reason = bug 820380
|
||||
[test_sourcemaps-01.js]
|
||||
[test_sourcemaps-02.js]
|
||||
[test_sourcemaps-03.js]
|
||||
[test_sourcemaps-04.js]
|
||||
skip-if = toolkit == "gonk"
|
||||
reason = bug 820380
|
||||
[test_sourcemaps-05.js]
|
||||
skip-if = toolkit == "gonk"
|
||||
reason = bug 820380
|
||||
[test_objectgrips-01.js]
|
||||
[test_objectgrips-02.js]
|
||||
[test_objectgrips-03.js]
|
||||
|
@ -470,10 +470,34 @@ define('source-map/util', ['require', 'exports', 'module' , ], function(require,
|
||||
}
|
||||
exports.getArg = getArg;
|
||||
|
||||
var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;
|
||||
|
||||
function urlParse(aUrl) {
|
||||
var match = aUrl.match(urlRegexp);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
scheme: match[1],
|
||||
auth: match[3],
|
||||
host: match[4],
|
||||
port: match[6],
|
||||
path: match[7]
|
||||
};
|
||||
}
|
||||
|
||||
function join(aRoot, aPath) {
|
||||
return aPath.charAt(0) === '/'
|
||||
? aPath
|
||||
: aRoot.replace(/\/$/, '') + '/' + aPath;
|
||||
var url;
|
||||
|
||||
if (aPath.match(urlRegexp)) {
|
||||
return aPath;
|
||||
}
|
||||
|
||||
if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {
|
||||
return aRoot.replace(url.path, '') + aPath;
|
||||
}
|
||||
|
||||
return aRoot.replace(/\/$/, '') + '/' + aPath;
|
||||
}
|
||||
exports.join = join;
|
||||
|
||||
|
@ -145,9 +145,21 @@ define('test/source-map/util', ['require', 'exports', 'module' , 'lib/source-ma
|
||||
assert.equal(origMapping.column, originalColumn,
|
||||
'Incorrect column, expected ' + JSON.stringify(originalColumn)
|
||||
+ ', got ' + JSON.stringify(origMapping.column));
|
||||
assert.equal(origMapping.source,
|
||||
originalSource ? util.join(map._sourceRoot, originalSource) : null,
|
||||
'Incorrect source, expected ' + JSON.stringify(originalSource)
|
||||
|
||||
var expectedSource;
|
||||
|
||||
if (originalSource && map.sourceRoot && originalSource.indexOf(map.sourceRoot) === 0) {
|
||||
expectedSource = originalSource;
|
||||
} else if (originalSource) {
|
||||
expectedSource = map.sourceRoot
|
||||
? util.join(map.sourceRoot, originalSource)
|
||||
: originalSource;
|
||||
} else {
|
||||
expectedSource = null;
|
||||
}
|
||||
|
||||
assert.equal(origMapping.source, expectedSource,
|
||||
'Incorrect source, expected ' + JSON.stringify(expectedSource)
|
||||
+ ', got ' + JSON.stringify(origMapping.source));
|
||||
}
|
||||
|
||||
@ -238,10 +250,34 @@ define('lib/source-map/util', ['require', 'exports', 'module' , ], function(requ
|
||||
}
|
||||
exports.getArg = getArg;
|
||||
|
||||
var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;
|
||||
|
||||
function urlParse(aUrl) {
|
||||
var match = aUrl.match(urlRegexp);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
scheme: match[1],
|
||||
auth: match[3],
|
||||
host: match[4],
|
||||
port: match[6],
|
||||
path: match[7]
|
||||
};
|
||||
}
|
||||
|
||||
function join(aRoot, aPath) {
|
||||
return aPath.charAt(0) === '/'
|
||||
? aPath
|
||||
: aRoot.replace(/\/$/, '') + '/' + aPath;
|
||||
var url;
|
||||
|
||||
if (aPath.match(urlRegexp)) {
|
||||
return aPath;
|
||||
}
|
||||
|
||||
if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {
|
||||
return aRoot.replace(url.path, '') + aPath;
|
||||
}
|
||||
|
||||
return aRoot.replace(/\/$/, '') + '/' + aPath;
|
||||
}
|
||||
exports.join = join;
|
||||
|
||||
|
@ -251,8 +251,46 @@ define("test/source-map/test-source-map-consumer", ["require", "exports", "modul
|
||||
map = new SourceMapConsumer(map.toString());
|
||||
|
||||
var sources = map.sources;
|
||||
assert.equal(map.sources.length, 1);
|
||||
assert.equal(map.sources[0], 'http://www.example.com/original.js');
|
||||
assert.equal(sources.length, 1);
|
||||
assert.equal(sources[0], 'http://www.example.com/original.js');
|
||||
};
|
||||
|
||||
exports['test github issue #43'] = function (assert, util) {
|
||||
var map = new SourceMapGenerator({
|
||||
sourceRoot: 'http://example.com',
|
||||
file: 'foo.js'
|
||||
});
|
||||
map.addMapping({
|
||||
original: { line: 1, column: 1 },
|
||||
generated: { line: 2, column: 2 },
|
||||
source: 'http://cdn.example.com/original.js'
|
||||
});
|
||||
map = new SourceMapConsumer(map.toString());
|
||||
|
||||
var sources = map.sources;
|
||||
assert.equal(sources.length, 1,
|
||||
'Should only be one source.');
|
||||
assert.equal(sources[0], 'http://cdn.example.com/original.js',
|
||||
'Should not be joined with the sourceRoot.');
|
||||
};
|
||||
|
||||
exports['test absolute path, but same host sources'] = function (assert, util) {
|
||||
var map = new SourceMapGenerator({
|
||||
sourceRoot: 'http://example.com/foo/bar',
|
||||
file: 'foo.js'
|
||||
});
|
||||
map.addMapping({
|
||||
original: { line: 1, column: 1 },
|
||||
generated: { line: 2, column: 2 },
|
||||
source: '/original.js'
|
||||
});
|
||||
map = new SourceMapConsumer(map.toString());
|
||||
|
||||
var sources = map.sources;
|
||||
assert.equal(sources.length, 1,
|
||||
'Should only be one source.');
|
||||
assert.equal(sources[0], 'http://example.com/original.js',
|
||||
'Source should be relative the host of the source root.');
|
||||
};
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user