1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/LoginManagerParent.jsm", this);
function* registerConverter() {
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/NetUtil.jsm", this);
/**
* Converts the "test/content" MIME type, served by the test over HTTP, to an
* HTML viewer page containing the "form_basic.html" code. The viewer is
* served from a "resource:" URI while keeping the "resource:" principal.
*/
function TestStreamConverter() {}
TestStreamConverter.prototype = {
classID: Components.ID("{5f01d6ef-c090-45a4-b3e5-940d64713eb7}"),
contractID: "@mozilla.org/streamconv;1?from=test/content&to=*/*",
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIRequestObserver,
Ci.nsIStreamListener,
Ci.nsIStreamConverter,
]),
// nsIStreamConverter
convert() {},
// nsIStreamConverter
asyncConvertData(aFromType, aToType, aListener, aCtxt) {
this.listener = aListener;
},
// nsIRequestObserver
onStartRequest(aRequest, aContext) {
let channel = NetUtil.newChannel({
uri: "resource://testing-common/form_basic.html",
loadUsingSystemPrincipal: true,
});
channel.originalURI = aRequest.QueryInterface(Ci.nsIChannel).URI;
channel.loadGroup = aRequest.loadGroup;
channel.owner = Services.scriptSecurityManager
.createCodebasePrincipal(channel.URI, {});
// In this test, we pass the new channel to the listener but don't fire a
// redirect notification, even if it would be required. This keeps the
// test code simpler and doesn't impact the principal check we're testing.
channel.asyncOpen2(this.listener);
},
// nsIRequestObserver
onStopRequest() {},
// nsIStreamListener
onDataAvailable() {},
};
let factory = XPCOMUtils._getFactory(TestStreamConverter);
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
registrar.registerFactory(TestStreamConverter.prototype.classID, "",
TestStreamConverter.prototype.contractID, factory);
this.cleanupFunction = function () {
registrar.unregisterFactory(TestStreamConverter.prototype.classID, factory);
};
}
/**
* Waits for the given number of occurrences of InsecureLoginFormsStateChange
* on the given browser element.
*/
function waitForInsecureLoginFormsStateChange(browser, count) {
return BrowserTestUtils.waitForEvent(browser, "InsecureLoginFormsStateChange",
false, () => --count == 0);
}
/**
* Checks that hasInsecureLoginForms is false for a viewer served internally
* using a "resource:" URI.
*/
add_task(function* test_streamConverter() {
let originalBrowser = gBrowser.selectedTab.linkedBrowser;
yield ContentTask.spawn(originalBrowser, null, registerConverter);
let tab = gBrowser.addTab("http://example.com/browser/toolkit/components/" +
"passwordmgr/test/browser/streamConverter_content.sjs",
{ relatedBrowser: originalBrowser.linkedBrowser });
let browser = tab.linkedBrowser;
yield Promise.all([
BrowserTestUtils.switchTab(gBrowser, tab),
BrowserTestUtils.browserLoaded(browser),
// One event is triggered by pageshow and one by DOMFormHasPassword.
waitForInsecureLoginFormsStateChange(browser, 2),
]);
Assert.ok(!LoginManagerParent.hasInsecureLoginForms(browser));
yield BrowserTestUtils.removeTab(tab);
yield ContentTask.spawn(originalBrowser, null, function* () {
this.cleanupFunction();
});
});
|