From 9cf7f406dbb7d0c438530c6a3bf2f0a01bfe5c1e Mon Sep 17 00:00:00 2001 From: Dmitry Panov Date: Mon, 26 Jul 2021 23:46:56 +0100 Subject: [PATCH] More typed arrays fixes Signed-off-by: Gabri --- builtin_typedarrays_test.go | 26 --------------- typedarrays.go | 35 ++++++++------------ typedarrays_test.go | 65 ++++++++++++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 48 deletions(-) diff --git a/builtin_typedarrays_test.go b/builtin_typedarrays_test.go index cadc2be2..27ad2326 100644 --- a/builtin_typedarrays_test.go +++ b/builtin_typedarrays_test.go @@ -304,29 +304,3 @@ func TestInt32ArrayNegativeIndex(t *testing.T) { testScript1(SCRIPT, valueTrue, t) } - -func TestTypedArrayDefineProperty(t *testing.T) { - const SCRIPT = ` - var sample = new Uint8Array([42, 42]); - - assert.sameValue( - Reflect.defineProperty(sample, "0", { - value: 8, - configurable: true, - enumerable: true, - writable: true - }), - true - ); - - assert.sameValue(sample[0], 8, "property value was set"); - let descriptor0 = Object.getOwnPropertyDescriptor(sample, "0"); - assert.sameValue(descriptor0.value, 8); - assert.sameValue(descriptor0.configurable, true, "configurable"); - assert.sameValue(descriptor0.enumerable, true); - assert.sameValue(descriptor0.writable, true); - - ` - - testScript1(TESTLIB+SCRIPT, _undefined, t) -} diff --git a/typedarrays.go b/typedarrays.go index a6cba761..63260726 100644 --- a/typedarrays.go +++ b/typedarrays.go @@ -502,20 +502,17 @@ func (a *typedArrayObject) getStr(name unistring.String, receiver Value) Value { } func (a *typedArrayObject) getIdx(idx valueInt, receiver Value) Value { - prop := a._getIdx(toIntClamp(int64(idx))) - if prop == nil { - if a.prototype != nil { - if receiver == nil { - return a.prototype.self.getIdx(idx, a.val) - } - return a.prototype.self.getIdx(idx, receiver) - } - } - return prop + return a._getIdx(toIntClamp(int64(idx))) } func (a *typedArrayObject) isValidIntegerIndex(idx int, throw bool) bool { - return a.viewedArrayBuf.ensureNotDetached(throw) && idx >= 0 && idx < a.length + if a.viewedArrayBuf.ensureNotDetached(throw) { + if idx >= 0 && idx < a.length { + return true + } + a.val.runtime.typeErrorResult(throw, "Invalid typed array index") + } + return false } func (a *typedArrayObject) _putIdx(idx int, v Value) { @@ -526,7 +523,7 @@ func (a *typedArrayObject) _putIdx(idx int, v Value) { } func (a *typedArrayObject) _hasIdx(idx int) bool { - return a.viewedArrayBuf.ensureNotDetached(false) && idx >= 0 && idx < a.length + return a.isValidIntegerIndex(idx, false) } func (a *typedArrayObject) setOwnStr(p unistring.String, v Value, throw bool) bool { @@ -558,7 +555,7 @@ func (a *typedArrayObject) setForeignIdx(p valueInt, v, receiver Value, throw bo func (a *typedArrayObject) hasOwnPropertyStr(name unistring.String) bool { idx, ok := strToIntNum(name) if ok { - return a.viewedArrayBuf.ensureNotDetached(false) && idx >= 0 && idx < a.length + return a._hasIdx(idx) } if idx == 0 { return false @@ -571,13 +568,8 @@ func (a *typedArrayObject) hasOwnPropertyIdx(idx valueInt) bool { } func (a *typedArrayObject) _defineIdxProperty(idx int, desc PropertyDescriptor, throw bool) bool { - if desc.Configurable == FLAG_FALSE || desc.Enumerable == FLAG_FALSE { - return false - } - if desc.IsAccessor() { - return false - } - if desc.Writable == FLAG_FALSE { + if desc.Configurable == FLAG_FALSE || desc.Enumerable == FLAG_FALSE || desc.IsAccessor() || desc.Writable == FLAG_FALSE { + a.val.runtime.typeErrorResult(throw, "Cannot redefine property: %d", idx) return false } _, ok := a._defineOwnProperty(unistring.String(strconv.Itoa(idx)), a.getOwnPropIdx(valueInt(idx)), desc, throw) @@ -598,6 +590,7 @@ func (a *typedArrayObject) defineOwnPropertyStr(name unistring.String, desc Prop } if idx == 0 { a.viewedArrayBuf.ensureNotDetached(throw) + a.val.runtime.typeErrorResult(throw, "Invalid typed array index") return false } return a.baseObject.defineOwnPropertyStr(name, desc, throw) @@ -610,7 +603,7 @@ func (a *typedArrayObject) defineOwnPropertyIdx(name valueInt, desc PropertyDesc func (a *typedArrayObject) deleteStr(name unistring.String, throw bool) bool { idx, ok := strToIntNum(name) if ok { - if a.viewedArrayBuf.ensureNotDetached(throw) && idx >= 0 && idx < a.length { + if !a.isValidIntegerIndex(idx, false) { a.val.runtime.typeErrorResult(throw, "Cannot delete property '%d' of %s", idx, a.val.String()) return false } diff --git a/typedarrays_test.go b/typedarrays_test.go index 57ed5a19..aa1ad1f0 100644 --- a/typedarrays_test.go +++ b/typedarrays_test.go @@ -170,7 +170,7 @@ func TestTypedArraySetDetachedBuffer(t *testing.T) { } } -func TestTypedArrayDefineDetachedBuffer(t *testing.T) { +func TestTypedArrayDefinePropDetachedBuffer(t *testing.T) { const SCRIPT = ` var desc = { value: 0, @@ -283,3 +283,66 @@ func TestTypedArrayDefineDetachedBuffer(t *testing.T) { t.Fatal(err) } } + +func TestTypedArrayDefineProperty(t *testing.T) { + const SCRIPT = ` + var a = new Uint8Array(1); + + assert.throws(TypeError, function() { + Object.defineProperty(a, "1", {value: 1}); + }); + assert.sameValue(Reflect.defineProperty(a, "1", {value: 1}), false, "1"); + + assert.throws(TypeError, function() { + Object.defineProperty(a, "Infinity", {value: 8}); + }); + assert.sameValue(Reflect.defineProperty(a, "Infinity", {value: 8}), false, "Infinity"); + + Object.defineProperty(a, "test", {value: "passed"}); + assert.sameValue(a.test, "passed", "string property"); + + assert.throws(TypeError, function() { + Object.defineProperty(a, "0", {value: 1, writable: false}); + }, "define non-writable"); + + assert.throws(TypeError, function() { + Object.defineProperty(a, "0", {get() { return 1; }}); + }, "define accessor"); + + var sample = new Uint8Array([42, 42]); + + assert.sameValue( + Reflect.defineProperty(sample, "0", { + value: 8, + configurable: true, + enumerable: true, + writable: true + }), + true + ); + + assert.sameValue(sample[0], 8, "property value was set"); + let descriptor0 = Object.getOwnPropertyDescriptor(sample, "0"); + assert.sameValue(descriptor0.value, 8); + assert.sameValue(descriptor0.configurable, true, "configurable"); + assert.sameValue(descriptor0.enumerable, true); + assert.sameValue(descriptor0.writable, true); + ` + testScript1(TESTLIB+SCRIPT, _undefined, t) +} + +func TestTypedArrayGetInvalidIndex(t *testing.T) { + const SCRIPT = ` + var TypedArray = Object.getPrototypeOf(Int8Array); + var proto = TypedArray.prototype; + Object.defineProperty(proto, "1", { + get: function() { + throw new Error("OrdinaryGet was called!"); + } + }); + var a = new Uint8Array(1); + assert.sameValue(a[1], undefined); + assert.sameValue(a["1"], undefined); + ` + testScript1(TESTLIB+SCRIPT, _undefined, t) +}