mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 467409 - (backslashplosion) Nested about:sessionrestore instances causes huge sessionstore.js file [r=dietrich]
This patch special cases the formdata we store for about:sessionrestore (which allows for nested instances) so that we store it internally as a JS object, as opposed to a string. The end result is that JSON.stringifying state doesn't result in the use of escape characters for that formdata and we no longer have an explosion of backslashes to make sessionstore.js as huge.
This commit is contained in:
parent
0eecf4510d
commit
6afa2f58ba
@ -359,7 +359,7 @@ SessionStoreService.prototype = {
|
||||
// replace the crashed session with a restore-page-only session
|
||||
let pageData = {
|
||||
url: "about:sessionrestore",
|
||||
formdata: { "#sessionData": JSON.stringify(this._initialState) }
|
||||
formdata: { "#sessionData": this._initialState }
|
||||
};
|
||||
this._initialState = { windows: [{ tabs: [{ entries: [pageData] }] }] };
|
||||
}
|
||||
@ -2140,10 +2140,17 @@ SessionStoreService.prototype = {
|
||||
}
|
||||
var isHTTPS = this._getURIFromString((aContent.parent || aContent).
|
||||
document.location.href).schemeIs("https");
|
||||
if (aFullData || this._checkPrivacyLevel(isHTTPS, aIsPinned) ||
|
||||
aContent.top.document.location.href == "about:sessionrestore") {
|
||||
let isAboutSR = aContent.top.document.location.href == "about:sessionrestore";
|
||||
if (aFullData || this._checkPrivacyLevel(isHTTPS, aIsPinned) || isAboutSR) {
|
||||
if (aFullData || aUpdateFormData) {
|
||||
let formData = this._collectFormDataForFrame(aContent.document);
|
||||
|
||||
// We want to avoid saving data for about:sessionrestore as a string.
|
||||
// Since it's stored in the form as stringified JSON, stringifying further
|
||||
// causes an explosion of escape characters. cf. bug 467409
|
||||
if (formData && isAboutSR)
|
||||
formData["#sessionData"] = JSON.parse(formData["#sessionData"]);
|
||||
|
||||
if (formData)
|
||||
aData.formdata = formData;
|
||||
else if (aData.formdata)
|
||||
@ -3380,6 +3387,13 @@ SessionStoreService.prototype = {
|
||||
|
||||
let eventType;
|
||||
let value = aData[key];
|
||||
|
||||
// for about:sessionrestore we saved the field as JSON to avoid nested
|
||||
// instances causing humongous sessionstore.js files. cf. bug 467409
|
||||
if (aURL == "about:sessionrestore" && typeof value == "object") {
|
||||
value = JSON.stringify(value);
|
||||
}
|
||||
|
||||
if (typeof value == "string" && node.type != "file") {
|
||||
if (node.value == value)
|
||||
continue; // don't dispatch an input event for no change
|
||||
|
@ -100,6 +100,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_465223.js \
|
||||
browser_466937.js \
|
||||
browser_466937_sample.html \
|
||||
browser_467409-backslashplosion.js \
|
||||
browser_477657.js \
|
||||
browser_480148.js \
|
||||
browser_480893.js \
|
||||
|
@ -0,0 +1,90 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test Summary:
|
||||
// 1. Open about:sessionrestore via setBrowserState where formdata is a JS object, not a string
|
||||
// 1a. Check that #sessionData on the page is readable after JSON.parse (skipped, checking formdata is sufficient)
|
||||
// 1b. Check that there are no backslashes in the formdata
|
||||
// 1c. Check that formdata (via getBrowserState) doesn't require JSON.parse
|
||||
//
|
||||
// 2. Use the current state (currently about:sessionrestore with data) and then open than in a new instance of about:sessionrestore
|
||||
// 2a. Check that there are no backslashes in the formdata
|
||||
// 2b. Check that formdata (via getBrowserState) doesn't require JSON.parse
|
||||
//
|
||||
// 3. [backwards compat] Use a stringified state as formdata when opening about:sessionrestore
|
||||
// 3a. Make sure there are nodes in the tree on about:sessionrestore (skipped, checking formdata is sufficient)
|
||||
// 3b. Check that there are no backslashes in the formdata
|
||||
// 3c. Check that formdata (via getBrowserState) doesn't require JSON.parse
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
|
||||
let crashState = { windows: [{ tabs: [{ entries: [{ url: "about:mozilla" }] }]}]};
|
||||
|
||||
let pagedata = { url: "about:sessionrestore",
|
||||
formdata: { "#sessionData": crashState } };
|
||||
let state = { windows: [{ tabs: [{ entries: [pagedata] }] }] };
|
||||
|
||||
// test1 calls test2 calls test3 calls finish
|
||||
test1(state);
|
||||
|
||||
|
||||
function test1(aState) {
|
||||
waitForBrowserState(aState, function() {
|
||||
checkState("test1", test2);
|
||||
});
|
||||
}
|
||||
|
||||
function test2(aState) {
|
||||
let pagedata2 = { url: "about:sessionrestore",
|
||||
formdata: { "#sessionData": aState } };
|
||||
let state2 = { windows: [{ tabs: [{ entries: [pagedata2] }] }] };
|
||||
|
||||
waitForBrowserState(state2, function() {
|
||||
checkState("test2", test3);
|
||||
});
|
||||
}
|
||||
|
||||
function test3(aState) {
|
||||
let pagedata3 = { url: "about:sessionrestore",
|
||||
formdata: { "#sessionData": JSON.stringify(crashState) } };
|
||||
let state3 = { windows: [{ tabs: [{ entries: [pagedata3] }] }] };
|
||||
waitForBrowserState(state3, function() {
|
||||
// In theory we should do inspection of the treeview on about:sessionrestore,
|
||||
// but we don't actually need to. If we fail tests in checkState then
|
||||
// about:sessionrestore won't be able to turn the form value into a usable page.
|
||||
checkState("test3", function() waitForBrowserState(blankState, finish));
|
||||
});
|
||||
}
|
||||
|
||||
function checkState(testName, callback) {
|
||||
let curState = JSON.parse(ss.getBrowserState());
|
||||
let formdata = curState.windows[0].tabs[0].entries[0].formdata;
|
||||
|
||||
ok(formdata["#sessionData"], testName + ": we have form data for about:sessionrestore");
|
||||
|
||||
let sessionData_raw = JSON.stringify(formdata["#sessionData"]);
|
||||
ok(!/\\/.test(sessionData_raw), testName + ": #sessionData contains no backslashes");
|
||||
info(sessionData_raw);
|
||||
|
||||
let gotError = false;
|
||||
try {
|
||||
JSON.parse(formdata["#sessionData"]);
|
||||
}
|
||||
catch (e) {
|
||||
info(testName + ": got error: " + e);
|
||||
gotError = true;
|
||||
}
|
||||
ok(gotError, testName + ": attempting to JSON.parse form data threw error");
|
||||
|
||||
// Panorama sticks JSON into extData, which we stringify causing the
|
||||
// naive backslash check to fail. extData doesn't matter in the grand
|
||||
// scheme here, so we'll delete the extData so doesn't end up in future states.
|
||||
delete curState.windows[0].extData;
|
||||
delete curState.windows[0].tabs[0].extData;
|
||||
callback(curState);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ function test() {
|
||||
};
|
||||
let pageData = {
|
||||
url: "about:sessionrestore",
|
||||
formdata: { "#sessionData": "(" + JSON.stringify(oldState) + ")" }
|
||||
formdata: { "#sessionData": oldState }
|
||||
};
|
||||
let state = { windows: [{ tabs: [{ entries: [pageData] }] }] };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user