blob: fb91dcd879640e61cd0034874da9cfe229c1a60b [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
29var should_throw_on_null_and_undefined =
30 [Object.prototype.toLocaleString,
31 Object.prototype.valueOf,
32 Object.prototype.hasOwnProperty,
33 Object.prototype.isPrototypeOf,
34 Object.prototype.propertyIsEnumerable,
35 Array.prototype.concat,
36 Array.prototype.join,
37 Array.prototype.pop,
38 Array.prototype.push,
39 Array.prototype.reverse,
40 Array.prototype.shift,
41 Array.prototype.slice,
42 Array.prototype.sort,
43 Array.prototype.splice,
44 Array.prototype.unshift,
45 Array.prototype.indexOf,
46 Array.prototype.lastIndexOf,
47 Array.prototype.every,
48 Array.prototype.some,
49 Array.prototype.forEach,
50 Array.prototype.map,
51 Array.prototype.filter,
52 Array.prototype.reduce,
53 Array.prototype.reduceRight,
54 String.prototype.charAt,
55 String.prototype.charCodeAt,
56 String.prototype.concat,
57 String.prototype.indexOf,
58 String.prototype.lastIndexOf,
59 String.prototype.localeCompare,
60 String.prototype.match,
61 String.prototype.replace,
62 String.prototype.search,
63 String.prototype.slice,
64 String.prototype.split,
65 String.prototype.substring,
66 String.prototype.toLowerCase,
67 String.prototype.toLocaleLowerCase,
68 String.prototype.toUpperCase,
69 String.prototype.toLocaleUpperCase,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 String.prototype.trim];
Ben Murdoch257744e2011-11-30 15:57:28 +000071
72// Non generic natives do not work on any input other than the specific
73// type, but since this change will allow call to be invoked with undefined
74// or null as this we still explicitly test that we throw on these here.
75var non_generic =
76 [Array.prototype.toString,
77 Array.prototype.toLocaleString,
78 Function.prototype.toString,
79 Function.prototype.call,
80 Function.prototype.apply,
81 String.prototype.toString,
82 String.prototype.valueOf,
83 Boolean.prototype.toString,
84 Boolean.prototype.valueOf,
85 Number.prototype.toString,
86 Number.prototype.valueOf,
87 Number.prototype.toFixed,
88 Number.prototype.toExponential,
89 Number.prototype.toPrecision,
90 Date.prototype.toString,
91 Date.prototype.toDateString,
92 Date.prototype.toTimeString,
93 Date.prototype.toLocaleString,
94 Date.prototype.toLocaleDateString,
95 Date.prototype.toLocaleTimeString,
96 Date.prototype.valueOf,
97 Date.prototype.getTime,
98 Date.prototype.getFullYear,
99 Date.prototype.getUTCFullYear,
100 Date.prototype.getMonth,
101 Date.prototype.getUTCMonth,
102 Date.prototype.getDate,
103 Date.prototype.getUTCDate,
104 Date.prototype.getDay,
105 Date.prototype.getUTCDay,
106 Date.prototype.getHours,
107 Date.prototype.getUTCHours,
108 Date.prototype.getMinutes,
109 Date.prototype.getUTCMinutes,
110 Date.prototype.getSeconds,
111 Date.prototype.getUTCSeconds,
112 Date.prototype.getMilliseconds,
113 Date.prototype.getUTCMilliseconds,
114 Date.prototype.getTimezoneOffset,
115 Date.prototype.setTime,
116 Date.prototype.setMilliseconds,
117 Date.prototype.setUTCMilliseconds,
118 Date.prototype.setSeconds,
119 Date.prototype.setUTCSeconds,
120 Date.prototype.setMinutes,
121 Date.prototype.setUTCMinutes,
122 Date.prototype.setHours,
123 Date.prototype.setUTCHours,
124 Date.prototype.setDate,
125 Date.prototype.setUTCDate,
126 Date.prototype.setMonth,
127 Date.prototype.setUTCMonth,
128 Date.prototype.setFullYear,
129 Date.prototype.setUTCFullYear,
130 Date.prototype.toUTCString,
131 Date.prototype.toISOString,
132 Date.prototype.toJSON,
133 RegExp.prototype.exec,
134 RegExp.prototype.test,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100135 RegExp.prototype.toString,
136 Error.prototype.toString];
Ben Murdoch257744e2011-11-30 15:57:28 +0000137
138
139// Mapping functions.
140var mapping_functions =
141 [Array.prototype.every,
142 Array.prototype.some,
143 Array.prototype.forEach,
144 Array.prototype.map,
145 Array.prototype.filter];
146
147// Reduce functions.
148var reducing_functions =
149 [Array.prototype.reduce,
150 Array.prototype.reduceRight];
151
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000152function checkExpectedMessage(e) {
153 assertTrue(e.message.indexOf("called on null or undefined") >= 0 ||
154 e.message.indexOf("invoked on undefined or null value") >= 0 ||
155 e.message.indexOf("Cannot convert undefined or null to object") >= 0);
156}
157
Ben Murdoch257744e2011-11-30 15:57:28 +0000158// Test that all natives using the ToObject call throw the right exception.
159for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
160 // Sanity check that all functions are correct
161 assertEquals(typeof(should_throw_on_null_and_undefined[i]), "function");
162
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000163 var exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000164 try {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400165 // We need to pass a dummy object argument ({}) to these functions because
166 // of Object.prototype.isPrototypeOf's special behavior, see issue 3483
167 // for more details.
168 should_throw_on_null_and_undefined[i].call(null, {});
Ben Murdoch257744e2011-11-30 15:57:28 +0000169 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000170 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000172 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000173 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000174
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000175 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000176 try {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400177 should_throw_on_null_and_undefined[i].call(undefined, {});
Ben Murdoch257744e2011-11-30 15:57:28 +0000178 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000179 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000181 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000182 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000183
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000184 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000185 try {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400186 should_throw_on_null_and_undefined[i].apply(null, [{}]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000187 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000188 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000190 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000191 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000192
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000193 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000194 try {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400195 should_throw_on_null_and_undefined[i].apply(undefined, [{}]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000196 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000197 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000198 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000199 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000200 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000201}
202
203// Test that all natives that are non generic throw on null and undefined.
204for (var i = 0; i < non_generic.length; i++) {
205 // Sanity check that all functions are correct
206 assertEquals(typeof(non_generic[i]), "function");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000207
208 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000209 try {
210 non_generic[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000211 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000212 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000213 assertTrue(e instanceof TypeError);
214 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000215 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000216
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000217 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000218 try {
219 non_generic[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000220 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000221 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000222 assertTrue(e instanceof TypeError);
223 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000224 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000225
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000226 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000227 try {
228 non_generic[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000229 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000230 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000231 assertTrue(e instanceof TypeError);
232 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000233 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000234
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000235 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000236 try {
237 non_generic[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000238 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000239 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000240 assertTrue(e instanceof TypeError);
241 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000242 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000243}
244
245
246// Test that we still throw when calling with thisArg null or undefined
247// through an array mapping function.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400248// We need to make sure that the elements of `array` are all object values,
249// see issue 3483 for more details.
250var array = [{}, [], new Number, new Map, new WeakSet];
Ben Murdoch257744e2011-11-30 15:57:28 +0000251for (var j = 0; j < mapping_functions.length; j++) {
252 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000253 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000254 try {
255 mapping_functions[j].call(array,
256 should_throw_on_null_and_undefined[i],
257 null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000258 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000259 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000261 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000262 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000263
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000264 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000265 try {
266 mapping_functions[j].call(array,
267 should_throw_on_null_and_undefined[i],
268 undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000269 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000270 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000272 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000273 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000274 }
275}
276
277for (var j = 0; j < mapping_functions.length; j++) {
278 for (var i = 0; i < non_generic.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000279 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000280 try {
281 mapping_functions[j].call(array,
282 non_generic[i],
283 null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000284 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000285 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000286 assertTrue(e instanceof TypeError);
287 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000288 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000289
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000290 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000291 try {
292 mapping_functions[j].call(array,
293 non_generic[i],
294 undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000295 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000296 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000297 assertTrue(e instanceof TypeError);
298 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000299 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000300 }
301}
302
303
304// Reduce functions do a call with null as this argument.
305for (var j = 0; j < reducing_functions.length; j++) {
306 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000307 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000308 try {
309 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000310 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000311 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000312 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000313 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000314 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000315
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000316 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000317 try {
318 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000319 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000320 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000321 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000322 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000323 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000324 }
325}
326
327for (var j = 0; j < reducing_functions.length; j++) {
328 for (var i = 0; i < non_generic.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000329 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000330 try {
331 reducing_functions[j].call(array, non_generic[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000332 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000333 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000334 assertTrue(e instanceof TypeError);
335 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000336 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000337
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000338 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000339 try {
340 reducing_functions[j].call(array, non_generic[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000341 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000342 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000343 assertTrue(e instanceof TypeError);
344 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000345 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000346 }
347}
348
349
350// Object.prototype.toString()
351assertEquals(Object.prototype.toString.call(null),
352 '[object Null]')
353
354assertEquals(Object.prototype.toString.call(undefined),
355 '[object Undefined]')