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
|
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Ensures that pasting unsafe protocols in the urlbar have the protocol
* correctly stripped.
*/
var pairs = [
["javascript:", ""],
["javascript:1+1", "1+1"],
["javascript:document.domain", "document.domain"],
[
" \u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009javascript:document.domain",
"document.domain",
],
["java\nscript:foo", "foo"],
["java\tscript:foo", "foo"],
["http://\nexample.com", "http://example.com"],
["http://\nexample.com\n", "http://example.com"],
["data:text/html,<body>hi</body>", "data:text/html,<body>hi</body>"],
["javaScript:foopy", "foopy"],
["javaScript:javaScript:alert('hi')", "alert('hi')"],
// Nested things get confusing because some things don't parse as URIs:
["javascript:javascript:alert('hi!')", "alert('hi!')"],
[
"data:data:text/html,<body>hi</body>",
"data:data:text/html,<body>hi</body>",
],
["javascript:data:javascript:alert('hi!')", "data:javascript:alert('hi!')"],
[
"javascript:data:text/html,javascript:alert('hi!')",
"data:text/html,javascript:alert('hi!')",
],
[
"data:data:text/html,javascript:alert('hi!')",
"data:data:text/html,javascript:alert('hi!')",
],
];
let supportsNullBytes = AppConstants.platform == "macosx";
// Note that \u000d (\r) is missing here; we test it separately because it
// makes the test sad on Windows.
let nonsense =
"\u000a\u000b\u000c\u000e\u000f\u0010\u0011\u0012\u0013\u0014javascript:foo";
if (supportsNullBytes) {
nonsense = "\u0000" + nonsense;
}
pairs.push([nonsense, "foo"]);
let supportsReturnWithoutNewline =
AppConstants.platform != "win" && AppConstants.platform != "linux";
if (supportsReturnWithoutNewline) {
pairs.push(["java\rscript:foo", "foo"]);
}
async function paste(input) {
try {
await SimpleTest.promiseClipboardChange(
aData => {
// This test checks how "\r" is treated. Therefore, we cannot specify
// string here and instead, we need to compare strictly with this
// function.
return aData === input;
},
() => {
clipboardHelper.copyString(input);
}
);
} catch (ex) {
Assert.ok(false, "Failed to copy string '" + input + "' to clipboard");
}
document.commandDispatcher
.getControllerForCommand("cmd_paste")
.doCommand("cmd_paste");
}
add_task(async function test_stripUnsafeProtocolPaste() {
for (let [inputValue, expectedURL] of pairs) {
gURLBar.value = "";
gURLBar.focus();
await paste(inputValue);
Assert.equal(
gURLBar.value,
expectedURL,
`entering ${inputValue} strips relevant bits.`
);
await new Promise(resolve => setTimeout(resolve, 0));
}
});
|