Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature suggestion: add new option disallow_duplicate_fields #375

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

peterzeller
Copy link

@peterzeller peterzeller commented Jul 27, 2022

This option makes unmarshalling return an error if a field appears in the json more than once.

This option can be useful as a precaution against JSON Interoperability Vulnerabilities, see for example "Inconsistent Duplicate Key Precedence" in https://bishopfox.com/blog/json-interoperability-vulnerabilities

Also, a similar option is planned for the Golang standard library: golang/go#48298

For reference, here is the generated code with the option:

// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.

package tests

import (
	json "encoding/json"
	fmt "fmt"
	easyjson "github.com/mailru/easyjson"
	jlexer "github.com/mailru/easyjson/jlexer"
	jwriter "github.com/mailru/easyjson/jwriter"
)

// suppress unused package warning
var (
	_ *json.RawMessage
	_ *jlexer.Lexer
	_ *jwriter.Writer
	_ easyjson.Marshaler
)

func easyjson4f43fa15DecodeGithubComMailruEasyjsonTests(in *jlexer.Lexer, out *Dupl) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	var ASet bool
	var BSet bool
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeFieldName(false)
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "a":
			if ASet {
				in.AddError(fmt.Errorf("duplicate field A"))
			}
			out.A = int(in.Int())
			ASet = true
		case "b":
			if BSet {
				in.AddError(fmt.Errorf("duplicate field B"))
			}
			out.B = int(in.Int())
			BSet = true
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjson4f43fa15EncodeGithubComMailruEasyjsonTests(out *jwriter.Writer, in Dupl) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"a\":"
		out.RawString(prefix[1:])
		out.Int(int(in.A))
	}
	{
		const prefix string = ",\"b\":"
		out.RawString(prefix)
		out.Int(int(in.B))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v Dupl) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjson4f43fa15EncodeGithubComMailruEasyjsonTests(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v Dupl) MarshalEasyJSON(w *jwriter.Writer) {
	easyjson4f43fa15EncodeGithubComMailruEasyjsonTests(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *Dupl) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjson4f43fa15DecodeGithubComMailruEasyjsonTests(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *Dupl) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjson4f43fa15DecodeGithubComMailruEasyjsonTests(l, v)
}

This option makes unmarshalling return an error if a field appears in the json more than once.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant