Changeset 261987 in webkit


Ignore:
Timestamp:
May 21, 2020 1:41:21 AM (4 years ago)
Author:
Alexey Shvayka
Message:

Array.prototype.concat is incorrect with objects whose "length" exceeds 2 32 - 1
https://bugs.webkit.org/show_bug.cgi?id=212167

Reviewed by Saam Barati.

JSTests:

  • stress/array-prototype-concat-of-long-spliced-arrays.js:
  • stress/array-prototype-concat-of-long-spliced-arrays2.js:
  • test262/expectations.yaml: Mark 4 test cases as passing.

Source/JavaScriptCore:

This patch increases "length" limit of Array.prototype.concat result to @MAX_SAFE_INTEGER
and changes thrown error to TypeError, aligning JSC with the spec [1], V8, and SpiderMonkey.

Also, adds missing @MAX_SAFE_INTEGER overflow check in Array.from [2] (we implement similar
checks in other methods). SunSpider and microbenchmarks/concat-append-one.js are both neutral.

[1]: https://tc39.es/ecma262/#sec-array.prototype.concat (steps 5.c.iii, 5.d.ii)
[2]: https://tc39.es/ecma262/#sec-array.from (step 5.e.i)

  • builtins/ArrayConstructor.js:

(from):

  • builtins/ArrayPrototype.js:

(globalPrivate.concatSlowPath):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r261862 r261987  
     12020-05-21  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Array.prototype.concat is incorrect with objects whose "length" exceeds 2 ** 32 - 1
     4        https://bugs.webkit.org/show_bug.cgi?id=212167
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/array-prototype-concat-of-long-spliced-arrays.js:
     9        * stress/array-prototype-concat-of-long-spliced-arrays2.js:
     10        * test262/expectations.yaml: Mark 4 test cases as passing.
     11
    1122020-05-19  Michael Catanzaro  <mcatanzaro@gnome.org>
    213
  • trunk/JSTests/stress/array-prototype-concat-of-long-spliced-arrays.js

    r237129 r261987  
    3131    }
    3232
    33     shouldEqual(exception, "RangeError: Length exceeded the maximum array length");
     33    shouldEqual(exception, "RangeError: Invalid array length");
    3434}
    3535
  • trunk/JSTests/stress/array-prototype-concat-of-long-spliced-arrays2.js

    r237200 r261987  
    2121        exception = e;
    2222    }
    23     shouldEqual(exception, "RangeError: Length exceeded the maximum array length");
     23    shouldEqual(exception, "RangeError: Invalid array length");
    2424}
    2525
  • trunk/JSTests/test262/expectations.yaml

    r261787 r261987  
    655655  default: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
    656656  strict mode: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
    657 test/built-ins/Array/prototype/concat/arg-length-exceeding-integer-limit.js:
    658   default: 'Test262Error: Expected a TypeError but got a RangeError'
    659   strict mode: 'Test262Error: Expected a TypeError but got a RangeError'
    660 test/built-ins/Array/prototype/concat/arg-length-near-integer-limit.js:
    661   default: 'Test262Error: Expected a Test262Error but got a RangeError'
    662   strict mode: 'Test262Error: Expected a Test262Error but got a RangeError'
    663657test/built-ins/Array/prototype/splice/property-traps-order-with-species.js:
    664658  default: 'Test262Error: Expected [defineProperty, defineProperty, set, getOwnPropertyDescriptor, defineProperty] and [defineProperty, defineProperty] to have the same contents. '
  • trunk/Source/JavaScriptCore/ChangeLog

    r261930 r261987  
     12020-05-21  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        Array.prototype.concat is incorrect with objects whose "length" exceeds 2 ** 32 - 1
     4        https://bugs.webkit.org/show_bug.cgi?id=212167
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch increases "length" limit of Array.prototype.concat result to @MAX_SAFE_INTEGER
     9        and changes thrown error to TypeError, aligning JSC with the spec [1], V8, and SpiderMonkey.
     10
     11        Also, adds missing @MAX_SAFE_INTEGER overflow check in Array.from [2] (we implement similar
     12        checks in other methods). SunSpider and microbenchmarks/concat-append-one.js are both neutral.
     13
     14        [1]: https://tc39.es/ecma262/#sec-array.prototype.concat (steps 5.c.iii, 5.d.ii)
     15        [2]: https://tc39.es/ecma262/#sec-array.from (step 5.e.i)
     16
     17        * builtins/ArrayConstructor.js:
     18        (from):
     19        * builtins/ArrayPrototype.js:
     20        (globalPrivate.concatSlowPath):
     21
    1222020-05-20  Michael Saboff  <msaboff@apple.com>
    223
  • trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js

    r261601 r261987  
    7070
    7171        for (var value of wrapper) {
     72            if (k >= @MAX_SAFE_INTEGER)
     73                @throwTypeError("Length exceeded the maximum array length");
    7274            if (mapFn)
    7375                @putByValDirect(result, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
  • trunk/Source/JavaScriptCore/builtins/ArrayPrototype.js

    r261430 r261987  
    559559        if ((spreadable === @undefined && @isArray(currentElement)) || spreadable) {
    560560            var length = @toLength(currentElement.length);
    561             if (length + resultIndex > @MAX_ARRAY_INDEX)
    562                 @throwRangeError("Length exceeded the maximum array length");
    563             if (resultIsArray && @isJSArray(currentElement)) {
     561            if (length + resultIndex > @MAX_SAFE_INTEGER)
     562                @throwTypeError("Length exceeded the maximum array length");
     563            if (resultIsArray && @isJSArray(currentElement) && length + resultIndex <= @MAX_ARRAY_INDEX) {
    564564                @appendMemcpy(result, currentElement, resultIndex);
    565565                resultIndex += length;
     
    572572            }
    573573        } else {
    574             if (resultIndex >= @MAX_ARRAY_INDEX)
    575                 @throwRangeError("Length exceeded the maximum array length");
     574            if (resultIndex >= @MAX_SAFE_INTEGER)
     575                @throwTypeError("Length exceeded the maximum array length");
    576576            @putByValDirect(result, resultIndex++, currentElement);
    577577        }
Note: See TracChangeset for help on using the changeset viewer.