-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathflow.js
More file actions
168 lines (118 loc) · 4.81 KB
/
flow.js
File metadata and controls
168 lines (118 loc) · 4.81 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
(async function () {
var source = "source";
var p1 = Promise.resolve(source);
sink(await p1); // NOT OK
var p2 = new Promise((resolve, reject) => resolve(source));
sink(await p2); // NOT OK
var p3 = new Promise((resolve, reject) => reject(source));
sink(await p3); // OK!
var p4 = new Promise((resolve, reject) => reject(source));
try {
var foo = await p4;
} catch (e) {
sink(e); // NOT OK!
}
Promise.resolve(source).then(x => sink(x)); // NOT OK!
Promise.resolve(source).then(x => foo(x), y => sink(y)); // OK!
new Promise((resolve, reject) => reject(source)).then(x => sink(x)); // OK!
new Promise((resolve, reject) => reject(source)).then(x => foo(x), y => sink(y)); // NOT OK!
Promise.resolve("foo").then(x => source).then(z => sink(z)); // NOT OK!
Promise.resolve(source).then(x => "foo").then(z => sink(z)); // OK!
new Promise((resolve, reject) => reject(source)).catch(x => sink(x)); // NOT OK!
Promise.resolve(source).catch(() => { }).then(a => sink(a)); // NOT OK!
var p5 = Promise.resolve(source);
var p6 = p5.catch(() => { });
var p7 = p6.then(a => sink(a)); // NOT OK!
new Promise((resolve, reject) => reject(source)).then(() => { }).catch(x => sink(x)); // NOT OK!
new Promise((resolve, reject) => reject(source)).then(() => { }, () => { }).catch(x => sink(x)); // OK!
Promise.resolve(source).catch(() => { }).catch(() => { }).catch(() => { }).then(a => sink(a)); // NOT OK!
Promise.resolve(source).finally(() => { }).then(a => sink(a)); // NOT OK!
new Promise(() => { throw source }).catch(x => sink(x)); // NOT OK!
function createPromise(src) {
return Promise.resolve(src);
}
createPromise(source).then(v => sink(v)); // NOT OK!
var p8 = new Promise((resolve, reject) => reject(source));
var p9 = p8.then(() => {});
var p10 = p9.finally(() => {});
p10.catch((x) => sink(x)); // NOT OK!
var p11 = new Promise((resolve, reject) => reject(source));
var p12 = p11.then(() => {});
p12.catch(x => sink(x)); // NOT OK!
async function throws() {
await new Promise((resolve, reject) => reject(source));
}
try {
await throws();
} catch(e) {
sink(e); // NOT OK!
}
function chainedPromise() {
return new Promise((resolve, reject) => reject(source)).then(() => {});
}
chainedPromise().then(() => {}).catch(e => sink(e)); // NOT OK!
function leaksResolvedPromise(p) {
p.then(x => sink(x)); // NOT OK!
}
leaksResolvedPromise(Promise.resolve(source));
function leaksRejectedPromise(p) {
p.catch(e => sink(e)); // NOT OK!
}
leaksRejectedPromise(new Promise((resolve, reject) => reject(source)));
function leaksRejectedAgain(p) {
("foo", p).then(() => {}).catch(e => sink(e)); // NOT OK!
}
leaksRejectedAgain(new Promise((resolve, reject) => reject(source)).then(() => {}));
async function returnsRejected(p) {
try {
await p;
} catch(e) {
return e;
}
}
var foo = await returnsRejected(new Promise((resolve, reject) => reject(source)));
sink(foo); // NOT OK!
new Promise((resolve, reject) => reject("BLA")).catch(x => {return source}).then(x => sink(x)); // NOT OK
new Promise((resolve, reject) => reject("BLA")).finally(x => {throw source}).catch(x => sink(x)); // NOT OK
var rejected = new Promise((resolve, reject) => reject(source));
new Promise((resolve, reject) => reject("BLA")).finally(x => rejected).catch(x => sink(x)); // NOT OK
new Promise((resolve, reject) => reject("BLA")).catch(x => rejected).then(x => sink(x)) // OK
new Promise((resolve, reject) => reject("BLA")).catch(x => rejected).catch(x => sink(x)) // NOT OK
var resolved = Promise.resolve(source);
new Promise((resolve, reject) => reject("BLA")).catch(x => resolved).catch(x => sink(x)) // OK
new Promise((resolve, reject) => reject("BLA")).catch(x => resolved).then(x => sink(x)) // NOT OK
Promise.resolve(123).then(x => resolved).catch(x => sink(x)) // OK
Promise.resolve(123).then(x => resolved).then(x => sink(x)) // NOT OK
Promise.resolve(123).then(x => rejected).catch(x => sink(x)) // NOT OK
Promise.resolve(123).then(x => rejected).then(x => sink(x)) // OK
new Promise((resolve, reject) => resolve(resolved)).then(x => sink(x)); // NOT OK
Promise.resolve(resolved).then(x => sink(x)); // NOT OK
})();
(async function () {
var source = "source";
async function async() {
return source;
}
sink(async()); // OK - wrapped in a promise. (NOT OK for taint-tracking configs)
sink(await async()); // NOT OK
async function throwsAsync() {
throw source;
}
try {
throwsAsync();
} catch (e) {
sink(e); // OK - throwsAsync just returns a promise.
}
try {
await throwsAsync();
} catch (e) {
sink(e); // NOT OK
}
})();
(function () {
var source = "source";
var bluebird = require("bluebird");
bluebird.mapSeries(source, x => sink(x)); // NOT OK (for taint-tracking configs)
const foo = bluebird.mapSeries(source, x => x);
sink(foo); // NOT OK (for taint-tracking configs)
})