michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: // Test Summary: michael@0: // 1. Open about:sessionrestore where formdata is a JS object, not a string michael@0: // 1a. Check that #sessionData on the page is readable after JSON.parse (skipped, checking formdata is sufficient) michael@0: // 1b. Check that there are no backslashes in the formdata michael@0: // 1c. Check that formdata doesn't require JSON.parse michael@0: // michael@0: // 2. Use the current state (currently about:sessionrestore with data) and then open that in a new instance of about:sessionrestore michael@0: // 2a. Check that there are no backslashes in the formdata michael@0: // 2b. Check that formdata doesn't require JSON.parse michael@0: // michael@0: // 3. [backwards compat] Use a stringified state as formdata when opening about:sessionrestore michael@0: // 3a. Make sure there are nodes in the tree on about:sessionrestore (skipped, checking formdata is sufficient) michael@0: // 3b. Check that there are no backslashes in the formdata michael@0: // 3c. Check that formdata doesn't require JSON.parse michael@0: michael@0: const CRASH_STATE = {windows: [{tabs: [{entries: [{url: "about:mozilla" }]}]}]}; michael@0: const STATE = {entries: [createEntry(CRASH_STATE)]}; michael@0: const STATE2 = {entries: [createEntry({windows: [{tabs: [STATE]}]})]}; michael@0: const STATE3 = {entries: [createEntry(JSON.stringify(CRASH_STATE))]}; michael@0: michael@0: function createEntry(sessionData) { michael@0: return { michael@0: url: "about:sessionrestore", michael@0: formdata: {id: {sessionData: sessionData}} michael@0: }; michael@0: } michael@0: michael@0: add_task(function test_nested_about_sessionrestore() { michael@0: // Prepare a blank tab. michael@0: let tab = gBrowser.addTab("about:blank"); michael@0: let browser = tab.linkedBrowser; michael@0: yield promiseBrowserLoaded(browser); michael@0: michael@0: // test 1 michael@0: ss.setTabState(tab, JSON.stringify(STATE)); michael@0: yield promiseTabRestored(tab); michael@0: checkState("test1", tab); michael@0: michael@0: // test 2 michael@0: ss.setTabState(tab, JSON.stringify(STATE2)); michael@0: yield promiseTabRestored(tab); michael@0: checkState("test2", tab); michael@0: michael@0: // test 3 michael@0: ss.setTabState(tab, JSON.stringify(STATE3)); michael@0: yield promiseTabRestored(tab); michael@0: checkState("test3", tab); michael@0: michael@0: // Cleanup. michael@0: gBrowser.removeTab(tab); michael@0: }); michael@0: michael@0: function checkState(prefix, tab) { michael@0: // Flush and query tab state. michael@0: SyncHandlers.get(tab.linkedBrowser).flush(); michael@0: let {formdata} = JSON.parse(ss.getTabState(tab)); michael@0: michael@0: ok(formdata.id["sessionData"], prefix + ": we have form data for about:sessionrestore"); michael@0: michael@0: let sessionData_raw = JSON.stringify(formdata.id["sessionData"]); michael@0: ok(!/\\/.test(sessionData_raw), prefix + ": #sessionData contains no backslashes"); michael@0: info(sessionData_raw); michael@0: michael@0: let gotError = false; michael@0: try { michael@0: JSON.parse(formdata.id["sessionData"]); michael@0: } catch (e) { michael@0: info(prefix + ": got error: " + e); michael@0: gotError = true; michael@0: } michael@0: ok(gotError, prefix + ": attempting to JSON.parse form data threw error"); michael@0: }