1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/test/unit/test_bug558431.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,163 @@ 1.4 + 1.5 +const Cc = Components.classes; 1.6 +const Ci = Components.interfaces; 1.7 +const Cu = Components.utils; 1.8 +const Cr = Components.results; 1.9 + 1.10 +Cu.import('resource://gre/modules/CSPUtils.jsm'); 1.11 + 1.12 +var httpserv = null; 1.13 + 1.14 +const POLICY_FROM_URI = "allow 'self'; img-src *"; 1.15 +const POLICY_PORT = 9000; 1.16 +const POLICY_URI = "http://localhost:" + POLICY_PORT + "/policy"; 1.17 +const POLICY_URI_RELATIVE = "/policy"; 1.18 +const DOCUMENT_URI = "http://localhost:" + POLICY_PORT + "/document"; 1.19 +const CSP_DOC_BODY = "CSP doc content"; 1.20 +const SD = CSPRep.SRC_DIRECTIVES; 1.21 + 1.22 +// this will get populated by run_tests() 1.23 +var TESTS = []; 1.24 + 1.25 +// helper to make URIs 1.26 +function mkuri(foo) { 1.27 + return Cc["@mozilla.org/network/io-service;1"] 1.28 + .getService(Ci.nsIIOService) 1.29 + .newURI(foo, null, null); 1.30 +} 1.31 + 1.32 +// helper to use .equals on stuff 1.33 +function do_check_equivalent(foo, bar, stack) { 1.34 + if (!stack) 1.35 + stack = Components.stack.caller; 1.36 + 1.37 + var text = foo + ".equals(" + bar + ")"; 1.38 + 1.39 + if (foo.equals && foo.equals(bar)) { 1.40 + dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " + 1.41 + stack.lineNumber + "] " + text + "\n"); 1.42 + return; 1.43 + } 1.44 + do_throw(text, stack); 1.45 +} 1.46 + 1.47 +function listener(csp, cspr_static) { 1.48 + this.buffer = ""; 1.49 + this._csp = csp; 1.50 + this._cspr_static = cspr_static; 1.51 +} 1.52 + 1.53 +listener.prototype = { 1.54 + onStartRequest: function (request, ctx) { 1.55 + }, 1.56 + 1.57 + onDataAvailable: function (request, ctx, stream, offset, count) { 1.58 + var sInputStream = Cc["@mozilla.org/scriptableinputstream;1"] 1.59 + .createInstance(Ci.nsIScriptableInputStream); 1.60 + sInputStream.init(stream); 1.61 + this.buffer = this.buffer.concat(sInputStream.read(count)); 1.62 + }, 1.63 + 1.64 + onStopRequest: function (request, ctx, status) { 1.65 + // make sure that we have the full document content, guaranteeing that 1.66 + // the document channel has been resumed, before we do the comparisons 1.67 + if (this.buffer == CSP_DOC_BODY) { 1.68 + 1.69 + // need to re-grab cspr since it may have changed inside the document's 1.70 + // nsIContentSecurityPolicy instance. The problem is, this cspr_str is a 1.71 + // string and not a policy due to the way it's exposed from 1.72 + // nsIContentSecurityPolicy, so we have to re-parse it. 1.73 + let cspr_str = this._csp.getPolicy(0); 1.74 + let cspr = CSPRep.fromString(cspr_str, mkuri(DOCUMENT_URI)); 1.75 + 1.76 + // and in reparsing it, we lose the 'self' relationships, so need to also 1.77 + // reparse the static one (or find a way to resolve 'self' in the parsed 1.78 + // policy when doing comparisons). 1.79 + let cspr_static_str = this._cspr_static.toString(); 1.80 + let cspr_static_reparse = CSPRep.fromString(cspr_static_str, mkuri(DOCUMENT_URI)); 1.81 + 1.82 + // not null, and one policy .equals the other one 1.83 + do_check_neq(null, cspr); 1.84 + do_check_true(cspr.equals(cspr_static_reparse)); 1.85 + 1.86 + // final teardown 1.87 + if (TESTS.length == 0) { 1.88 + httpserv.stop(do_test_finished); 1.89 + } else { 1.90 + do_test_finished(); 1.91 + (TESTS.shift())(); 1.92 + } 1.93 + } 1.94 + } 1.95 +}; 1.96 + 1.97 +function run_test() { 1.98 + httpserv = new HttpServer(); 1.99 + httpserv.registerPathHandler("/document", csp_doc_response); 1.100 + httpserv.registerPathHandler("/policy", csp_policy_response); 1.101 + httpserv.start(POLICY_PORT); 1.102 + TESTS = [ test_CSPRep_fromPolicyURI, test_CSPRep_fromRelativePolicyURI ]; 1.103 + 1.104 + // when this triggers the "onStopRequest" callback, it'll 1.105 + // go to the next test. 1.106 + (TESTS.shift())(); 1.107 +} 1.108 + 1.109 +function makeChan(url) { 1.110 + var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); 1.111 + var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel); 1.112 + return chan; 1.113 +} 1.114 + 1.115 +function csp_doc_response(metadata, response) { 1.116 + response.setStatusLine(metadata.httpVersion, 200, "OK"); 1.117 + response.setHeader("Content-Type", "text/html", false); 1.118 + response.bodyOutputStream.write(CSP_DOC_BODY, CSP_DOC_BODY.length); 1.119 +} 1.120 + 1.121 +function csp_policy_response(metadata, response) { 1.122 + response.setStatusLine(metadata.httpVersion, 200, "OK"); 1.123 + response.setHeader("Content-Type", "text/csp", false); 1.124 + response.bodyOutputStream.write(POLICY_FROM_URI, POLICY_FROM_URI.length); 1.125 +} 1.126 + 1.127 +///////////////////// TEST POLICY_URI ////////////////////// 1.128 +function test_CSPRep_fromPolicyURI() { 1.129 + do_test_pending(); 1.130 + let csp = Cc["@mozilla.org/contentsecuritypolicy;1"] 1.131 + .createInstance(Ci.nsIContentSecurityPolicy); 1.132 + // once the policy-uri is returned we will compare our static CSPRep with one 1.133 + // we generated from the content we got back from the network to make sure 1.134 + // they are equivalent 1.135 + let cspr_static = CSPRep.fromString(POLICY_FROM_URI, mkuri(DOCUMENT_URI)); 1.136 + 1.137 + // simulates the request for the parent document 1.138 + var docChan = makeChan(DOCUMENT_URI); 1.139 + docChan.asyncOpen(new listener(csp, cspr_static), null); 1.140 + 1.141 + // the resulting policy here can be discarded, since it's going to be 1.142 + // "allow *"; when the policy-uri fetching call-back happens, the *real* 1.143 + // policy will be in csp.policy 1.144 + CSPRep.fromString("policy-uri " + POLICY_URI, 1.145 + mkuri(DOCUMENT_URI), false, docChan, csp); 1.146 +} 1.147 + 1.148 +function test_CSPRep_fromRelativePolicyURI() { 1.149 + do_test_pending(); 1.150 + let csp = Cc["@mozilla.org/contentsecuritypolicy;1"] 1.151 + .createInstance(Ci.nsIContentSecurityPolicy); 1.152 + // once the policy-uri is returned we will compare our static CSPRep with one 1.153 + // we generated from the content we got back from the network to make sure 1.154 + // they are equivalent 1.155 + let cspr_static = CSPRep.fromString(POLICY_FROM_URI, mkuri(DOCUMENT_URI)); 1.156 + 1.157 + // simulates the request for the parent document 1.158 + var docChan = makeChan(DOCUMENT_URI); 1.159 + docChan.asyncOpen(new listener(csp, cspr_static), null); 1.160 + 1.161 + // the resulting policy here can be discarded, since it's going to be 1.162 + // "allow *"; when the policy-uri fetching call-back happens, the *real* 1.163 + // policy will be in csp.policy 1.164 + CSPRep.fromString("policy-uri " + POLICY_URI_RELATIVE, 1.165 + mkuri(DOCUMENT_URI), false, docChan, csp); 1.166 +}