Skip to content

Commit 67afbf6

Browse files
committed
Always use UseNumber() to avoid float64 lossyness
1 parent f72a464 commit 67afbf6

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

v5/merge.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ func MergePatch(docData, patchData []byte) ([]byte, error) {
119119
func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
120120
doc := &partialDoc{}
121121

122-
docErr := json.Unmarshal(docData, doc)
122+
docErr := unmarshal(docData, doc)
123123

124124
patch := &partialDoc{}
125125

126-
patchErr := json.Unmarshal(patchData, patch)
126+
patchErr := unmarshal(patchData, patch)
127127

128128
if isSyntaxError(docErr) {
129129
return nil, errBadJSONDoc
@@ -151,7 +151,7 @@ func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
151151
}
152152
} else {
153153
patchAry := &partialArray{}
154-
patchErr = json.Unmarshal(patchData, patchAry)
154+
patchErr = unmarshal(patchData, patchAry)
155155

156156
if patchErr != nil {
157157
return nil, errBadJSONPatch
@@ -227,12 +227,12 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
227227
originalDoc := map[string]interface{}{}
228228
modifiedDoc := map[string]interface{}{}
229229

230-
err := json.Unmarshal(originalJSON, &originalDoc)
230+
err := unmarshal(originalJSON, &originalDoc)
231231
if err != nil {
232232
return nil, errBadJSONDoc
233233
}
234234

235-
err = json.Unmarshal(modifiedJSON, &modifiedDoc)
235+
err = unmarshal(modifiedJSON, &modifiedDoc)
236236
if err != nil {
237237
return nil, errBadJSONDoc
238238
}
@@ -245,6 +245,12 @@ func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
245245
return json.Marshal(dest)
246246
}
247247

248+
func unmarshal(data []byte, into interface{}) error {
249+
dec := json.NewDecoder(bytes.NewReader(data))
250+
dec.UseNumber()
251+
return dec.Decode(into)
252+
}
253+
248254
// createArrayMergePatch will return an array of merge-patch documents capable
249255
// of converting the original document to the modified document for each
250256
// pair of JSON documents provided in the arrays.
@@ -253,12 +259,12 @@ func createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
253259
originalDocs := []json.RawMessage{}
254260
modifiedDocs := []json.RawMessage{}
255261

256-
err := json.Unmarshal(originalJSON, &originalDocs)
262+
err := unmarshal(originalJSON, &originalDocs)
257263
if err != nil {
258264
return nil, errBadJSONDoc
259265
}
260266

261-
err = json.Unmarshal(modifiedJSON, &modifiedDocs)
267+
err = unmarshal(modifiedJSON, &modifiedDocs)
262268
if err != nil {
263269
return nil, errBadJSONDoc
264270
}
@@ -314,6 +320,11 @@ func matchesValue(av, bv interface{}) bool {
314320
if bt == at {
315321
return true
316322
}
323+
case json.Number:
324+
bt := bv.(json.Number)
325+
if bt == at {
326+
return true
327+
}
317328
case float64:
318329
bt := bv.(float64)
319330
if bt == at {
@@ -377,7 +388,7 @@ func getDiff(a, b map[string]interface{}) (map[string]interface{}, error) {
377388
if len(dst) > 0 {
378389
into[key] = dst
379390
}
380-
case string, float64, bool:
391+
case string, float64, bool, json.Number:
381392
if !matchesValue(av, bv) {
382393
into[key] = bv
383394
}

v5/patch.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func (err *syntaxError) Error() string {
172172
}
173173

174174
func (n *partialDoc) UnmarshalJSON(data []byte) error {
175-
if err := json.Unmarshal(data, &n.obj); err != nil {
175+
if err := unmarshal(data, &n.obj); err != nil {
176176
return err
177177
}
178178
buffer := bytes.NewBuffer(data)
@@ -252,7 +252,7 @@ func (n *lazyNode) intoDoc() (*partialDoc, error) {
252252
return nil, ErrInvalid
253253
}
254254

255-
err := json.Unmarshal(*n.raw, &n.doc)
255+
err := unmarshal(*n.raw, &n.doc)
256256

257257
if err != nil {
258258
return nil, err
@@ -271,7 +271,7 @@ func (n *lazyNode) intoAry() (*partialArray, error) {
271271
return nil, ErrInvalid
272272
}
273273

274-
err := json.Unmarshal(*n.raw, &n.ary)
274+
err := unmarshal(*n.raw, &n.ary)
275275

276276
if err != nil {
277277
return nil, err
@@ -302,7 +302,7 @@ func (n *lazyNode) tryDoc() bool {
302302
return false
303303
}
304304

305-
err := json.Unmarshal(*n.raw, &n.doc)
305+
err := unmarshal(*n.raw, &n.doc)
306306

307307
if err != nil {
308308
return false
@@ -317,7 +317,7 @@ func (n *lazyNode) tryAry() bool {
317317
return false
318318
}
319319

320-
err := json.Unmarshal(*n.raw, &n.ary)
320+
err := unmarshal(*n.raw, &n.ary)
321321

322322
if err != nil {
323323
return false
@@ -398,7 +398,7 @@ func (o Operation) Kind() string {
398398
if obj, ok := o["op"]; ok && obj != nil {
399399
var op string
400400

401-
err := json.Unmarshal(*obj, &op)
401+
err := unmarshal(*obj, &op)
402402

403403
if err != nil {
404404
return "unknown"
@@ -415,7 +415,7 @@ func (o Operation) Path() (string, error) {
415415
if obj, ok := o["path"]; ok && obj != nil {
416416
var op string
417417

418-
err := json.Unmarshal(*obj, &op)
418+
err := unmarshal(*obj, &op)
419419

420420
if err != nil {
421421
return "unknown", err
@@ -432,7 +432,7 @@ func (o Operation) From() (string, error) {
432432
if obj, ok := o["from"]; ok && obj != nil {
433433
var op string
434434

435-
err := json.Unmarshal(*obj, &op)
435+
err := unmarshal(*obj, &op)
436436

437437
if err != nil {
438438
return "unknown", err
@@ -461,7 +461,7 @@ func (o Operation) ValueInterface() (interface{}, error) {
461461

462462
var v interface{}
463463

464-
err := json.Unmarshal(*obj, &v)
464+
err := unmarshal(*obj, &v)
465465

466466
if err != nil {
467467
return nil, err
@@ -1079,7 +1079,7 @@ func Equal(a, b []byte) bool {
10791079
func DecodePatch(buf []byte) (Patch, error) {
10801080
var p Patch
10811081

1082-
err := json.Unmarshal(buf, &p)
1082+
err := unmarshal(buf, &p)
10831083

10841084
if err != nil {
10851085
return nil, err
@@ -1124,7 +1124,7 @@ func (p Patch) ApplyIndentWithOptions(doc []byte, indent string, options *ApplyO
11241124
pd = &partialDoc{}
11251125
}
11261126

1127-
err := json.Unmarshal(doc, pd)
1127+
err := unmarshal(doc, pd)
11281128

11291129
if err != nil {
11301130
return nil, err

0 commit comments

Comments
 (0)