Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /*
2 * Any copyright is dedicated to the Public Domain.
3 * http://creativecommons.org/licenses/publicdomain/
4 * Contributor:
5 * Jeff Walden <jwalden+code@mit.edu>
6 */
8 //-----------------------------------------------------------------------------
9 var BUGNUMBER = 562448;
10 var summary = 'Function.prototype.apply should accept any arraylike arguments';
11 print(BUGNUMBER + ": " + summary);
13 /**************
14 * BEGIN TEST *
15 **************/
17 function expectTypeError(fun, msg)
18 {
19 try
20 {
21 fun();
22 assertEq(true, false, "should have thrown a TypeError");
23 }
24 catch (e)
25 {
26 assertEq(e instanceof TypeError, true, msg + "; instead threw " + e);
27 }
28 }
30 function fun() { }
32 var global = this;
35 /* Step 1. */
36 var nonfuns = [null, 1, -1, 2.5, "[[Call]]", undefined, true, false, {}];
37 for (var i = 0, sz = nonfuns.length; i < sz; i++)
38 {
39 var f = function()
40 {
41 Function.prototype.apply.apply(nonfuns[i], [1, 2, 3]);
42 };
43 var msg =
44 "expected TypeError calling Function.prototype.apply with uncallable this";
45 expectTypeError(f, msg);
46 }
49 /* Step 2. */
50 var thisObj = {};
52 var currentThis, currentThisBox;
53 function funLength()
54 {
55 assertEq(arguments.length, 0, "should have been called with no arguments");
56 assertEq(this, currentThis, "wrong this");
57 }
58 function strictFunLength()
59 {
60 "use strict";
61 assertEq(arguments.length, 0, "should have been called with no arguments");
62 assertEq(this, currentThis, "wrong this");
63 }
65 currentThis = global;
66 funLength.apply();
67 funLength.apply(undefined);
68 funLength.apply(undefined, undefined);
69 funLength.apply(undefined, null);
71 currentThis = undefined;
72 strictFunLength.apply();
73 strictFunLength.apply(undefined);
74 strictFunLength.apply(undefined, undefined);
75 strictFunLength.apply(undefined, null);
77 currentThis = null;
78 strictFunLength.apply(null);
79 strictFunLength.apply(null, undefined);
80 strictFunLength.apply(null, null);
82 currentThis = thisObj;
83 funLength.apply(thisObj);
84 funLength.apply(thisObj, null);
85 funLength.apply(thisObj, undefined);
86 strictFunLength.apply(thisObj);
87 strictFunLength.apply(thisObj, null);
88 strictFunLength.apply(thisObj, undefined);
90 currentThis = 17;
91 strictFunLength.apply(17);
92 strictFunLength.apply(17, null);
93 strictFunLength.apply(17, undefined);
95 function funThisPrimitive()
96 {
97 assertEq(arguments.length, 0, "should have been called with no arguments");
98 assertEq(this instanceof currentThisBox, true,
99 "this not instanceof " + currentThisBox);
100 assertEq(this.valueOf(), currentThis,
101 "wrong this valueOf()");
102 }
104 currentThis = 17;
105 currentThisBox = Number;
106 funThisPrimitive.apply(17);
107 funThisPrimitive.apply(17, undefined);
108 funThisPrimitive.apply(17, null);
110 currentThis = "foopy";
111 currentThisBox = String;
112 funThisPrimitive.apply("foopy");
113 funThisPrimitive.apply("foopy", undefined);
114 funThisPrimitive.apply("foopy", null);
116 currentThis = false;
117 currentThisBox = Boolean;
118 funThisPrimitive.apply(false);
119 funThisPrimitive.apply(false, undefined);
120 funThisPrimitive.apply(false, null);
123 /* Step 3. */
124 var nonobjs = [1, -1, 2.5, "[[Call]]", true, false];
125 for (var i = 0, sz = nonobjs.length; i < sz; i++)
126 {
127 var f = function() { fun.apply(thisObj, nonobjs[i]); };
128 var msg = "should have thrown a TypeError with non-object arguments";
129 expectTypeError(f, msg);
130 }
133 /* Step 4. */
134 var args = { get length() { throw 42; } };
135 try
136 {
137 fun.apply(thisObj, args);
138 }
139 catch (e)
140 {
141 assertEq(e, 42, "didn't throw result of [[Get]] on arguments object");
142 }
145 /*
146 * NB: There was an erratum removing the steps numbered 5 and 7 in the original
147 * version of ES5; see also the comments in js_fun_apply.
148 */
150 /* Step 5. */
151 var called = false;
152 var argsObjectLength =
153 { length: { valueOf: function() { called = true; return 17; } } };
155 fun.apply({}, argsObjectLength);
156 assertEq(called, true, "should have been set in valueOf called via ToUint32");
158 var upvar = "unset";
159 var argsObjectPrimitiveLength =
160 {
161 length:
162 {
163 valueOf: function() { upvar = "valueOf"; return {}; },
164 toString: function()
165 {
166 upvar = upvar === "valueOf" ? "both" : "toString";
167 return 17;
168 }
169 }
170 };
171 fun.apply({}, argsObjectPrimitiveLength);
172 assertEq(upvar, "both", "didn't call all hooks properly");
175 /* Step 6-9. */
176 var seenThis, res, steps;
177 var argsAccessors =
178 {
179 length: 4,
180 get 0() { steps.push("0"); return 1; },
181 get 1() { steps.push("1"); return 2; },
182 // make sure values shine through holes
183 get 3() { steps.push("3"); return 8; },
184 };
186 Object.prototype[2] = 729;
188 seenThis = "not seen";
189 function argsAsArray()
190 {
191 seenThis = this;
192 steps.push(Math.PI);
193 return Array.prototype.map.call(arguments, function(v) { return v; });
194 }
196 steps = [];
197 res = argsAsArray.apply(thisObj, argsAccessors);
198 assertEq(seenThis, thisObj, "saw wrong this");
200 assertEq(steps.length, 4, "wrong steps: " + steps);
201 assertEq(steps[0], "0", "bad step 0");
202 assertEq(steps[1], "1", "bad step 1");
203 assertEq(steps[2], "3", "bad step 3");
204 assertEq(steps[3], Math.PI, "bad last step");
206 assertEq(res.length, 4, "wrong return: " + res);
207 assertEq(res[0], 1, "wrong ret[0]");
208 assertEq(res[1], 2, "wrong ret[0]");
209 assertEq(res[2], 729, "wrong ret[0]");
210 assertEq(res[3], 8, "wrong ret[0]");
212 seenThis = "not seen";
213 function strictArgsAsArray()
214 {
215 "use strict";
216 seenThis = this;
217 steps.push(NaN);
218 return Array.prototype.map.call(arguments, function(v) { return v; });
219 }
221 steps = [];
222 res = strictArgsAsArray.apply(null, argsAccessors);
223 assertEq(seenThis, null, "saw wrong this");
225 assertEq(steps.length, 4, "wrong steps: " + steps);
226 assertEq(steps[0], "0", "bad step 0");
227 assertEq(steps[1], "1", "bad step 1");
228 assertEq(steps[2], "3", "bad step 3");
229 assertEq(steps[3], 0 / 0, "bad last step");
231 assertEq(res.length, 4, "wrong return: " + res);
232 assertEq(res[0], 1, "wrong ret[0]");
233 assertEq(res[1], 2, "wrong ret[0]");
234 assertEq(res[2], 729, "wrong ret[0]");
235 assertEq(res[3], 8, "wrong ret[0]");
237 strictArgsAsArray.apply(17, argsAccessors);
238 assertEq(seenThis, 17, "saw wrong this");
240 /******************************************************************************/
242 if (typeof reportCompare === "function")
243 reportCompare(true, true);
245 print("All tests passed!");