⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 244950 in webkit


Ignore:
Timestamp:
May 4, 2019, 12:12:31 PM (7 years ago)
Author:
Tadeu Zagallo
Message:

TypedArrays should not store properties that are canonical numeric indices
https://bugs.webkit.org/show_bug.cgi?id=197228
<rdar://problem/49557381>

Reviewed by Saam Barati.

JSTests:

  • stress/array-species-config-array-constructor.js:

(test):

  • stress/put-direct-index-broken-2.js:
  • stress/typed-array-canonical-numeric-index-string.js: Added.

(makeTest.assert):
(makeTest):
(const.testInvalidIndices.makeTest.set assert):
(const.testInvalidIndices.makeTest):
(const.makeTestValidIndex.configurable.set assert):
(const.makeTestValidIndex.configurable):

  • stress/typedarray-access-monomorphic-neutered.js:

(checkNoException):
(testNoException):
(testFTLNoException):

  • stress/typedarray-access-neutered.js:

(testNoException):

  • stress/typedarray-getownproperty-not-configurable.js:

(foo):

  • test262/expectations.yaml:

Source/JavaScriptCore:

According to the spec[1]:

  • TypedArrays should not perform an ordinary GetOwnProperty/SetOwnProperty if the index is a

CanonicalNumericIndexString, but invalid according to IntegerIndexedElementGet and similar
functions. I.e., there are a few properties that should not be set in a TypedArray, like NaN,
Infinity and -0.

  • On DefineOwnProperty, the out-of-bounds check should be performed before validating the property

descriptor.

  • On GetOwnProperty, the returned descriptor for numeric properties should have writable set to true.

[1]: https://www.ecma-international.org/ecma-262/9.0/index.html#sec-integer-indexed-exotic-objects-defineownproperty-p-desc

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • runtime/JSGenericTypedArrayViewInlines.h:

(JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot):
(JSC::JSGenericTypedArrayView<Adaptor>::put):
(JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
(JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlotByIndex):
(JSC::JSGenericTypedArrayView<Adaptor>::putByIndex):

  • runtime/PropertyName.h:

(JSC::isCanonicalNumericIndexString):

LayoutTests:

  • fast/canvas/canvas-ImageData-behaviour-expected.txt:
  • fast/canvas/canvas-ImageData-behaviour.js:
Location:
trunk
Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r244939 r244950  
     12019-05-04  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        TypedArrays should not store properties that are canonical numeric indices
     4        https://bugs.webkit.org/show_bug.cgi?id=197228
     5        <rdar://problem/49557381>
     6
     7        Reviewed by Saam Barati.
     8
     9        * stress/array-species-config-array-constructor.js:
     10        (test):
     11        * stress/put-direct-index-broken-2.js:
     12        * stress/typed-array-canonical-numeric-index-string.js: Added.
     13        (makeTest.assert):
     14        (makeTest):
     15        (const.testInvalidIndices.makeTest.set assert):
     16        (const.testInvalidIndices.makeTest):
     17        (const.makeTestValidIndex.configurable.set assert):
     18        (const.makeTestValidIndex.configurable):
     19        * stress/typedarray-access-monomorphic-neutered.js:
     20        (checkNoException):
     21        (testNoException):
     22        (testFTLNoException):
     23        * stress/typedarray-access-neutered.js:
     24        (testNoException):
     25        * stress/typedarray-getownproperty-not-configurable.js:
     26        (foo):
     27        * test262/expectations.yaml:
     28
    1292019-05-03  Yusuke Suzuki  <ysuzuki@apple.com>
    230
  • trunk/JSTests/stress/array-species-config-array-constructor.js

    r216279 r244950  
    3333function test() {
    3434    const message = "TypeError: Attempting to configure non-configurable property on a typed array at index: 0";
    35     shouldThrow(() => foo.concat([1]), message);
     35    foo.concat([1]);
    3636    foo = [1,2,3,4];
    3737    shouldThrow(() => foo.slice(0), message);
  • trunk/JSTests/stress/put-direct-index-broken-2.js

    r232525 r244950  
    5858        err = e;
    5959    }
    60     assert(err.toString() ===  "TypeError: Attempting to configure non-configurable property on a typed array at index: 0");
     60    assert(!err);
    6161});
    6262
  • trunk/JSTests/stress/typedarray-access-monomorphic-neutered.js

    r203096 r244950  
    2929    test("delete array[0]", array);
    3030    test("Object.getOwnPropertyDescriptor(array, 0)", array);
    31     test("Object.defineProperty(array, 0, { value: 1, writable: true, configurable: false, enumerable: true })", array);
    3231    test("array[0] = 1", array);
    3332    test("array[i] = 1", array);
     
    4948    testFTL("delete array[0]", array, failArray);
    5049    testFTL("Object.getOwnPropertyDescriptor(array, 0)", array, failArray);
    51     testFTL("Object.defineProperty(array, 0, { value: 1, writable: true, configurable: false, enumerable: true })", array, failArray);
    5250    testFTL("array[0] = 1", array, failArray);
    5351    testFTL("array[i] = 1", array, failArray);
    5452}
     53
     54
     55function checkNoException(array, thunk, count) {
     56    thunk(array, count);
     57}
     58noInline(check);
     59
     60function testNoException(thunk, array) {
     61    let fn = Function("array", "i", thunk);
     62    noInline(fn);
     63    for (let i = 0; i < 10000; i++)
     64        checkNoException(array, fn, i);
     65}
     66
     67for (let constructor of typedArrays) {
     68    let array = new constructor(10);
     69    transferArrayBuffer(array.buffer);
     70    testNoException("Object.defineProperty(array, 0, { value: 1, writable: true, configurable: false, enumerable: true })", array);
     71}
     72
     73function testFTLNoException(thunk, array, failArray) {
     74    let fn = Function("array", "i", thunk);
     75    noInline(fn);
     76    for (let i = 0; i < 10000; i++)
     77        fn(array, i)
     78    checkNoException(failArray, fn, 10000);
     79}
     80for (let constructor of typedArrays) {
     81    let array = new constructor(10);
     82    let failArray = new constructor(10);
     83    transferArrayBuffer(failArray.buffer);
     84    testFTLNoException("Object.defineProperty(array, 0, { value: 1, writable: true, configurable: false, enumerable: true })", array, failArray);
     85}
  • trunk/JSTests/stress/typedarray-access-neutered.js

    r203096 r244950  
    2626    test((array) => delete array[0], i);
    2727    test((array) => Object.getOwnPropertyDescriptor(array, 0), i);
    28     test((array) => Object.defineProperty(array, 0, { value: 1, writable: true, configurable: false, enumerable: true }), i)
    2928    test((array) => array[0] = 1, i);
    3029}
     30
     31function checkNoException(thunk, count) {
     32    let array = new constructor(10);
     33    transferArrayBuffer(array.buffer);
     34    thunk(array);
     35}
     36
     37function testNoException(thunk, count) {
     38    for (constructor of typedArrays)
     39        checkNoException(thunk, count);
     40}
     41
     42for (let i = 0; i < 10000; i++) {
     43    testNoException((array) => Object.defineProperty(array, 0, { value: 1, writable: true, configurable: false, enumerable: true }), i)
     44}
  • trunk/JSTests/stress/typedarray-getownproperty-not-configurable.js

    r220377 r244950  
    1111        let b = Object.getOwnPropertyDescriptor(a, 0);
    1212        assert(b.value === 0);
    13         assert(b.writable === false);
     13        assert(b.writable === true);
    1414        assert(b.enumerable === true);
    1515        assert(b.configurable === false);
  • trunk/JSTests/test262/expectations.yaml

    r244833 r244950  
    13951395  default: 'Test262Error: Expected a Test262Error but got a TypeError (Testing with Float64Array.)'
    13961396  strict mode: 'Test262Error: Expected a Test262Error but got a TypeError (Testing with Float64Array.)'
     1397test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer-realm.js:
     1398  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
     1399  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    13971400test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer.js:
    1398   default: 'Test262Error: Return false before Detached Buffer check when value is a negative number Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1399   strict mode: 'Test262Error: Return false before Detached Buffer check when value is a negative number Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1400 test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-lower-than-zero.js:
    1401   default: 'Test262Error: -1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1402   strict mode: 'Test262Error: -1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1403 test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-minus-zero.js:
    1404   default: 'Test262Error: defineProperty returns false Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1405   strict mode: 'Test262Error: defineProperty returns false Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1406 test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-not-integer.js:
    1407   default: 'Test262Error: 0.1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1408   strict mode: 'Test262Error: 0.1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1409 test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-numericindex.js:
    1410   default: 'Test262Error: property is writable Expected SameValue(«false», «true») to be true (Testing with Float64Array.)'
    1411   strict mode: 'Test262Error: property is writable Expected SameValue(«false», «true») to be true (Testing with Float64Array.)'
     1401  default: 'Test262Error: Throws TypeError on valid numeric index if instance has a detached buffer Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
     1402  strict mode: 'Test262Error: Throws TypeError on valid numeric index if instance has a detached buffer Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    14121403test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/set-value.js:
    14131404  default: 'Test262Error: set value for sample[0] returns true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)'
     
    14161407  default: 'Test262Error: detaching a ArrayBuffer during defining an element of a typed array viewing it should throw Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    14171408  strict mode: 'Test262Error: detaching a ArrayBuffer during defining an element of a typed array viewing it should throw Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1418 test/built-ins/TypedArrayConstructors/internals/Get/detached-buffer.js:
    1419   default: 'Test262Error: detach buffer runs before checking for 1.1 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1420   strict mode: 'Test262Error: detach buffer runs before checking for 1.1 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1421 test/built-ins/TypedArrayConstructors/internals/Get/infinity-detached-buffer.js:
    1422   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1423   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    14241409test/built-ins/TypedArrayConstructors/internals/Get/key-is-not-integer.js:
    14251410  default: 'Test262Error: OrdinaryGet was called! Ref: 9.1.8.1 3.c (Testing with Float64Array.)'
     
    14341419  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    14351420  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1436 test/built-ins/TypedArrayConstructors/internals/GetOwnProperty/index-prop-desc.js:
    1437   default: 'Test262Error: index descriptor is writable [0] Expected SameValue(«false», «true») to be true (Testing with Float64Array.)'
    1438   strict mode: 'Test262Error: index descriptor is writable [0] Expected SameValue(«false», «true») to be true (Testing with Float64Array.)'
    14391421test/built-ins/TypedArrayConstructors/internals/HasProperty/abrupt-from-ordinary-has-parent-hasproperty.js:
    14401422  default: 'Test262Error:  (Testing with Float64Array.)'
     
    14461428  default: 'Test262Error: 0 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    14471429  strict mode: 'Test262Error: 0 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1448 test/built-ins/TypedArrayConstructors/internals/HasProperty/infinity-with-detached-buffer.js:
    1449   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    14501430test/built-ins/TypedArrayConstructors/internals/HasProperty/inherited-property.js:
    14511431  default: 'Test262Error: 42 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
     
    14631443  default: 'Test262Error: 1.1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    14641444  strict mode: 'Test262Error: 1.1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1465 test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer.js:
    1466   default: 'Test262Error: detach buffer runs before checking for 1.1 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1467   strict mode: 'Test262Error: detach buffer runs before checking for 1.1 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
    1468 test/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js:
    1469   default: 'Test262Error: -0 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1470   strict mode: 'Test262Error: -0 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1471 test/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js:
    1472   default: 'Test262Error: 1.1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1473   strict mode: 'Test262Error: 1.1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1474 test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds.js:
    1475   default: 'Test262Error: -1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    1476   strict mode: 'Test262Error: -1 Expected SameValue(«true», «false») to be true (Testing with Float64Array.)'
    14771445test/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-throws.js:
    14781446  default: 'Test262Error: ToNumber runs before ToInteger(index) Expected a Test262Error to be thrown but no exception was thrown at all (Testing with Float64Array.)'
  • trunk/LayoutTests/ChangeLog

    r244948 r244950  
     12019-05-04  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        TypedArrays should not store properties that are canonical numeric indices
     4        https://bugs.webkit.org/show_bug.cgi?id=197228
     5        <rdar://problem/49557381>
     6
     7        Reviewed by Saam Barati.
     8
     9        * fast/canvas/canvas-ImageData-behaviour-expected.txt:
     10        * fast/canvas/canvas-ImageData-behaviour.js:
     11
    1122019-05-04  Per Arne Vollan  <pvollan@apple.com>
    213
  • trunk/LayoutTests/fast/canvas/canvas-ImageData-behaviour-expected.txt

    r244816 r244950  
    4444PASS imageData.data[0] = undefined, imageData.data[0] is 0
    4545PASS imageData.data['foo']='garbage',imageData.data['foo'] is 'garbage'
    46 PASS imageData.data[-1]='garbage',imageData.data[-1] is 'garbage'
     46PASS imageData.data[-1]='garbage',imageData.data[-1] is undefined
    4747PASS imageData.data[17]='garbage',imageData.data[17] is undefined
    4848PASS successfullyParsed is true
  • trunk/LayoutTests/fast/canvas/canvas-ImageData-behaviour.js

    r244816 r244950  
    2222
    2323shouldBe("imageData.data['foo']='garbage',imageData.data['foo']", "'garbage'");
    24 shouldBe("imageData.data[-1]='garbage',imageData.data[-1]", "'garbage'");
     24shouldBe("imageData.data[-1]='garbage',imageData.data[-1]", "undefined");
    2525shouldBe("imageData.data[17]='garbage',imageData.data[17]", "undefined");
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r244907 r244950  
    858858    runtime/JSGlobalLexicalEnvironment.h
    859859    runtime/JSGlobalObject.h
     860    runtime/JSGlobalObjectFunctions.h
    860861    runtime/JSGlobalObjectInlines.h
    861862    runtime/JSImmutableButterfly.h
  • trunk/Source/JavaScriptCore/ChangeLog

    r244939 r244950  
     12019-05-04  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        TypedArrays should not store properties that are canonical numeric indices
     4        https://bugs.webkit.org/show_bug.cgi?id=197228
     5        <rdar://problem/49557381>
     6
     7        Reviewed by Saam Barati.
     8
     9        According to the spec[1]:
     10        - TypedArrays should not perform an ordinary GetOwnProperty/SetOwnProperty if the index is a
     11        CanonicalNumericIndexString, but invalid according to IntegerIndexedElementGet and similar
     12        functions. I.e., there are a few properties that should not be set in a TypedArray, like NaN,
     13        Infinity and -0.
     14        - On DefineOwnProperty, the out-of-bounds check should be performed before validating the property
     15        descriptor.
     16        - On GetOwnProperty, the returned descriptor for numeric properties should have writable set to true.
     17
     18        [1]: https://www.ecma-international.org/ecma-262/9.0/index.html#sec-integer-indexed-exotic-objects-defineownproperty-p-desc
     19
     20        * CMakeLists.txt:
     21        * JavaScriptCore.xcodeproj/project.pbxproj:
     22        * runtime/JSGenericTypedArrayViewInlines.h:
     23        (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot):
     24        (JSC::JSGenericTypedArrayView<Adaptor>::put):
     25        (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty):
     26        (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlotByIndex):
     27        (JSC::JSGenericTypedArrayView<Adaptor>::putByIndex):
     28        * runtime/PropertyName.h:
     29        (JSC::isCanonicalNumericIndexString):
     30
    1312019-05-03  Yusuke Suzuki  <ysuzuki@apple.com>
    232
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r244816 r244950  
    16701670                BC3046070E1F497F003232CF /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; settings = {ATTRIBUTES = (Private, ); }; };
    16711671                BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
    1672                 BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; };
     1672                BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
    16731673                BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC87CDB810712ACA000614CF /* JSONObject.lut.h */; };
    16741674                BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9041470EB9250900FE26FA /* StructureTransitionTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
  • trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h

    r244816 r244950  
    11/*
    2  * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    353353
    354354        if (thisObject->canGetIndexQuickly(index.value())) {
    355             slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly, thisObject->getIndexQuickly(index.value()));
     355            slot.setValue(thisObject, static_cast<unsigned>(PropertyAttribute::DontDelete), thisObject->getIndexQuickly(index.value()));
    356356            return true;
    357357        }
    358358
    359         slot.setValue(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly, jsUndefined());
    360         return false;
    361     }
    362    
     359        return false;
     360    }
     361
     362    if (isCanonicalNumericIndexString(propertyName)) {
     363        if (thisObject->isNeutered()) {
     364            slot.setCustom(thisObject, static_cast<unsigned>(PropertyAttribute::None), throwNeuteredTypedArrayTypeError);
     365            return true;
     366        }
     367
     368        return false;
     369    }
     370
    363371    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
    364372}
     
    369377    PutPropertySlot& slot)
    370378{
     379    VM& vm = exec->vm();
     380    auto scope = DECLARE_THROW_SCOPE(vm);
     381
    371382    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(cell);
    372383
     
    375386    // 9.4.5.5-2-b-i Return ? IntegerIndexedElementSet(O, numericIndex, V).
    376387    if (Optional<uint32_t> index = parseIndex(propertyName))
    377         return putByIndex(thisObject, exec, index.value(), value, slot.isStrictMode());
    378    
    379     return Base::put(thisObject, exec, propertyName, value, slot);
     388        RELEASE_AND_RETURN(scope, putByIndex(thisObject, exec, index.value(), value, slot.isStrictMode()));
     389
     390    if (isCanonicalNumericIndexString(propertyName)) {
     391        if (thisObject->isNeutered())
     392            throwTypeError(exec, scope, typedArrayBufferHasBeenDetachedErrorMessage);
     393        return false;
     394    }
     395
     396    RELEASE_AND_RETURN(scope, Base::put(thisObject, exec, propertyName, value, slot));
    380397}
    381398
     
    396413        };
    397414
     415        if (index.value() >= thisObject->m_length)
     416            return false;
     417
    398418        if (descriptor.isAccessorDescriptor())
    399419            return throwTypeErrorIfNeeded("Attempting to store accessor property on a typed array at index: ");
     
    405425            return throwTypeErrorIfNeeded("Attempting to store non-enumerable or non-writable property on a typed array at index: ");
    406426
    407         if (descriptor.value()) {
    408             PutPropertySlot unused(JSValue(thisObject), shouldThrow);
    409             RELEASE_AND_RETURN(scope, thisObject->put(thisObject, exec, propertyName, descriptor.value(), unused));
    410         }
    411         return true;
    412     }
    413    
     427        if (descriptor.value())
     428            RELEASE_AND_RETURN(scope, thisObject->putByIndex(thisObject, exec, index.value(), descriptor.value(), shouldThrow));
     429
     430        return true;
     431    }
     432
     433    if (isCanonicalNumericIndexString(propertyName))
     434        return false;
     435
    414436    RELEASE_AND_RETURN(scope, Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow));
    415437}
     
    434456template<typename Adaptor>
    435457bool JSGenericTypedArrayView<Adaptor>::getOwnPropertySlotByIndex(
    436     JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
     458    JSObject* object, ExecState*, unsigned propertyName, PropertySlot& slot)
    437459{
    438460    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object);
     
    443465    }
    444466
    445     if (propertyName > MAX_ARRAY_INDEX) {
    446         return thisObject->methodTable(exec->vm())->getOwnPropertySlot(
    447             thisObject, exec, Identifier::from(exec, propertyName), slot);
    448     }
    449    
    450467    if (!thisObject->canGetIndexQuickly(propertyName))
    451468        return false;
     
    457474template<typename Adaptor>
    458475bool JSGenericTypedArrayView<Adaptor>::putByIndex(
    459     JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
     476    JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)
    460477{
    461478    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(cell);
    462 
    463     if (propertyName > MAX_ARRAY_INDEX) {
    464         PutPropertySlot slot(JSValue(thisObject), shouldThrow);
    465         return thisObject->methodTable(exec->vm())->put(thisObject, exec, Identifier::from(exec, propertyName), value, slot);
    466     }
    467    
    468479    return thisObject->setIndex(exec, propertyName, value);
    469480}
  • trunk/Source/JavaScriptCore/runtime/PropertyName.h

    r244816 r244950  
    2727
    2828#include "Identifier.h"
     29#include "JSGlobalObjectFunctions.h"
    2930#include "PrivateName.h"
    3031#include <wtf/Optional.h>
     32#include <wtf/dtoa.h>
    3133
    3234namespace JSC {
     
    131133}
    132134
     135// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-canonicalnumericindexstring
     136ALWAYS_INLINE bool isCanonicalNumericIndexString(const PropertyName& propertyName)
     137{
     138    StringImpl* property = propertyName.uid();
     139    if (!property)
     140        return false;
     141    if (property->isSymbol())
     142        return false;
     143    if (equal(property, "-0"))
     144        return true;
     145    double index = jsToNumber(property);
     146    NumberToStringBuffer buffer;
     147    const char* indexString = WTF::numberToString(index, buffer);
     148    if (!equal(property, indexString))
     149        return false;
     150    return true;
     151}
     152
    133153} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.