diff --git a/encoding/ghtml/ghtml.go b/encoding/ghtml/ghtml.go index da0b798cd..34fa027aa 100644 --- a/encoding/ghtml/ghtml.go +++ b/encoding/ghtml/ghtml.go @@ -12,6 +12,8 @@ import ( "reflect" "strings" + "github.com/gogf/gf/v2/errors/gcode" + "github.com/gogf/gf/v2/errors/gerror" strip "github.com/grokify/html-strip-tags-go" ) @@ -60,15 +62,26 @@ func SpecialCharsDecode(s string) string { } // SpecialCharsMapOrStruct automatically encodes string values/attributes for map/struct. +// +// Note that, if operation on struct, the given parameter `mapOrStruct` should be type of pointer to struct. +// +// For example: +// var m = map{} +// var s = struct{}{} +// OK: SpecialCharsMapOrStruct(m) +// OK: SpecialCharsMapOrStruct(&s) +// Error: SpecialCharsMapOrStruct(s) func SpecialCharsMapOrStruct(mapOrStruct interface{}) error { var ( reflectValue = reflect.ValueOf(mapOrStruct) reflectKind = reflectValue.Kind() + originalKind = reflectKind ) for reflectValue.IsValid() && (reflectKind == reflect.Ptr || reflectKind == reflect.Interface) { reflectValue = reflectValue.Elem() reflectKind = reflectValue.Kind() } + switch reflectKind { case reflect.Map: var ( @@ -82,22 +95,43 @@ func SpecialCharsMapOrStruct(mapOrStruct interface{}) error { reflectValue.SetMapIndex(key, reflect.ValueOf(SpecialChars(mapValue.String()))) case reflect.Interface: if mapValue.Elem().Kind() == reflect.String { - reflectValue.SetMapIndex(key, reflect.ValueOf(SpecialChars(mapValue.Elem().String()))) + reflectValue.SetMapIndex( + key, + reflect.ValueOf(SpecialChars(mapValue.Elem().String())), + ) } + default: } } case reflect.Struct: - var ( - fieldValue reflect.Value - ) + if originalKind != reflect.Ptr { + return gerror.NewCodef( + gcode.CodeInvalidParameter, + `invalid input parameter type "%s", should be type of pointer to struct`, + reflect.TypeOf(mapOrStruct).String(), + ) + } + var fieldValue reflect.Value for i := 0; i < reflectValue.NumField(); i++ { fieldValue = reflectValue.Field(i) switch fieldValue.Kind() { case reflect.String: - fieldValue.Set(reflect.ValueOf(SpecialChars(fieldValue.String()))) + fieldValue.Set( + reflect.ValueOf( + SpecialChars(fieldValue.String()), + ), + ) + default: } } + + default: + return gerror.NewCodef( + gcode.CodeInvalidParameter, + `invalid input parameter type "%s"`, + reflect.TypeOf(mapOrStruct).String(), + ) } return nil } diff --git a/encoding/ghtml/ghtml_z_unit_test.go b/encoding/ghtml/ghtml_z_unit_test.go index 8ac444753..41b06912d 100644 --- a/encoding/ghtml/ghtml_z_unit_test.go +++ b/encoding/ghtml/ghtml_z_unit_test.go @@ -78,4 +78,14 @@ func Test_SpecialCharsMapOrStruct_Struct(t *testing.T) { t.Assert(a.Title, `<h1>T</h1>`) t.Assert(a.Content, `<div>C</div>`) }) + + // should error + gtest.C(t, func(t *gtest.T) { + a := A{ + Title: "

T

", + Content: "
C
", + } + err := ghtml.SpecialCharsMapOrStruct(a) + t.AssertNE(err, nil) + }) }