Skip to content

Commit 0e1cb15

Browse files
authored
fix(os/gstructs): strip tag options in TagPriorityName to avoid field name pollution (gogf#4681)
## Summary - Fix `TagPriorityName()` to strip comma-separated tag options (e.g., `omitempty`) from tag values - Before: `json:"user_name,omitempty"` → field name = `user_name,omitempty` - After: `json:"user_name,omitempty"` → field name = `user_name` - Aligns with `structcache.genPriorityTagAndFieldName()` which already handles this correctly - When tag name is empty (e.g., `gconv:",omitempty"`), continues to next priority tag instead of breaking ## Test plan - [x] Reproduced bug: `RuleFuncInput.Field` was `user_name,omitempty` instead of `user_name` - [x] Verified fix: field name correctly extracted as `user_name` - [x] Verified fallthrough: `gconv:",omitempty"` + `json:"name"` → uses `name` - [x] Existing `Test_Fields_TagPriorityName` passes - [x] Full `os/gstructs` test suite passes - [x] Full `util/gvalid` test suite passes - [x] Full `util/gconv` test suite passes closes gogf#4665
1 parent 612e545 commit 0e1cb15

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

os/gstructs/gstructs_field_tag.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ func (f *Field) TagPriorityName() string {
101101
name := f.Name()
102102
for _, tagName := range gtag.StructTagPriority {
103103
if tagValue := f.Tag(tagName); tagValue != "" {
104-
name = tagValue
105-
break
104+
// Strip tag options after comma, e.g., json:"name,omitempty" -> "name".
105+
tagValue = strings.Split(tagValue, ",")[0]
106+
if tagValue != "" {
107+
name = tagValue
108+
break
109+
}
106110
}
107111
}
108112
return name

os/gstructs/gstructs_z_unit_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,4 +546,32 @@ func Test_Fields_TagPriorityName(t *testing.T) {
546546
t.Assert(fields[2].TagPriorityName(), "pass_json")
547547
t.Assert(fields[3].TagPriorityName(), "IsMen")
548548
})
549+
// Tag with omitempty option should return name only, not "name,omitempty".
550+
gtest.C(t, func(t *gtest.T) {
551+
type User struct {
552+
Name string `json:"user_name,omitempty"`
553+
Age uint `gconv:"age,string" json:"age_json"`
554+
}
555+
var user *User
556+
fields, _ := gstructs.Fields(gstructs.FieldsInput{
557+
Pointer: user,
558+
RecursiveOption: 0,
559+
})
560+
t.Assert(fields[0].TagPriorityName(), "user_name")
561+
t.Assert(fields[1].TagPriorityName(), "age")
562+
})
563+
// Empty tag name with options (e.g., gconv:",omitempty") should fallthrough to next priority tag.
564+
gtest.C(t, func(t *gtest.T) {
565+
type User struct {
566+
Name string `gconv:",omitempty" json:"name_json"`
567+
Age uint `gconv:",string" param:",omitempty" json:"age_json"`
568+
}
569+
var user *User
570+
fields, _ := gstructs.Fields(gstructs.FieldsInput{
571+
Pointer: user,
572+
RecursiveOption: 0,
573+
})
574+
t.Assert(fields[0].TagPriorityName(), "name_json")
575+
t.Assert(fields[1].TagPriorityName(), "age_json")
576+
})
549577
}

0 commit comments

Comments
 (0)