diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go index 3c20e09..95e5d1e 100644 --- a/bootstrap/bootstrap.go +++ b/bootstrap/bootstrap.go @@ -22,10 +22,11 @@ type Generator struct { PkgPath, PkgName string Types []string - NoStdMarshalers bool - SnakeCase bool - LowerCamelCase bool - OmitEmpty bool + NoStdMarshalers bool + SnakeCase bool + LowerCamelCase bool + OmitEmpty bool + DisallowUnknownFields bool OutName string BuildTags string @@ -120,6 +121,9 @@ func (g *Generator) writeMain() (path string, err error) { if g.NoStdMarshalers { fmt.Fprintln(f, " g.NoStdMarshalers()") } + if g.DisallowUnknownFields { + fmt.Fprintln(f, " g.DisallowUnknownFields()") + } sort.Strings(g.Types) for _, v := range g.Types { diff --git a/easyjson/main.go b/easyjson/main.go index 1cd30bb..df180ea 100644 --- a/easyjson/main.go +++ b/easyjson/main.go @@ -27,6 +27,7 @@ var stubs = flag.Bool("stubs", false, "only generate stubs for marshaler/unmarsh var noformat = flag.Bool("noformat", false, "do not run 'gofmt -w' on output file") var specifiedName = flag.String("output_filename", "", "specify the filename of the output") var processPkg = flag.Bool("pkg", false, "process the whole package instead of just the given file") +var disallowUnknownFields = flag.Bool("disallow_unknown_fields", false, "return error if any unknown field in json found") func generate(fname string) (err error) { fInfo, err := os.Stat(fname) @@ -60,18 +61,19 @@ func generate(fname string) (err error) { } g := bootstrap.Generator{ - BuildTags: trimmedBuildTags, - PkgPath: p.PkgPath, - PkgName: p.PkgName, - Types: p.StructNames, - SnakeCase: *snakeCase, - LowerCamelCase: *lowerCamelCase, - NoStdMarshalers: *noStdMarshalers, - OmitEmpty: *omitEmpty, - LeaveTemps: *leaveTemps, - OutName: outName, - StubsOnly: *stubs, - NoFormat: *noformat, + BuildTags: trimmedBuildTags, + PkgPath: p.PkgPath, + PkgName: p.PkgName, + Types: p.StructNames, + SnakeCase: *snakeCase, + LowerCamelCase: *lowerCamelCase, + NoStdMarshalers: *noStdMarshalers, + DisallowUnknownFields: *disallowUnknownFields, + OmitEmpty: *omitEmpty, + LeaveTemps: *leaveTemps, + OutName: outName, + StubsOnly: *stubs, + NoFormat: *noformat, } if err := g.Run(); err != nil { diff --git a/gen/decoder.go b/gen/decoder.go index 3c8f8f8..5dc1249 100644 --- a/gen/decoder.go +++ b/gen/decoder.go @@ -461,7 +461,15 @@ func (g *Generator) genStructDecoder(t reflect.Type) error { } fmt.Fprintln(g.out, " default:") - fmt.Fprintln(g.out, " in.SkipRecursive()") + if g.disallowUnknownFields { + fmt.Fprintln(g.out, ` in.AddError(&jlexer.LexerError{ + Offset: in.GetPos(), + Reason: "unknown field", + Data: key, + })`) + } else { + fmt.Fprintln(g.out, " in.SkipRecursive()") + } fmt.Fprintln(g.out, " }") fmt.Fprintln(g.out, " in.WantComma()") fmt.Fprintln(g.out, " }") diff --git a/gen/generator.go b/gen/generator.go index 4f1eb04..a34a852 100644 --- a/gen/generator.go +++ b/gen/generator.go @@ -33,9 +33,10 @@ type Generator struct { varCounter int - noStdMarshalers bool - omitEmpty bool - fieldNamer FieldNamer + noStdMarshalers bool + omitEmpty bool + disallowUnknownFields bool + fieldNamer FieldNamer // package path to local alias map for tracking imports imports map[string]string @@ -110,6 +111,11 @@ func (g *Generator) NoStdMarshalers() { g.noStdMarshalers = true } +// DisallowUnknownFields instructs not to skip unknown fields in json and return error. +func (g *Generator) DisallowUnknownFields() { + g.disallowUnknownFields = true +} + // OmitEmpty triggers `json=",omitempty"` behaviour by default. func (g *Generator) OmitEmpty() { g.omitEmpty = true