Bug 171606 - getOwnPropertyDescriptor on an indexed property for a typed array is wrong
Summary: getOwnPropertyDescriptor on an indexed property for a typed array is wrong
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-03 11:03 PDT by Saam Barati
Modified: 2017-05-03 11:07 PDT (History)
11 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Saam Barati 2017-05-03 11:03:03 PDT
e.g:
```
let x = new Uint8Array
Object.getOwnPropertyDescriptor(x, "0").writable === false
```
but it should === true.
Comment 1 Saam Barati 2017-05-03 11:03:27 PDT
I think the fix is trivial:
```
template<typename Adaptor>
bool JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot(
    JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object);

    if (std::optional<uint32_t> index = parseIndex(propertyName)) {
        if (thisObject->isNeutered()) {
            slot.setCustom(thisObject, None, throwNeuteredTypedArrayTypeError);
            return true;
        }

        if (thisObject->canGetIndexQuickly(index.value()))
            slot.setValue(thisObject, DontDelete | ReadOnly, thisObject->getIndexQuickly(index.value()));
        else
            slot.setValue(thisObject, DontDelete | ReadOnly, jsUndefined());
        return true;
    }
    
    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}
```
should not say ReadOnly.
Comment 2 Saam Barati 2017-05-03 11:04:56 PDT
(In reply to Saam Barati from comment #1)
> I think the fix is trivial:
> ```
> template<typename Adaptor>
> bool JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot(
>     JSObject* object, ExecState* exec, PropertyName propertyName,
> PropertySlot& slot)
> {
>     JSGenericTypedArrayView* thisObject =
> jsCast<JSGenericTypedArrayView*>(object);
> 
>     if (std::optional<uint32_t> index = parseIndex(propertyName)) {
>         if (thisObject->isNeutered()) {
>             slot.setCustom(thisObject, None,
> throwNeuteredTypedArrayTypeError);
>             return true;
>         }
> 
>         if (thisObject->canGetIndexQuickly(index.value()))
>             slot.setValue(thisObject, DontDelete | ReadOnly,
> thisObject->getIndexQuickly(index.value()));
>         else
>             slot.setValue(thisObject, DontDelete | ReadOnly, jsUndefined());
This part here is also wrong. If the index is >= our length, we don't have the property, and thus, should return false.
>         return true;
>     }
>     
>     return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
> }
> ```
> should not say ReadOnly.
Comment 3 Saam Barati 2017-05-03 11:05:58 PDT
This will lead to code like this which is also wrong:
```
>>> let x = new Uint8Array
>>> JSON.stringify(Object.getOwnPropertyDescriptor(x, "5"))
{"writable":false,"enumerable":true,"configurable":false}
```
Comment 4 Saam Barati 2017-05-03 11:07:07 PDT
I would bet that this is tested by test262.