@@ -2,14 +2,135 @@ const PATH =
22 "http://example.com/browser/dom/tests/mochitest/ajax/offline/" ;
33const URL = PATH + "file_simpleManifest.html" ;
44const MANIFEST = PATH + "file_simpleManifest.cacheManifest" ;
5+ const PREF_INSECURE_APPCACHE = "browser.cache.offline.insecure.enable" ;
56const PREF_NETWORK_PROXY = "network.proxy.type" ;
67
8+ function setSJSState ( sjsPath , stateQuery ) {
9+ let client = new XMLHttpRequest ( ) ;
10+ client . open ( "GET" , sjsPath + "?state=" + stateQuery , false ) ;
11+ let appcachechannel = SpecialPowers . wrap ( client ) . channel . QueryInterface ( Ci . nsIApplicationCacheChannel ) ;
12+
13+ return new Promise ( ( resolve , reject ) => {
14+ client . addEventListener ( "load" , resolve ) ;
15+ client . addEventListener ( "error" , reject ) ;
16+
17+ appcachechannel . chooseApplicationCache = false ;
18+ appcachechannel . inheritApplicationCache = false ;
19+ appcachechannel . applicationCache = null ;
20+
21+ client . send ( ) ;
22+ } ) ;
23+ }
24+
25+ add_task ( async function ( ) {
26+ /* This test loads "evil" content and verified it isn't loaded when appcache is disabled, which emulates loading stale cache from an untrusted network:
27+ - Sets frame to load "evil" content
28+ - Loads HTML file which also loads and caches content into AppCache
29+ - Sets frame to load "good"
30+ - Check we still have "evil" content from AppCache
31+ - Disables appcache
32+ - Check content is "good"
33+ */
34+ await SpecialPowers . pushPrefEnv ( {
35+ set : [
36+ [ PREF_INSECURE_APPCACHE , true ]
37+ ]
38+ } ) ;
39+ await setSJSState ( PATH + "file_testFile.sjs" , "evil" ) ;
40+ await BrowserTestUtils . openNewForegroundTab ( gBrowser , URL ) ;
41+ await ContentTask . spawn ( gBrowser . selectedBrowser , null , async ( ) => {
42+ let windowPromise = new Promise ( ( resolve , reject ) => {
43+ function init ( ) {
44+ if ( content . document . readyState == "complete" ) {
45+ const frame = content . document . getElementById ( "childframe" ) ;
46+ const state = frame . contentDocument . getElementById ( "state" ) ;
47+ is ( state . textContent , "evil" , "Loaded evil content" ) ;
48+ resolve ( ) ;
49+ }
50+ }
51+ content . document . onreadystatechange = init ;
52+ init ( ) ;
53+ } ) ;
54+ let appcachePromise = new Promise ( ( resolve , reject ) => {
55+ function appcacheInit ( ) {
56+ if ( content . applicationCache . status === content . applicationCache . IDLE ) {
57+ ok ( true , "Application cache loaded" ) ;
58+ resolve ( ) ;
59+ } else {
60+ info ( "State was: " + content . applicationCache . status ) ;
61+ }
62+ }
63+ content . applicationCache . oncached = appcacheInit ;
64+ content . applicationCache . onnoupdate = appcacheInit ;
65+ content . applicationCache . onerror = ( ) => {
66+ ok ( false , "Application cache failed" ) ;
67+ reject ( ) ;
68+ } ;
69+ appcacheInit ( ) ;
70+ } ) ;
71+ await Promise . all ( [ windowPromise , appcachePromise ] ) ;
72+ } ) ;
73+ gBrowser . removeCurrentTab ( ) ;
74+
75+ // Turn network and proxy off so we can check the content loads still
76+ await setSJSState ( PATH + "file_testFile.sjs" , "good" ) ;
77+ Services . cache2 . clear ( ) ;
78+
79+ // Check we still have the "evil" content despite the state change
80+ await BrowserTestUtils . openNewForegroundTab ( gBrowser , URL ) ;
81+ await ContentTask . spawn ( gBrowser . selectedBrowser , null , async ( ) => {
82+ const frame = content . document . getElementById ( "childframe" ) ;
83+ const state = frame . contentDocument . getElementById ( "state" ) ;
84+ is ( state . textContent , "evil" , "Loaded evil content from cache" ) ;
85+ } ) ;
86+ gBrowser . removeCurrentTab ( ) ;
87+
88+
89+ await SpecialPowers . pushPrefEnv ( {
90+ set : [
91+ [ PREF_INSECURE_APPCACHE , false ]
92+ ]
93+ } ) ;
94+ await BrowserTestUtils . openNewForegroundTab ( gBrowser , URL ) ;
95+
96+ // Check that the "good" content is back now appcache is disabled
97+ await ContentTask . spawn ( gBrowser . selectedBrowser , [ URL ] , async ( URL ) => {
98+ const frame = content . document . getElementById ( "childframe" ) ;
99+ const state = frame . contentDocument . getElementById ( "state" ) ;
100+ is ( state . textContent , "good" , "Loaded good content" ) ;
101+ // Eval is needed to execure in child context.
102+ content . window . eval ( "OfflineTest.clear()" ) ;
103+ } ) ;
104+
105+ gBrowser . removeCurrentTab ( ) ;
106+ await setSJSState ( PATH + "file_testFile.sjs" , "" ) ;
107+ await SpecialPowers . popPrefEnv ( ) ;
108+ } ) ;
109+
7110add_task ( async function test_pref_removes_api ( ) {
111+ await SpecialPowers . pushPrefEnv ( {
112+ set : [
113+ [ PREF_INSECURE_APPCACHE , true ]
114+ ]
115+ } ) ;
8116 await BrowserTestUtils . openNewForegroundTab ( gBrowser , URL ) ;
9117 await ContentTask . spawn ( gBrowser . selectedBrowser , null , async ( ) => {
10118 // Have to use in page checking as IsSecureContextOrObjectIsFromSecureContext is true for spawn()
11119 is ( content . document . getElementById ( "hasAppcache" ) . textContent , "yes" , "Appcache is enabled" ) ;
12120 is ( content . document . getElementById ( "hasOfflineResourceList" ) . textContent , "yes" , "OfflineResourceList is enabled" ) ;
13121 } ) ;
14122 gBrowser . removeCurrentTab ( ) ;
123+
124+ await SpecialPowers . pushPrefEnv ( {
125+ set : [
126+ [ PREF_INSECURE_APPCACHE , false ]
127+ ]
128+ } ) ;
129+ await BrowserTestUtils . openNewForegroundTab ( gBrowser , URL ) ;
130+ await ContentTask . spawn ( gBrowser . selectedBrowser , [ URL ] , async ( URL ) => {
131+ is ( content . document . getElementById ( "hasAppcache" ) . textContent , "no" , "Appcache is disabled" ) ;
132+ is ( content . document . getElementById ( "hasOfflineResourceList" ) . textContent , "no" , "OfflineResourceList is disabled" ) ;
133+ content . window . eval ( "OfflineTest.clear()" ) ;
134+ } ) ;
135+ gBrowser . removeCurrentTab ( ) ;
15136} ) ;
0 commit comments