Skip to content

Commit 850009d

Browse files
authored
Merge pull request #194 from evanphx/b-num-prec
Always use UseNumber() to avoid float64 lossyness
2 parents c32ee8f + 67afbf6 commit 850009d

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
@@ -418,7 +418,7 @@ func (o Operation) Kind() string {
418418
if obj, ok := o["op"]; ok && obj != nil {
419419
var op string
420420

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

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

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

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

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

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

482482
var v interface{}
483483

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

486486
if err != nil {
487487
return nil, err
@@ -1099,7 +1099,7 @@ func Equal(a, b []byte) bool {
10991099
func DecodePatch(buf []byte) (Patch, error) {
11001100
var p Patch
11011101

1102-
err := json.Unmarshal(buf, &p)
1102+
err := unmarshal(buf, &p)
11031103

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

1147-
err := json.Unmarshal(doc, pd)
1147+
err := unmarshal(doc, pd)
11481148

11491149
if err != nil {
11501150
return nil, err

0 commit comments

Comments
 (0)