1
0
mirror of https://github.com/golang/go synced 2024-11-05 17:36:15 -07:00

cmd/vet: check for use of json/xml struct tags with unexported fields

This is a common source of bugs, particularly for those new to Go. Running this on a corpus of public code flagged 114 instances.

This check may need to be updated once issue 7363 is resolved.

LGTM=r
R=golang-codereviews, r
CC=bradfitz, golang-codereviews
https://golang.org/cl/91010047
This commit is contained in:
Josh Bleecher Snyder 2014-06-13 18:44:31 -07:00
parent de23e2b0c2
commit d46b792624
3 changed files with 37 additions and 2 deletions

View File

@ -72,6 +72,7 @@ Struct tags
Flag: -structtags
Struct tags that do not follow the format understood by reflect.StructTag.Get.
Well-known encoding struct tags (json, xml) used with unexported fields.
Unkeyed composite literals

View File

@ -14,7 +14,7 @@ import (
func init() {
register("structtags",
"check that struct field tags have canonical format",
"check that struct field tags have canonical format and apply to exported fields as needed",
checkCanonicalFieldTag,
field)
}
@ -35,8 +35,28 @@ func checkCanonicalFieldTag(f *File, node ast.Node) {
// Check tag for validity by appending
// new key:value to end and checking that
// the tag parsing code can find it.
if reflect.StructTag(tag+` _gofix:"_magic"`).Get("_gofix") != "_magic" {
st := reflect.StructTag(tag + ` _gofix:"_magic"`)
if st.Get("_gofix") != "_magic" {
f.Badf(field.Pos(), "struct field tag %s not compatible with reflect.StructTag.Get", field.Tag.Value)
return
}
// Check for use of json or xml tags with unexported fields.
// Embedded struct. Nothing to do for now, but that
// may change, depending on what happens with issue 7363.
if len(field.Names) == 0 {
return
}
if field.Names[0].IsExported() {
return
}
for _, enc := range [...]string{"json", "xml"} {
if st.Get(enc) != "" {
f.Badf(field.Pos(), "struct field %s has %s tag but is not exported", field.Names[0].Name, enc)
return
}
}
}

View File

@ -11,3 +11,17 @@ package testdata
type StructTagTest struct {
X int "hello" // ERROR "not compatible with reflect.StructTag.Get"
}
type UnexportedEncodingTagTest struct {
x int `json:"xx"` // ERROR "struct field x has json tag but is not exported"
y int `xml:"yy"` // ERROR "struct field y has xml tag but is not exported"
z int
A int `json:"aa" xml:"bb"`
}
type unexp struct{}
type JSONEmbeddedField struct {
UnexportedEncodingTagTest `is:"embedded"`
unexp `is:"embedded,notexported" json:"unexp"` // OK for now, see issue 7363
}