forked from chakra-core/ChakraCore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCallNonFunction.js
More file actions
335 lines (289 loc) · 8.25 KB
/
CallNonFunction.js
File metadata and controls
335 lines (289 loc) · 8.25 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
var obj = new Object();
obj.n = null;
obj.blah = 1;
obj[0] = null;
obj[1] = 1;
var n = null;
var blah = 1;
// Call integer global var
function CallErrorTest0()
{
blah();
}
// new integer global var
function CallErrorTest1()
{
new blah();
}
// Call integer property
function CallErrorTest2()
{
obj.blah();
}
// new integer property
function CallErrorTest3()
{
new obj.blah();
}
// Call primitive null
function CallErrorTest4()
{
null();
}
// New primitive null
function CallErrorTest5()
{
new null();
}
// Call integer
function CallErrorTest6()
{
1();
}
// new integer
function CallErrorTest7()
{
new 1();
}
// Call parameter
function CallErrorTest8()
{
function func(f)
{
f();
}
func(1);
}
// Call index - null
function CallErrorTest9()
{
obj[0]();
}
// new index - null
function CallErrorTest10()
{
new obj[0]();
}
// Call index - number
function CallErrorTest11()
{
obj[1]();
}
// new index - number
function CallErrorTest12()
{
new obj[1]();
}
// Call index on null
function CallErrorTest13()
{
n[1]();
}
// new index on null
function CallErrorTest14()
{
new n[1]();
}
// Call property on null
function CallErrorTest15()
{
n.prop();
}
// new property on null
function CallErrorTest16()
{
new n.prop();
}
// Call null property
function CallErrorTest17()
{
obj.n();
}
// new null property
function CallErrorTest18()
{
new obj.n();
}
// Call null global var
function CallErrorTest17()
{
n();
}
// new null global var
function CallErrorTest18()
{
new n();
}
var i = 0;
while (this["CallErrorTest" + i] != undefined)
{
safeCall(this["CallErrorTest" + i]);
i++;
}
writeLine("");
writeLine("");
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// The following tests invalid function calls on unresolvable vars, nonexisting and existing globals accessed using different
// methods, local vars, objects, arrays, and deleted properties. Test functions are generated for each case and evaluated.
var testCase_implicitGlobal = "implicit global";
var testCase_globalUsingWindow = "global using window";
var testCase_globalUsingThis = "global using this";
var testCase_local = "local";
var testCase_object = "object";
var testCase_arrayInitialized = "array initialized";
var testCase_arrayAssigned = "array assigned";
var testCases =
[
testCase_implicitGlobal,
testCase_globalUsingWindow,
testCase_globalUsingThis,
testCase_local,
testCase_object,
testCase_arrayInitialized,
testCase_arrayAssigned
];
var testValue_uninitialized = null; // don't initialize before calling as a function
var testValue_undefined = "undefined";
var testValue_null = "null";
var testValue_number = "1";
var testValue_object = "{}";
var testValues =
[
testValue_uninitialized,
testValue_undefined,
testValue_null,
testValue_number,
testValue_object
];
var globalIndex = 0;
function generateAndRunTests(testCase, doDelete)
{
if (testCase === testCase_local && doDelete)
return; // deleting is not supported for this test case
writeLine("--- Test case: " + testCase + ", do delete: " + doDelete + " ---");
writeLine("");
for (var testValueIndex in testValues)
{
var testValue = testValues[testValueIndex];
// A function that looks like the following is generated, and varies based on the test case and test value. The function
// below is generated for the following parameters: {testCase_arrayAssigned, testValue_object, doDelete = true}
// safeCall(function ()
// {
// var a = [];
// a[0] = {};
// delete a[0];
// a[0]();
// });
var globalIdentifier;
switch (testCase)
{
case testCase_implicitGlobal:
globalIdentifier = "g" + globalIndex++;
break;
case testCase_globalUsingWindow:
globalIdentifier = "window.g" + globalIndex++;
break;
case testCase_globalUsingThis:
globalIdentifier = "this.g" + globalIndex++;
break;
}
var f = "safeCall(function(){";
switch (testCase)
{
case testCase_implicitGlobal:
case testCase_globalUsingWindow:
case testCase_globalUsingThis:
if (!testValue && doDelete)
continue; // no need to delete an uninitialized property
if (testCase === testCase_globalUsingWindow)
writeLine("Only valid in IE:"); // the result of this test is only valid when run in IE since 'window' is undefined otherwise
if (testCase === testCase_globalUsingThis && (!testValue || doDelete))
writeLine("INCORRECT in JC all versions:"); // BUG: these cases produce incorrect results in JC (all versions) but work in IE
if (testValue)
f += globalIdentifier + "=" + testValue + ";";
if (doDelete)
f += "delete " + globalIdentifier + ";";
f += globalIdentifier + "();";
break;
case testCase_local:
f += "var v";
if (testValue)
f += "=" + testValue;
f += ";v();";
break;
case testCase_object:
if (!testValue && doDelete)
continue; // no need to delete an uninitialized property
f += "var o={";
if (testValue)
f += "p:" + testValue;
f += "};"
if (doDelete)
f += "delete o.p;";
f += "o.p();";
break;
case testCase_arrayInitialized:
if (!testValue && doDelete)
continue; // no need to delete an uninitialized property
if (testValue === testValue_undefined && !doDelete)
writeLine("INCORRECT in compat modes:");
f += "var a=[";
if (testValue)
f += testValue;
f += "];"
if (doDelete)
f += "delete a[0];";
f += "a[0]();";
break;
case testCase_arrayAssigned:
if (!testValue && doDelete)
continue; // no need to delete an uninitialized property
f += "var a=[];";
if (testValue)
f += "a[0]=" + testValue + ";";
if (doDelete)
f += "delete a[0];";
f += "a[0]();";
break;
default:
writeLine("Unknown test case '" + testCase + "'.");
return;
}
f += "});";
writeLine(f);
eval(f);
writeLine("");
}
writeLine("");
}
var booleans = [false, true];
for (var testCaseIndex in testCases)
{
var testCase = testCases[testCaseIndex];
for (var doDeleteIndex in booleans)
{
var doDelete = booleans[doDeleteIndex];
generateAndRunTests(testCase, doDelete);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Helpers
function writeLine(str)
{
WScript.Echo("" + str);
}
function safeCall(func)
{
try
{
return func();
}
catch (ex)
{
writeLine(ex.name + " (" + ex.number + "): " + ex.message);
}
}