Skip to content

Commit

Permalink
Removed erroneous IsExported() calls, because these are js names whic…
Browse files Browse the repository at this point in the history
…h may be mapped. Closes dop251#114
  • Loading branch information
dop251 committed Sep 12, 2019
1 parent bb8ee19 commit aa89e6a
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 25 deletions.
41 changes: 18 additions & 23 deletions object_goreflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type FieldNameMapper interface {
// If this method returns "" the field becomes hidden.
FieldName(t reflect.Type, f reflect.StructField) string

// FieldName returns a JavaScript name for the given method in the given type.
// MethodName returns a JavaScript name for the given method in the given type.
// If this method returns "" the method becomes hidden.
MethodName(t reflect.Type, m reflect.Method) string
}
Expand Down Expand Up @@ -216,35 +216,30 @@ func (r *Runtime) checkHostObjectPropertyDescr(name string, descr propertyDescr,
}

func (o *objectGoReflect) defineOwnProperty(n Value, descr propertyDescr, throw bool) bool {
name := n.String()
if ast.IsExported(name) {
if o.value.Kind() == reflect.Struct {
if v := o._getField(name); v.IsValid() {
if !o.val.runtime.checkHostObjectPropertyDescr(name, descr, throw) {
return false
}
val := descr.Value
if val == nil {
val = _undefined
}
vv, err := o.val.runtime.toReflectValue(val, v.Type())
if err != nil {
o.val.runtime.typeErrorResult(throw, "Go struct conversion error: %v", err)
return false
}
v.Set(vv)
return true
if o.value.Kind() == reflect.Struct {
name := n.String()
if v := o._getField(name); v.IsValid() {
if !o.val.runtime.checkHostObjectPropertyDescr(name, descr, throw) {
return false
}
val := descr.Value
if val == nil {
val = _undefined
}
vv, err := o.val.runtime.toReflectValue(val, v.Type())
if err != nil {
o.val.runtime.typeErrorResult(throw, "Go struct conversion error: %v", err)
return false
}
v.Set(vv)
return true
}
}

return o.baseObject.defineOwnProperty(n, descr, throw)
}

func (o *objectGoReflect) _has(name string) bool {
if !ast.IsExported(name) {
return false
}
if o.value.Kind() == reflect.Struct {
if v := o._getField(name); v.IsValid() {
return true
Expand Down Expand Up @@ -508,7 +503,7 @@ func (r *Runtime) typeInfo(t reflect.Type) (info *reflectTypeInfo) {
return
}

// Sets a custom field name mapper for Go types. It can be called at any time, however
// SetFieldNameMapper sets a custom field name mapper for Go types. It can be called at any time, however
// the mapping for any given value is fixed at the point of creation.
// Setting this to nil restores the default behaviour which is all exported fields and methods are mapped to their
// original unchanged names.
Expand Down
67 changes: 65 additions & 2 deletions object_goreflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,14 +487,14 @@ func TestGoReflectEmbeddedStruct(t *testing.T) {

type jsonTagNamer struct{}

func (*jsonTagNamer) FieldName(t reflect.Type, field reflect.StructField) string {
func (jsonTagNamer) FieldName(t reflect.Type, field reflect.StructField) string {
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
return jsonTag
}
return field.Name
}

func (*jsonTagNamer) MethodName(t reflect.Type, method reflect.Method) string {
func (jsonTagNamer) MethodName(t reflect.Type, method reflect.Method) string {
return method.Name
}

Expand Down Expand Up @@ -729,6 +729,69 @@ func TestFieldOverriding(t *testing.T) {
}
}

func TestDefinePropertyUnexportedJsName(t *testing.T) {
type T struct {
Field int
unexported int
}

vm := New()
vm.SetFieldNameMapper(fieldNameMapper1{})
vm.Set("f", &T{})

_, err := vm.RunString(`
"use strict";
Object.defineProperty(f, "field", {value: 42});
if (f.field !== 42) {
throw new Error("Unexpected value: " + f.field);
}
if (f.hasOwnProperty("unexported")) {
throw new Error("hasOwnProporty('unexported') is true");
}
var thrown;
try {
Object.defineProperty(f, "unexported", {value: 1});
} catch (e) {
thrown = e;
}
if (!(thrown instanceof TypeError)) {
throw new Error("Unexpected error: ", thrown);
}
`)
if err != nil {
t.Fatal(err)
}
}

type fieldNameMapperToLower struct{}

func (fieldNameMapperToLower) FieldName(t reflect.Type, f reflect.StructField) string {
return strings.ToLower(f.Name)
}

func (fieldNameMapperToLower) MethodName(t reflect.Type, m reflect.Method) string {
return strings.ToLower(m.Name)
}

func TestHasOwnPropertyUnexportedJsName(t *testing.T) {
vm := New()
vm.SetFieldNameMapper(fieldNameMapperToLower{})
vm.Set("f", &testGoReflectMethod_O{})

_, err := vm.RunString(`
"use strict";
if (!f.hasOwnProperty("test")) {
throw new Error("hasOwnProperty('test') returned false");
}
if (!f.hasOwnProperty("method")) {
throw new Error("hasOwnProperty('method') returned false");
}
`)
if err != nil {
t.Fatal(err)
}
}

func BenchmarkGoReflectGet(b *testing.B) {
type parent struct {
field, Test1, Test2, Test3, Test4, Test5, Test string
Expand Down

0 comments on commit aa89e6a

Please sign in to comment.