Browse Source

Fixed exporting of typed arrays and DataView into []byte so that it respects the offset and length.

Dmitry Panov 2 months ago
parent
commit
cf18d89f3c
2 changed files with 45 additions and 2 deletions
  1. 43 0
      builtin_typedarrays_test.go
  2. 2 2
      typedarrays.go

+ 43 - 0
builtin_typedarrays_test.go

@@ -1,6 +1,7 @@
 package goja
 package goja
 
 
 import (
 import (
+	"bytes"
 	"testing"
 	"testing"
 )
 )
 
 
@@ -324,3 +325,45 @@ func TestTypedArrayDeleteUnconfigurable(t *testing.T) {
 
 
 	testScript(SCRIPT, _undefined, t)
 	testScript(SCRIPT, _undefined, t)
 }
 }
+
+func TestTypedArrayExportToBytes(t *testing.T) {
+	const SCRIPT = `
+	const arr = new Uint16Array(10);
+	arr[2] = 0xFFFF; // make sure it's not affected by the platform endianness
+	arr.subarray(2, 4);
+	`
+	vm := New()
+	v, err := vm.RunString(SCRIPT)
+	if err != nil {
+		t.Fatal(err)
+	}
+	var b []byte
+	err = vm.ExportTo(v, &b)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(b, []byte{0xFF, 0xFF, 0, 0}) {
+		t.Fatal("unexpected value", b)
+	}
+}
+
+func TestDataViewExportToBytes(t *testing.T) {
+	const SCRIPT = `
+	const arr = new Uint16Array(10);
+	arr[2] = 0xFFFF;
+	new DataView(arr.buffer, 4, 4);
+	`
+	vm := New()
+	v, err := vm.RunString(SCRIPT)
+	if err != nil {
+		t.Fatal(err)
+	}
+	var b []byte
+	err = vm.ExportTo(v, &b)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(b, []byte{0xFF, 0xFF, 0, 0}) {
+		t.Fatal("unexpected value", b)
+	}
+}

+ 2 - 2
typedarrays.go

@@ -994,7 +994,7 @@ func (a *typedArrayObject) iterateStringKeys() iterNextFunc {
 
 
 func (a *typedArrayObject) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
 func (a *typedArrayObject) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
 	if typ == typeBytes {
 	if typ == typeBytes {
-		dst.Set(reflect.ValueOf(a.viewedArrayBuf.data))
+		dst.Set(reflect.ValueOf(a.viewedArrayBuf.data[a.offset*a.elemSize : (a.offset+a.length)*a.elemSize]))
 		return nil
 		return nil
 	}
 	}
 	return a.baseObject.exportToArrayOrSlice(dst, typ, ctx)
 	return a.baseObject.exportToArrayOrSlice(dst, typ, ctx)
@@ -1010,7 +1010,7 @@ func (a *typedArrayObject) exportType() reflect.Type {
 
 
 func (o *dataViewObject) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
 func (o *dataViewObject) exportToArrayOrSlice(dst reflect.Value, typ reflect.Type, ctx *objectExportCtx) error {
 	if typ == typeBytes {
 	if typ == typeBytes {
-		dst.Set(reflect.ValueOf(o.viewedArrayBuf.data))
+		dst.Set(reflect.ValueOf(o.viewedArrayBuf.data[o.byteOffset : o.byteOffset+o.byteLen]))
 		return nil
 		return nil
 	}
 	}
 	return o.baseObject.exportToArrayOrSlice(dst, typ, ctx)
 	return o.baseObject.exportToArrayOrSlice(dst, typ, ctx)