misc_bugs.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
  4. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  5. //-------------------------------------------------------------------------------------------------------
  6. WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  7. var tests = [
  8. {
  9. name: "calling Symbol.toPrimitive on Date prototype should not AV",
  10. body: function () {
  11. Date.prototype[Symbol.toPrimitive].call({},'strin' + 'g');
  12. }
  13. },
  14. {
  15. name: "updated stackTraceLimit should not fire re-entrancy assert",
  16. body: function () {
  17. Error.__defineGetter__('stackTraceLimit', function () { return 1;});
  18. assert.throws(()=> Array.prototype.map.call([]));
  19. }
  20. },
  21. {
  22. name: "Array.prototype.slice should not fire re-entrancy error when the species returns proxy",
  23. body: function () {
  24. let arr = [1, 2];
  25. arr.__proto__ = {
  26. constructor: {
  27. [Symbol.species]: function () {
  28. return new Proxy({}, {
  29. defineProperty(...args) {
  30. return Reflect.defineProperty(...args);
  31. }
  32. });
  33. }
  34. }
  35. }
  36. Array.prototype.slice.call(arr);
  37. }
  38. },
  39. {
  40. name: "rest param under eval with arguments usage in the body should not fail assert",
  41. body: function () {
  42. f();
  43. function f() {
  44.     eval("function bar(...x){arguments;}")
  45. }
  46. }
  47. },
  48. {
  49. name: "Token left after parsing lambda result to the syntax error",
  50. body: function () {
  51. assert.throws(()=> { eval('function foo ([ [] = () => { } = {a2:z2}]) { };'); });
  52. }
  53. },
  54. {
  55. name: "Token left after parsing lambda in ternary operator should not throw",
  56. body: function () {
  57. assert.doesNotThrow(()=> { eval('function foo () { true ? e => {} : 1};'); });
  58. }
  59. },
  60. {
  61. name: "ArrayBuffer.slice with proxy constructor should not fail fast",
  62. body: function () {
  63. let arr = new ArrayBuffer(10);
  64. arr.constructor = new Proxy(ArrayBuffer, {});
  65. arr.slice(1,2);
  66. }
  67. },
  68. {
  69. name: "Large proxy chain should not cause IsConstructor to crash on stack overflow",
  70. body: function () {
  71. let p = new Proxy(Object, {});
  72. for (let i=0; i<20000; ++i)
  73. {
  74. p = new Proxy(p, {});
  75. }
  76. try
  77. {
  78. let a = new p();
  79. }
  80. catch(e)
  81. {
  82. }
  83. }
  84. },
  85. {
  86. name: "splice an array which has getter/setter at 4294967295 should not fail due to re-entrancy error",
  87. body: function () {
  88. var base = 4294967290;
  89. var arr = [];
  90. for (var i = 0; i < 10; i++) {
  91. arr[base + i] = 100 + i;
  92. }
  93. Object.defineProperty(arr, 4294967295, {
  94. get: function () { }, set : function(b) { }
  95. }
  96. );
  97. assert.throws(()=> {arr.splice(4294967290, 0, 200, 201, 202, 203, 204, 205, 206);});
  98. }
  99. },
  100. {
  101. name: "Passing args count near 2**16 should not fire assert (OS# 17406027)",
  102. body: function () {
  103. try {
  104. eval.call(...(new Array(2**16)));
  105. } catch (e) { }
  106. try {
  107. eval.call(...(new Array(2**16+1)));
  108. } catch (e) { }
  109. try {
  110. var sc1 = WScript.LoadScript(`function foo() {}`, "samethread");
  111. sc1.foo(...(new Array(2**16)));
  112. } catch(e) { }
  113. try {
  114. var sc2 = WScript.LoadScript(`function foo() {}`, "samethread");
  115. sc2.foo(...(new Array(2**16+1)));
  116. } catch(e) { }
  117. try {
  118. function foo() {}
  119. Reflect.construct(foo, new Array(2**16-3));
  120. } catch(e) { }
  121. try {
  122. function foo() {}
  123. Reflect.construct(foo, new Array(2**16-2));
  124. } catch(e) { }
  125. try {
  126. function foo() {}
  127. var bar = foo.bind({}, 1);
  128. new bar(...(new Array(2**16+1)))
  129. } catch(e) { }
  130. }
  131. },
  132. {
  133. name: "Using RegExp as newTarget should not assert",
  134. body: function() {
  135. var v0 = function() { this.a; };
  136. var v1 = class extends v0 { constructor() { super(); } };
  137. Reflect.construct(v1, [], RegExp);
  138. }
  139. },
  140. {
  141. name: "getPrototypeOf Should not be called when set as prototype",
  142. body: function () {
  143. var p = new Proxy({}, { getPrototypeOf: function() {
  144. assert.fail("this should not be called")
  145. return {};
  146. }});
  147. var obj = {};
  148. obj.__proto__ = p; // This should not call the getPrototypeOf
  149. var obj1 = {};
  150. Object.setPrototypeOf(obj1, p); // This should not call the getPrototypeOf
  151. var obj2 = {__proto__ : p}; // This should not call the getPrototypeOf
  152. }
  153. },
  154. {
  155. name: "Cross-site activation object",
  156. body: function () {
  157. var tests = [0, 0];
  158. tests.forEach(function() {
  159. var eval = WScript.LoadScript(0, "samethread").eval;
  160. eval(0);
  161. });
  162. }
  163. },
  164. {
  165. name: "Destructuring declaration should return undefined",
  166. body: function () {
  167. assert.areEqual(undefined, eval("var {x} = {};"));
  168. assert.areEqual(undefined, eval("let {x,y} = {};"));
  169. assert.areEqual(undefined, eval("const [z] = [];"));
  170. assert.areEqual(undefined, eval("let {x} = {}, y = 1, {z} = {};"));
  171. assert.areEqual([1], eval("let {x} = {}; [x] = [1]"));
  172. }
  173. },
  174. {
  175. name: "Strict Mode : throw type error when the handler returns falsy value",
  176. body: function () {
  177. assert.throws(() => {"use strict"; let p1 = new Proxy({}, { set() {}}); p1.foo = 1;}, TypeError, "returning undefined on set handler is return false which will throw type error", "Proxy set handler returned false");
  178. assert.throws(() => {"use strict"; let p1 = new Proxy({}, { deleteProperty() {}}); delete p1.foo;}, TypeError, "returning undefined on deleteProperty handler is return false which will throw type error", "Proxy deleteProperty handler returned false");
  179. assert.throws(() => {"use strict"; let p1 = new Proxy({}, { set() {return false;}}); p1.foo = 1;}, TypeError, "set handler is returning false which will throw type error", "Proxy set handler returned false");
  180. assert.throws(() => {"use strict"; let p1 = new Proxy({}, { deleteProperty() {return false;}}); delete p1.foo;}, TypeError, "deleteProperty handler is returning false which will throw type error", "Proxy deleteProperty handler returned false");
  181. }
  182. },
  183. {
  184. name: "Generator : testing recursion",
  185. body: function () {
  186. // This will throw out of stack error
  187. assert.throws(() => {
  188. function foo() {
  189. function *f() {
  190. yield foo();
  191. }
  192. f().next();
  193. }
  194. foo();
  195. });
  196. }
  197. },
  198. {
  199. name: "destructuring : testing recursion",
  200. body: function () {
  201. try {
  202. eval(`
  203. var ${'['.repeat(6631)}
  204. `);
  205. assert.fail();
  206. }
  207. catch (e) {
  208. }
  209. try {
  210. eval(`
  211. var {${'a:{'.repeat(6631)}
  212. `);
  213. assert.fail();
  214. }
  215. catch (e) {
  216. }
  217. }
  218. },
  219. {
  220. name: "CrossSite issue while array concat OS: 18874745",
  221. body: function () {
  222. function test0() {
  223. var IntArr0 = Array();
  224. var sc0Code = `
  225. Object.defineProperty(Array, Symbol.species, { value : function() {
  226. return IntArr0;
  227. }
  228. }
  229. );
  230. test = function(a, list) {
  231. return [a].concat(list);
  232. }
  233. function out() {
  234. test({}, [1]);
  235. }
  236. `;
  237. var sc0 = WScript.LoadScript(sc0Code, 'samethread');
  238. sc0.IntArr0 = IntArr0;
  239. sc0.out();
  240. }
  241. test0();
  242. }
  243. },
  244. {
  245. name: "Init box javascript array : OS : 20517662",
  246. body: function () {
  247. var obj = {};
  248. obj[0] = 11;
  249. obj[1] = {};
  250. obj[17] = 222;
  251. obj[35] = 333; // This is will increase the size past the inline segment
  252. Object.assign({}, obj); // The InitBoxedInlineSegments will be called due to this call.
  253. }
  254. },
  255. {
  256. name: "calling promise's function as constructor should not be allowed",
  257. body: function () {
  258. var var_0 = new Promise(function () {});
  259. var var_1 = function () {};
  260. var_0.then = function (a, b) {
  261. var_2 = b;
  262. };
  263. var_3 = Promise.prototype.finally.call(var_0, var_1);
  264. assert.throws(() => { new var_2([]).var_3(); },TypeError);
  265. }
  266. },
  267. {
  268. name: "issue : 6174 : calling ToNumber for the fill value for typedarray.prototype.fill",
  269. body: function () {
  270. let arr1 = new Uint32Array(5);
  271. let valueOfCalled = false;
  272. let p1 = new Proxy([], {
  273. get: function(oTarget, sKey) {
  274. if (sKey.toString() == 'valueOf') {
  275. valueOfCalled = true;
  276. }
  277. return Reflect.get(oTarget, sKey);
  278. }
  279. });
  280. Uint32Array.prototype.fill.call(arr1, p1, 5, 1);
  281. assert.isTrue(valueOfCalled);
  282. }
  283. },
  284. {
  285. name: "class name should not change if calling multiple times",
  286. body: function () {
  287. function getClass() {
  288. class A {
  289. constructor() {
  290. }
  291. };
  292. return A;
  293. }
  294. let f1 = getClass();
  295. let f2 = getClass();
  296. let f3 = getClass();
  297. assert.areEqual("A", f1.name);
  298. assert.areEqual("A", f2.name);
  299. assert.areEqual("A", f3.name);
  300. }
  301. },
  302. {
  303. name: "should throw syntax error when expression within if is comma-terminated",
  304. body: function () {
  305. assert.throws(()=> { eval('var f = function () { var f = 0; if (f === 0,) print("run_here"); }; f();'); }, SyntaxError);
  306. }
  307. }
  308. ];
  309. testRunner.runTests(tests, { verbose: WScript.Arguments[0] != "summary" });