Bug 171606
| Summary: | getOwnPropertyDescriptor on an indexed property for a typed array is wrong | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Saam Barati <saam> |
| Component: | JavaScriptCore | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW | ||
| Severity: | Normal | CC: | benjamin, fpizlo, ggaren, gskachkov, jfbastien, joepeck, keith_miller, mark.lam, msaboff, ticaiolima, ysuzuki |
| Priority: | P2 | ||
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
Saam Barati
e.g:
```
let x = new Uint8Array
Object.getOwnPropertyDescriptor(x, "0").writable === false
```
but it should === true.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Saam Barati
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.
Saam Barati
(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.
Saam Barati
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}
```
Saam Barati
I would bet that this is tested by test262.