Bug 1456973 - Add explicit ToNumber in wrappedCompareFn in TypedArraySort. r=jorendorff
authorAshley Hauck <khyperia@mozilla.com>
Tue, 21 Aug 2018 10:16:00 +0300
changeset 481791 4e65beb5c22617498520374366b9391ac416565a
parent 481790 ba637657bbf8a6b52fa42a565ec8555997ccd936
child 481815 a34520293b3867e2a3999c07439077479274e3b5
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewersjorendorff
bugs1456973
milestone63.0a1
Bug 1456973 - Add explicit ToNumber in wrappedCompareFn in TypedArraySort. r=jorendorff
js/src/builtin/TypedArray.js
js/src/tests/non262/TypedArray/sort-tonumber.js
--- a/js/src/builtin/TypedArray.js
+++ b/js/src/builtin/TypedArray.js
@@ -1208,17 +1208,17 @@ function TypedArraySort(comparefn) {
         }
         return QuickSort(obj, len, TypedArrayCompare);
     }
 
     // To satisfy step 2 from TypedArray SortCompare described in 22.2.3.26
     // the user supplied comparefn is wrapped.
     var wrappedCompareFn = function(x, y) {
         // Step a.
-        var v = comparefn(x, y);
+        var v = +comparefn(x, y);
 
         // Step b.
         var length;
         if (isTypedArray) {
             length = TypedArrayLength(obj);
         } else {
             length = callFunction(CallTypedArrayMethodIfWrapped, obj, "TypedArrayLengthMethod");
         }
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/TypedArray/sort-tonumber.js
@@ -0,0 +1,29 @@
+var BUGNUMBER = 230216;
+var summary = 'Ensure ToNumber is called on the result of compareFn inside TypedArray.prototype.sort';
+
+printBugNumber(BUGNUMBER);
+printStatus(summary);
+
+var ta = new Int32Array(4);
+var ab = ta.buffer;
+
+var called = false;
+try {
+  ta.sort(function(a, b) {
+    // IsDetachedBuffer is checked right after calling the compare function.
+    // The order of operations is:
+    // var tmp = compareFn(a, b)
+    // var res = ToNumber(tmp)
+    // if IsDetachedBuffer, throw TypeError
+    // [...]
+    // inspect `res` to determine sorting (calling ToNumber in the process)
+    // So, detach the ArrayBuffer to throw, to make sure we're actually calling ToNumber immediately (as spec'd)
+    detachArrayBuffer(ab);
+    return {
+      [Symbol.toPrimitive]() { called = true; }
+    };
+  });
+} catch (e) { }
+
+if (typeof reportCompare === "function")
+    reportCompare(true, called);