test_bug337744.js (3606B)
1 /* verify that certain invalid URIs are not parsed by the resource 2 protocol handler */ 3 4 "use strict"; 5 6 const specs = [ 7 "resource://res-test//", 8 "resource://res-test/?foo=http:", 9 "resource://res-test/?foo=" + encodeURIComponent("http://example.com/"), 10 "resource://res-test/?foo=" + encodeURIComponent("x\\y"), 11 "resource://res-test/..%2F", 12 "resource://res-test/..%2f", 13 "resource://res-test/..%2F..", 14 "resource://res-test/..%2f..", 15 "resource://res-test/../../", 16 "resource://res-test/http://www.mozilla.org/", 17 "resource://res-test/file:///", 18 ]; 19 20 const error_specs = [ 21 "resource://res-test/..\\", 22 "resource://res-test/..\\..\\", 23 "resource://res-test/..%5C", 24 "resource://res-test/..%5c", 25 ]; 26 27 // Create some fake principal that has not enough 28 // privileges to access any resource: uri. 29 var uri = NetUtil.newURI("http://www.example.com"); 30 var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {}); 31 32 function get_channel(spec) { 33 var channel = NetUtil.newChannel({ 34 uri: NetUtil.newURI(spec), 35 loadingPrincipal: principal, 36 securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, 37 contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER, 38 }); 39 40 Assert.throws( 41 () => { 42 channel.asyncOpen(null); 43 }, 44 /NS_ERROR_DOM_BAD_URI/, 45 `asyncOpen() of uri: ${spec} should throw` 46 ); 47 Assert.throws( 48 () => { 49 channel.open(); 50 }, 51 /NS_ERROR_DOM_BAD_URI/, 52 `Open() of uri: ${spec} should throw` 53 ); 54 55 return channel; 56 } 57 58 function check_safe_resolution(spec, rootURI) { 59 info(`Testing URL "${spec}"`); 60 61 let channel = get_channel(spec); 62 63 ok( 64 channel.name.startsWith(rootURI), 65 `URL resolved safely to ${channel.name}` 66 ); 67 let startOfQuery = channel.name.indexOf("?"); 68 if (startOfQuery == -1) { 69 ok(!/%2f/i.test(channel.name), `URL contains no escaped / characters`); 70 } else { 71 // Escaped slashes are allowed in the query or hash part of the URL 72 ok( 73 !channel.name.replace(/\?.*/, "").includes("%2f"), 74 `URL contains no escaped slashes before the query ${channel.name}` 75 ); 76 } 77 } 78 79 function check_resolution_error(spec) { 80 Assert.throws( 81 () => { 82 get_channel(spec); 83 }, 84 /NS_ERROR_MALFORMED_URI/, 85 "Expected a malformed URI error" 86 ); 87 } 88 89 function run_test() { 90 // resource:/// and resource://gre/ are resolved specially, so we need 91 // to create a temporary resource package to test the standard logic 92 // with. 93 94 let resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService( 95 Ci.nsIResProtocolHandler 96 ); 97 let rootFile = Services.dirsvc.get("GreD", Ci.nsIFile); 98 let rootURI = Services.io.newFileURI(rootFile); 99 100 rootFile.append("directory-that-does-not-exist"); 101 let inexistentURI = Services.io.newFileURI(rootFile); 102 103 resProto.setSubstitution("res-test", rootURI); 104 resProto.setSubstitution("res-inexistent", inexistentURI); 105 registerCleanupFunction(() => { 106 resProto.setSubstitution("res-test", null); 107 resProto.setSubstitution("res-inexistent", null); 108 }); 109 110 let baseRoot = resProto.resolveURI(Services.io.newURI("resource:///")); 111 let greRoot = resProto.resolveURI(Services.io.newURI("resource://gre/")); 112 113 for (let spec of specs) { 114 check_safe_resolution(spec, rootURI.spec); 115 check_safe_resolution( 116 spec.replace("res-test", "res-inexistent"), 117 inexistentURI.spec 118 ); 119 check_safe_resolution(spec.replace("res-test", ""), baseRoot); 120 check_safe_resolution(spec.replace("res-test", "gre"), greRoot); 121 } 122 123 for (let spec of error_specs) { 124 check_resolution_error(spec); 125 } 126 }