зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1582266 - Use actual source text when mismatches are found with contents fetched over the network, r=loganfsmyth.
Differential Revision: https://phabricator.services.mozilla.com/D55402 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
0beec6773c
Коммит
ee87de9d1b
|
@ -184,3 +184,4 @@ skip-if = debug
|
|||
skip-if = asan # Bug 1591064
|
||||
[browser_dbg-toolbox-workers.js]
|
||||
skip-if = asan || !nightly_build # Bug 1591064, parent intercept mode is needed bug 1588154
|
||||
[browser_dbg-wrong-fetch.js]
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// Test that incorrect source contents are not shown if the server refetches
|
||||
// different HTML when attaching to an open page.
|
||||
|
||||
add_task(async function() {
|
||||
await addTab(EXAMPLE_URL + "different_html.sjs");
|
||||
|
||||
// This goop is here to manually clear the HTTP cache because setting response
|
||||
// headers in different_html.sjs to not cache the response doesn't work.
|
||||
const cacheStorageSrv = SpecialPowers.Cc[
|
||||
"@mozilla.org/netwerk/cache-storage-service;1"
|
||||
].getService(Ci.nsICacheStorageService);
|
||||
cacheStorageSrv.clear();
|
||||
|
||||
const toolbox = await openToolboxForTab(gBrowser.selectedTab, "jsdebugger");
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
await selectSource(dbg, "different_html.sjs");
|
||||
await waitForLoadedSource(dbg, "different_html.sjs");
|
||||
const contents = findSourceContent(dbg, "different_html.sjs");
|
||||
|
||||
ok(contents.value.includes("Incorrect contents fetched"), "Error message is shown");
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const contents = `
|
||||
<div>Hello COUNTER</div>
|
||||
<script>
|
||||
function f() {
|
||||
console.log("First Inline Script " + COUNTER);
|
||||
}
|
||||
setInterval(f, 1000);
|
||||
</script>
|
||||
<script>
|
||||
function f() {
|
||||
console.log("Second Inline Script " + COUNTER);
|
||||
}
|
||||
setInterval(f, 1000);
|
||||
</script>
|
||||
`;
|
||||
|
||||
function handleRequest(request, response) {
|
||||
response.setHeader("Cache-Control", "no-store");
|
||||
response.setHeader("Content-Type", "text/html");
|
||||
|
||||
let counter = 1 + (+getState("counter") % 4);
|
||||
setState("counter", "" + counter);
|
||||
|
||||
response.write(contents.replace(/COUNTER/g, counter));
|
||||
}
|
|
@ -239,16 +239,7 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
(this._contentType.includes("javascript") ||
|
||||
this._contentType === "text/wasm")
|
||||
) {
|
||||
// If the source doesn't start at line 1, line numbers in the client will
|
||||
// not match up with those in the source. Pad the text with blank lines to
|
||||
// fix this. This can show up for sources associated with inline scripts
|
||||
// in HTML created via document.write() calls: the script's source line
|
||||
// number is relative to the start of the written HTML, but we show the
|
||||
// source's content by itself.
|
||||
const padding = this._source.startLine
|
||||
? "\n".repeat(this._source.startLine - 1)
|
||||
: "";
|
||||
return toResolvedContent(padding + this._source.text);
|
||||
return toResolvedContent(this.actualText());
|
||||
}
|
||||
|
||||
const result = await this.sources.urlContents(
|
||||
|
@ -263,6 +254,37 @@ const SourceActor = ActorClassWithSpec(sourceSpec, {
|
|||
return result;
|
||||
},
|
||||
|
||||
// Get the actual text of this source, padded so that line numbers will match
|
||||
// up with the source itself.
|
||||
actualText() {
|
||||
// If the source doesn't start at line 1, line numbers in the client will
|
||||
// not match up with those in the source. Pad the text with blank lines to
|
||||
// fix this. This can show up for sources associated with inline scripts
|
||||
// in HTML created via document.write() calls: the script's source line
|
||||
// number is relative to the start of the written HTML, but we show the
|
||||
// source's content by itself.
|
||||
const padding = this._source.startLine
|
||||
? "\n".repeat(this._source.startLine - 1)
|
||||
: "";
|
||||
return padding + this._source.text;
|
||||
},
|
||||
|
||||
// Return whether the specified fetched contents includes the actual text of
|
||||
// this source in the expected position.
|
||||
contentMatches(fileContents) {
|
||||
const lineBreak = /\r\n?|\n|\u2028|\u2029/;
|
||||
const contentLines = fileContents.content.split(lineBreak);
|
||||
const sourceLines = this._source.text.split(lineBreak);
|
||||
let line = this._source.startLine - 1;
|
||||
for (const sourceLine of sourceLines) {
|
||||
const contentLine = contentLines[line++] || "";
|
||||
if (!contentLine.includes(sourceLine)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
getBreakableLines: async function() {
|
||||
const positions = await this.getBreakpointPositions();
|
||||
const lines = new Set();
|
||||
|
|
|
@ -587,6 +587,25 @@ TabSources.prototype = {
|
|||
throw error;
|
||||
}
|
||||
|
||||
// When we fetch the contents, there is a risk that the contents we get
|
||||
// do not match up with the actual text of the sources these contents will
|
||||
// be associated with. We want to always show contents that include that
|
||||
// actual text (otherwise it will be very confusing or unusable for users),
|
||||
// so replace the contents with the actual text if there is a mismatch.
|
||||
const actors = [...this._sourceActors.values()].filter(
|
||||
actor => actor.url == url
|
||||
);
|
||||
if (!actors.every(actor => actor.contentMatches(result))) {
|
||||
if (actors.length > 1) {
|
||||
// When there are multiple actors we won't be able to show the source
|
||||
// for all of them. Ask the user to reload so that we don't have to do
|
||||
// any fetching.
|
||||
result.content = "Error: Incorrect contents fetched, please reload.";
|
||||
} else {
|
||||
result.content = actors[0].actualText();
|
||||
}
|
||||
}
|
||||
|
||||
this._urlContents.set(url, { ...result, complete: true });
|
||||
|
||||
return result;
|
||||
|
|
Загрузка…
Ссылка в новой задаче