Skip to content

Commit

Permalink
Merge pull request #194 from evanphx/b-num-prec
Browse files Browse the repository at this point in the history
Always use UseNumber() to avoid float64 lossyness
  • Loading branch information
evanphx authored Jan 12, 2024
2 parents c32ee8f + 67afbf6 commit 850009d
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 19 deletions.
27 changes: 19 additions & 8 deletions v5/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ func MergePatch(docData, patchData []byte) ([]byte, error) {
func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
doc := &partialDoc{}

docErr := json.Unmarshal(docData, doc)
docErr := unmarshal(docData, doc)

patch := &partialDoc{}

patchErr := json.Unmarshal(patchData, patch)
patchErr := unmarshal(patchData, patch)

if isSyntaxError(docErr) {
return nil, errBadJSONDoc
Expand Down Expand Up @@ -151,7 +151,7 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
}
} else {
patchAry := &partialArray{}
patchErr = json.Unmarshal(patchData, patchAry)
patchErr = unmarshal(patchData, patchAry)

if patchErr != nil {
return nil, errBadJSONPatch
Expand Down Expand Up @@ -227,12 +227,12 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
originalDoc := map[string]interface{}{}
modifiedDoc := map[string]interface{}{}

err := json.Unmarshal(originalJSON, &originalDoc)
err := unmarshal(originalJSON, &originalDoc)
if err != nil {
return nil, errBadJSONDoc
}

err = json.Unmarshal(modifiedJSON, &modifiedDoc)
err = unmarshal(modifiedJSON, &modifiedDoc)
if err != nil {
return nil, errBadJSONDoc
}
Expand All @@ -245,6 +245,12 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
return json.Marshal(dest)
}

func unmarshal(data []byte, into interface{}) error {
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
return dec.Decode(into)
}

// createArrayMergePatch will return an array of merge-patch documents capable
// of converting the original document to the modified document for each
// pair of JSON documents provided in the arrays.
Expand All @@ -253,12 +259,12 @@ func createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
originalDocs := []json.RawMessage{}
modifiedDocs := []json.RawMessage{}

err := json.Unmarshal(originalJSON, &originalDocs)
err := unmarshal(originalJSON, &originalDocs)
if err != nil {
return nil, errBadJSONDoc
}

err = json.Unmarshal(modifiedJSON, &modifiedDocs)
err = unmarshal(modifiedJSON, &modifiedDocs)
if err != nil {
return nil, errBadJSONDoc
}
Expand Down Expand Up @@ -314,6 +320,11 @@ func matchesValue(av, bv interface{}) bool {
if bt == at {
return true
}
case json.Number:
bt := bv.(json.Number)
if bt == at {
return true
}
case float64:
bt := bv.(float64)
if bt == at {
Expand Down Expand Up @@ -377,7 +388,7 @@ func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) {
if len(dst) > 0 {
into[key] = dst
}
case string, float64, bool:
case string, float64, bool, json.Number:
if !matchesValue(av, bv) {
into[key] = bv
}
Expand Down
22 changes: 11 additions & 11 deletions v5/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (err *syntaxError) Error() string {
}

func (n *partialDoc) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &n.obj); err != nil {
if err := unmarshal(data, &n.obj); err != nil {
return err
}
buffer := bytes.NewBuffer(data)
Expand Down Expand Up @@ -252,7 +252,7 @@ func (n *lazyNode) intoDoc() (*partialDoc, error) {
return nil, ErrInvalid
}

err := json.Unmarshal(*n.raw, &n.doc)
err := unmarshal(*n.raw, &n.doc)

if err != nil {
return nil, err
Expand All @@ -271,7 +271,7 @@ func (n *lazyNode) intoAry() (*partialArray, error) {
return nil, ErrInvalid
}

err := json.Unmarshal(*n.raw, &n.ary)
err := unmarshal(*n.raw, &n.ary)

if err != nil {
return nil, err
Expand Down Expand Up @@ -302,7 +302,7 @@ func (n *lazyNode) tryDoc() bool {
return false
}

err := json.Unmarshal(*n.raw, &n.doc)
err := unmarshal(*n.raw, &n.doc)

if err != nil {
return false
Expand All @@ -317,7 +317,7 @@ func (n *lazyNode) tryAry() bool {
return false
}

err := json.Unmarshal(*n.raw, &n.ary)
err := unmarshal(*n.raw, &n.ary)

if err != nil {
return false
Expand Down Expand Up @@ -418,7 +418,7 @@ func (o Operation) Kind() string {
if obj, ok := o["op"]; ok && obj != nil {
var op string

err := json.Unmarshal(*obj, &op)
err := unmarshal(*obj, &op)

if err != nil {
return "unknown"
Expand All @@ -435,7 +435,7 @@ func (o Operation) Path() (string, error) {
if obj, ok := o["path"]; ok && obj != nil {
var op string

err := json.Unmarshal(*obj, &op)
err := unmarshal(*obj, &op)

if err != nil {
return "unknown", err
Expand All @@ -452,7 +452,7 @@ func (o Operation) From() (string, error) {
if obj, ok := o["from"]; ok && obj != nil {
var op string

err := json.Unmarshal(*obj, &op)
err := unmarshal(*obj, &op)

if err != nil {
return "unknown", err
Expand Down Expand Up @@ -481,7 +481,7 @@ func (o Operation) ValueInterface() (interface{}, error) {

var v interface{}

err := json.Unmarshal(*obj, &v)
err := unmarshal(*obj, &v)

if err != nil {
return nil, err
Expand Down Expand Up @@ -1099,7 +1099,7 @@ func Equal(a, b []byte) bool {
func DecodePatch(buf []byte) (Patch, error) {
var p Patch

err := json.Unmarshal(buf, &p)
err := unmarshal(buf, &p)

if err != nil {
return nil, err
Expand Down Expand Up @@ -1144,7 +1144,7 @@ func (p Patch) ApplyIndentWithOptions(doc []byte, indent string, options *ApplyO
pd = &partialDoc{}
}

err := json.Unmarshal(doc, pd)
err := unmarshal(doc, pd)

if err != nil {
return nil, err
Expand Down

0 comments on commit 850009d

Please sign in to comment.