Skip to content

Commit

Permalink
More typed arrays fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
dop251 committed Jul 26, 2021
1 parent ebe1101 commit a55e4cf
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 48 deletions.
26 changes: 0 additions & 26 deletions builtin_typedarrays_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
35 changes: 14 additions & 21 deletions typedarrays.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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
}
Expand Down
65 changes: 64 additions & 1 deletion typedarrays_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}

0 comments on commit a55e4cf

Please sign in to comment.