aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/json/decode.go
AgeCommit message (Collapse)Author
2019-03-18encoding/json: fix performance regression in the decoderDaniel Martí
In golang.org/cl/145218, a feature was added where the JSON decoder would keep track of the entire path to a field when reporting an UnmarshalTypeError. However, we all failed to check if this affected the benchmarks - myself included, as a reviewer. Below are the numbers comparing the CL's parent with itself, once it was merged: name old time/op new time/op delta CodeDecoder-8 12.9ms ± 1% 28.2ms ± 2% +119.33% (p=0.002 n=6+6) name old speed new speed delta CodeDecoder-8 151MB/s ± 1% 69MB/s ± 3% -54.40% (p=0.002 n=6+6) name old alloc/op new alloc/op delta CodeDecoder-8 2.74MB ± 0% 109.39MB ± 0% +3891.83% (p=0.002 n=6+6) name old allocs/op new allocs/op delta CodeDecoder-8 77.5k ± 0% 168.5k ± 0% +117.30% (p=0.004 n=6+5) The reason why the decoder got twice as slow is because it now allocated ~40x as many objects, which puts a lot of pressure on the garbage collector. The reason is that the CL concatenated strings every time a nested field was decoded. In other words, practically every field generated garbage when decoded. This is hugely wasteful, especially considering that the vast majority of JSON decoding inputs won't return UnmarshalTypeError. Instead, use a stack of fields, and make sure to always use the same backing array, to ensure we only need to grow the slice to the maximum depth once. The original CL also introduced a bug. The field stack string wasn't reset to its original state when reaching "d.opcode == scanEndObject", so the last field in a decoded struct could leak. For example, an added test decodes a list of structs, and encoding/json before this CL would fail: got: cannot unmarshal string into Go struct field T.Ts.Y.Y.Y of type int want: cannot unmarshal string into Go struct field T.Ts.Y of type int To fix that, simply reset the stack after decoding every field, even if it's the last. Below is the original performance versus this CL. There's a tiny performance hit, probably due to the append for every decoded field, but at least we're back to the usual ~150MB/s. name old time/op new time/op delta CodeDecoder-8 12.9ms ± 1% 13.0ms ± 1% +1.25% (p=0.009 n=6+6) name old speed new speed delta CodeDecoder-8 151MB/s ± 1% 149MB/s ± 1% -1.24% (p=0.009 n=6+6) name old alloc/op new alloc/op delta CodeDecoder-8 2.74MB ± 0% 2.74MB ± 0% +0.00% (p=0.002 n=6+6) name old allocs/op new allocs/op delta CodeDecoder-8 77.5k ± 0% 77.5k ± 0% +0.00% (p=0.002 n=6+6) Finally, make all of these benchmarks report allocs by default. The decoder ones are pretty sensitive to generated garbage, so ReportAllocs would have made the performance regression more obvious. Change-Id: I67b50f86b2e72f55539429450c67bfb1a9464b67 Reviewed-on: https://go-review.googlesource.com/c/go/+/167978 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-03-05encoding/json: add Path to UnmarshalTypeErrorLE Manh Cuong
When parsing nested object, UnmarshalTypeError does not contain actual path to nested field in original JSON. This commit change Field to contain the full path to that field. One can get the Field name by stripping all the leading path elements. Fixes #22369 Change-Id: I6969cc08abe8387a351e3fb2944adfaa0dccad2a Reviewed-on: https://go-review.googlesource.com/c/go/+/145218 Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-10-16encoding/json: always verify we can get a field's valueDaniel Martí
Calling .Interface on a struct field's reflect.Value isn't always safe. For example, if that field is an unexported anonymous struct. We only descended into this branch if the struct type had any methods, so this bug had gone unnoticed for a few release cycles. Add the check, and add a simple test case. Fixes #28145. Change-Id: I02f7e0ab9a4a0c18a5e2164211922fe9c3d30f64 Reviewed-on: https://go-review.googlesource.com/c/141537 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-10-16encoding/json: fix "data changed underfoot?" panicDaniel Martí
Given a program as follows: data := []byte(`{"F": { "a": 2, "3": 4 }}`) json.Unmarshal(data, &map[string]map[int]int{}) The JSON package should error, as "a" is not a valid integer. However, we'd encounter a panic: panic: JSON decoder out of sync - data changing underfoot? The reason was that decodeState.object would return a nil error on encountering the invalid map key string, while saving the key type error for later. This broke if we were inside another object, as we would abruptly end parsing the nested object, leaving the decoder in an unexpected state. To fix this, simply avoid storing the map element and continue decoding the object, to leave the decoder state exactly as if we hadn't seen an invalid key type. This affected both signed and unsigned integer keys, so fix both and add two test cases. Updates #28189. Change-Id: I8a6204cc3ff9fb04ed769df7a20a824c8b94faff Reviewed-on: https://go-review.googlesource.com/c/142518 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-09-12encoding/json: use panics for phase errorsDaniel Martí
Having these panic-like errors used to be ok, since they were used in the internal decoder state instead of passed around via return parameters. Recently, the decoder was rewritten to use explicit error returns instead. This error is a terrible fit for error returns; a handful of functions must return an error because of it, and their callers must check for an error that should never happen. This is precisely what panics are for, so use them. The test coverage of the package goes up from 91.3% to 91.6%, and performance is unaffected. We can also get rid of some unnecessary verbosity in the code. name old time/op new time/op delta CodeDecoder-4 27.5ms ± 1% 27.5ms ± 1% ~ (p=0.937 n=6+6) Change-Id: I01033b3f5b7c0cf0985082fa272754f96bf6353c Reviewed-on: https://go-review.googlesource.com/134835 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2018-09-12encoding/json: more tests to cover decoding edge casesDaniel Martí
The overall coverage of the json package goes up from 90.8% to 91.3%. While at it, apply two minor code simplifications found while inspecting the HTML coverage report. Change-Id: I0fba968afeedc813b1385e4bde72d93b878854d7 Reviewed-on: https://go-review.googlesource.com/134735 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-09-06encoding/json: recover saved error context when unmarshallingIan Davis
Fixes: #27464 Change-Id: I270c56fd0d5ae8787a1293029aff3072f4f52f33 Reviewed-on: https://go-review.googlesource.com/132955 Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-08-28encoding/json: fix UnmarshalTypeError without field and struct valuesTaesu Pyo
Fixes #26444 Fixes #27275 Change-Id: I9e8cbff79f7643ca8964c572c1a98172b6831730 GitHub-Last-Rev: 7eea2158b67ccab34b45a21e8f4289c36de02d93 GitHub-Pull-Request: golang/go#26719 Reviewed-on: https://go-review.googlesource.com/126897 Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-08-21encoding/json: various minor decoder speed-upsDaniel Martí
Reuse v.Type() and cachedTypeFields(t) when decoding maps and structs. Always use the same data slices when in hot loops, to ensure that the compiler generates good code. "for i < len(data) { use(d.data[i]) }" makes it harder for the compiler. Finally, do other minor clean-ups, such as deduplicating switch cases, and using a switch instead of three chained ifs. The decoder sees a noticeable speed-up, in particular when decoding structs. name old time/op new time/op delta CodeDecoder-4 29.8ms ± 1% 27.5ms ± 0% -7.83% (p=0.002 n=6+6) name old speed new speed delta CodeDecoder-4 65.0MB/s ± 1% 70.6MB/s ± 0% +8.49% (p=0.002 n=6+6) Updates #5683. Change-Id: I9d751e22502221962da696e48996ffdeb777277d Reviewed-on: https://go-review.googlesource.com/122468 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-21encoding/json: defer error context work until necessaryDaniel Martí
Calling Name on a reflect.Type is somewhat expensive, as it involves a number of nested calls and string handling. This cost was showing up when decoding structs, as we were calling it to set up an error context. We can avoid the extra work unless we do encounter an error, which makes decoding via struct types faster. name old time/op new time/op delta CodeDecoder-4 31.0ms ± 1% 29.9ms ± 1% -3.69% (p=0.002 n=6+6) name old speed new speed delta CodeDecoder-4 62.6MB/s ± 1% 65.0MB/s ± 1% +3.83% (p=0.002 n=6+6) Updates #5683. Change-Id: I48a3a85ef0ba96f524b7c3e9096cb2c4589e077a Reviewed-on: https://go-review.googlesource.com/122467 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-21encoding/json: call reflect.TypeOf with nil pointers rather than allocatingTim Cooper
Updates #26775 Change-Id: I83c9eeda59769d2f35e0cc98f3a8579861d5978b Reviewed-on: https://go-review.googlesource.com/119715 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-06-01all: update comment URLs from HTTP to HTTPS, where possibleTim Cooper
Each URL was manually verified to ensure it did not serve up incorrect content. Change-Id: I4dc846227af95a73ee9a3074d0c379ff0fa955df Reviewed-on: https://go-review.googlesource.com/115798 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org>
2018-04-20encoding/json: remove unnecessary if conditionstengufromsky
Fixes gosimple warning "if err != nil { return err }; return nil' can be simplified to 'return err" Change-Id: Ife7f78a3a76ab7802b5561d1afec536e103b504a Reviewed-on: https://go-review.googlesource.com/108275 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-04-09encoding/json: remove unnecessary else conditionsbontequero
Fixes golint warning about "if block ends with a return statement, so drop this else and outdent its block". Change-Id: Id17ad0bf37ba939386b177b709e9e3c067d8ba21 Reviewed-on: https://go-review.googlesource.com/105736 Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-03-03encoding/json: apply conventional error handling in decoderPascal S. de Kloe
name old time/op new time/op delta CodeEncoder-12 1.89ms ± 1% 1.91ms ± 0% +1.16% (p=0.000 n=20+19) CodeMarshal-12 2.09ms ± 1% 2.12ms ± 0% +1.63% (p=0.000 n=17+18) CodeDecoder-12 8.43ms ± 1% 8.32ms ± 1% -1.35% (p=0.000 n=18+20) UnicodeDecoder-12 399ns ± 0% 339ns ± 0% -15.00% (p=0.000 n=20+19) DecoderStream-12 281ns ± 1% 231ns ± 0% -17.91% (p=0.000 n=20+16) CodeUnmarshal-12 9.35ms ± 2% 9.15ms ± 2% -2.11% (p=0.000 n=20+20) CodeUnmarshalReuse-12 8.41ms ± 2% 8.29ms ± 2% -1.34% (p=0.000 n=20+20) UnmarshalString-12 81.2ns ± 2% 74.0ns ± 4% -8.89% (p=0.000 n=20+20) UnmarshalFloat64-12 71.1ns ± 2% 64.3ns ± 1% -9.60% (p=0.000 n=20+19) UnmarshalInt64-12 60.6ns ± 2% 53.2ns ± 0% -12.28% (p=0.000 n=18+18) Issue10335-12 96.9ns ± 0% 87.7ns ± 1% -9.52% (p=0.000 n=17+20) Unmapped-12 247ns ± 4% 231ns ± 3% -6.34% (p=0.000 n=20+20) TypeFieldsCache/MissTypes1-12 11.1µs ± 0% 11.1µs ± 0% ~ (p=0.376 n=19+20) TypeFieldsCache/MissTypes10-12 33.9µs ± 0% 33.8µs ± 0% -0.32% (p=0.000 n=18+9) name old speed new speed delta CodeEncoder-12 1.03GB/s ± 1% 1.01GB/s ± 0% -1.15% (p=0.000 n=20+19) CodeMarshal-12 930MB/s ± 1% 915MB/s ± 0% -1.60% (p=0.000 n=17+18) CodeDecoder-12 230MB/s ± 1% 233MB/s ± 1% +1.37% (p=0.000 n=18+20) UnicodeDecoder-12 35.0MB/s ± 0% 41.2MB/s ± 0% +17.60% (p=0.000 n=20+19) CodeUnmarshal-12 208MB/s ± 2% 212MB/s ± 2% +2.16% (p=0.000 n=20+20) name old alloc/op new alloc/op delta Issue10335-12 184B ± 0% 184B ± 0% ~ (all equal) Unmapped-12 216B ± 0% 216B ± 0% ~ (all equal) name old allocs/op new allocs/op delta Issue10335-12 3.00 ± 0% 3.00 ± 0% ~ (all equal) Unmapped-12 4.00 ± 0% 4.00 ± 0% ~ (all equal) Change-Id: I4b1a87a205da2ef9a572f86f85bc833653c61570 Reviewed-on: https://go-review.googlesource.com/98440 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-03-01encoding/json: read ahead after value consumptionPascal S. de Kloe
Eliminates the need for an extra scanner, read undo and some other tricks. name old time/op new time/op delta CodeEncoder-12 1.92ms ± 0% 1.91ms ± 1% -0.65% (p=0.000 n=17+20) CodeMarshal-12 2.13ms ± 2% 2.12ms ± 1% -0.49% (p=0.038 n=18+17) CodeDecoder-12 8.55ms ± 2% 8.49ms ± 1% ~ (p=0.119 n=20+18) UnicodeDecoder-12 411ns ± 0% 422ns ± 0% +2.77% (p=0.000 n=19+15) DecoderStream-12 320ns ± 1% 307ns ± 1% -3.80% (p=0.000 n=18+20) CodeUnmarshal-12 9.65ms ± 3% 9.58ms ± 3% ~ (p=0.157 n=20+20) CodeUnmarshalReuse-12 8.54ms ± 3% 8.56ms ± 2% ~ (p=0.602 n=20+20) UnmarshalString-12 110ns ± 1% 87ns ± 2% -21.53% (p=0.000 n=16+20) UnmarshalFloat64-12 101ns ± 1% 77ns ± 2% -23.08% (p=0.000 n=19+20) UnmarshalInt64-12 94.5ns ± 2% 68.4ns ± 1% -27.60% (p=0.000 n=20+20) Issue10335-12 128ns ± 1% 100ns ± 1% -21.89% (p=0.000 n=19+18) Unmapped-12 427ns ± 3% 247ns ± 4% -42.17% (p=0.000 n=20+20) NumberIsValid-12 23.0ns ± 0% 21.7ns ± 0% -5.73% (p=0.000 n=20+20) NumberIsValidRegexp-12 641ns ± 0% 642ns ± 0% +0.15% (p=0.003 n=19+19) EncoderEncode-12 56.9ns ± 0% 55.0ns ± 1% -3.32% (p=0.012 n=2+17) name old speed new speed delta CodeEncoder-12 1.01GB/s ± 1% 1.02GB/s ± 1% +0.71% (p=0.000 n=18+20) CodeMarshal-12 913MB/s ± 2% 917MB/s ± 1% +0.49% (p=0.038 n=18+17) CodeDecoder-12 227MB/s ± 2% 229MB/s ± 1% ~ (p=0.110 n=20+18) UnicodeDecoder-12 34.1MB/s ± 0% 33.1MB/s ± 0% -2.73% (p=0.000 n=19+19) CodeUnmarshal-12 201MB/s ± 3% 203MB/s ± 3% ~ (p=0.151 n=20+20) name old alloc/op new alloc/op delta Issue10335-12 320B ± 0% 184B ± 0% -42.50% (p=0.000 n=20+20) Unmapped-12 568B ± 0% 216B ± 0% -61.97% (p=0.000 n=20+20) EncoderEncode-12 0.00B 0.00B ~ (all equal) name old allocs/op new allocs/op delta Issue10335-12 4.00 ± 0% 3.00 ± 0% -25.00% (p=0.000 n=20+20) Unmapped-12 18.0 ± 0% 4.0 ± 0% -77.78% (p=0.000 n=20+20) EncoderEncode-12 0.00 0.00 ~ (all equal) Fixes #17914 Updates #20693 Updates #10335 Change-Id: I0459a52febb8b79c9a2991e69ed2614cf8740429 Reviewed-on: https://go-review.googlesource.com/47152 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-03-01encoding/json: avoid assuming side-effect free reflect.Value.Addr().Elem()Joe Tsai
Consider the following: type child struct{ Field string } type parent struct{ child } p := new(parent) v := reflect.ValueOf(p).Elem().Field(0) v.Field(0).SetString("hello") // v.Field = "hello" v = v.Addr().Elem() // v = *(&v) v.Field(0).SetString("goodbye") // v.Field = "goodbye" It would appear that v.Addr().Elem() should have the same value, and that it would be safe to set "goodbye". However, after CL 66331, any interspersed calls between Field calls causes the RO flag to be set. Thus, setting to "goodbye" actually causes a panic. That CL affects decodeState.indirect which assumes that back-to-back Value.Addr().Elem() is side-effect free. We fix that logic to keep track of the Addr() and Elem() calls and set v back to the original after a full round-trip has occured. Fixes #24152 Updates #24153 Change-Id: Ie50f8fe963f00cef8515d89d1d5cbc43b76d9f9c Reviewed-on: https://go-review.googlesource.com/97796 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-02-14encoding/json: make error capture logic in recover more type safeJoe Tsai
Rather than only ignoring runtime.Error panics, which are a very narrow set of possible panic values, switch it such that the json package only captures panic values that have been properly wrapped in a jsonError struct. This ensures that only intentional panics originating from the json package are captured. Fixes #23012 Change-Id: I5e85200259edd2abb1b0512ce6cc288849151a6d Reviewed-on: https://go-review.googlesource.com/94019 Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-12-06encoding/json: error when trying to set an embedded pointer to unexported ↵Joe Tsai
struct types This CL reverts CL 76851 and takes a different approach to #21357. The changes in encode.go and encode_test.go are reverts that rolls back the changed behavior in CL 76851 where embedded pointers to unexported struct types were unilaterally ignored in both marshal and unmarshal. Instead, these fields are handled as before with the exception that it returns an error when Unmarshal is unable to set an unexported field. The behavior of Marshal is now unchanged with regards to #21357. This policy maintains the greatest degree of backwards compatibility and avoids silently discarding data the user may have expected to be present. Fixes #21357 Change-Id: I7dc753280c99f786ac51acf7e6c0246618c8b2b1 Reviewed-on: https://go-review.googlesource.com/82135 Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-11-22encoding/json: reduce allocations by Decoder for \uXXXXMichael Schurter
Manually convert hex escape sequence to rune instead of calling strconv.ParseUint. This inlines the unhex func from docs (and many other packages). name old time/op new time/op delta UnicodeDecoder-4 468ns ± 1% 402ns ± 1% -14.26% (p=0.000 n=10+10) name old speed new speed delta UnicodeDecoder-4 29.9MB/s ± 1% 34.8MB/s ± 1% +16.59% (p=0.000 n=10+10) name old alloc/op new alloc/op delta UnicodeDecoder-4 44.0B ± 0% 36.0B ± 0% -18.18% (p=0.000 n=10+10) name old allocs/op new allocs/op delta UnicodeDecoder-4 4.00 ± 0% 2.00 ± 0% -50.00% (p=0.000 n=10+10) Fixes #20567 Change-Id: If350978d5bb98ff517485752184d02249f5d1f3a Reviewed-on: https://go-review.googlesource.com/44738 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-10-31encoding/json: disallow unknown fields in DecoderIvan Bertona
Add a DisallowUnknownFields flag to Decoder. DisallowUnknownFields causes the Decoder to return an error when the the decoding destination is a struct and the input contains object keys which do not match any non-ignored, public field the destination, including keys whose value is set to null. Note: this fix has already been worked on in 27231, which seems to be abandoned. This version is a slightly simpler implementation and is up to date with the master branch. Fixes #15314 Change-Id: I987a5857c52018df334f4d1a2360649c44a7175d Reviewed-on: https://go-review.googlesource.com/74830 Reviewed-by: Joe Tsai <joetsai@google.com> Run-TryBot: Joe Tsai <joetsai@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-10-11encoding/json: use Deprecated markersJoe Tsai
In #10909, it was decided that "Deprecated:" is a magic string for tools (e.g., #17056 for godoc) to detect deprecated identifiers. Use those convention instead of custom written prose. Change-Id: Ia514fc3c88fc502e86c6e3de361c435f4cb80b22 Reviewed-on: https://go-review.googlesource.com/70110 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
2017-08-26all: remove some double spaces from commentsDaniel Martí
Went mainly for the ones that make no sense, such as the ones mid-sentence or after commas. Change-Id: Ie245d2c19cc7428a06295635cf6a9482ade25ff0 Reviewed-on: https://go-review.googlesource.com/57293 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-06-29Revert "encoding/json: reduce unmarshal mallocs for unmapped fields"Brad Fitzpatrick
This reverts commit df68afd07ce67727 (https://golang.org/cl/33276) Reason for revert: made other benchmarks worse Fixes #20693 (details) Updates #17914 Updates #10335 Change-Id: If451b620803ccb0536b89c76c4353d2185d57d7e Reviewed-on: https://go-review.googlesource.com/47211 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
2017-06-05encoding/json: clarify unmarshaling behaviour on bad fieldsAlberto Donizetti
Fixes #19526 Change-Id: Ifaaf454e0e89fdf4309118c2e2e6ac0d0a43c39d Reviewed-on: https://go-review.googlesource.com/44711 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-03-20encoding/json: reduce unmarshal mallocs for unmapped fieldsPascal S. de Kloe
JSON decoding performs poorly for unmapped and ignored fields. We noticed better performance when unmarshalling unused fields. The loss comes mostly from calls to scanner.error as described at #17914. benchmark old ns/op new ns/op delta BenchmarkIssue10335-8 431 408 -5.34% BenchmarkUnmapped-8 1744 1314 -24.66% benchmark old allocs new allocs delta BenchmarkIssue10335-8 4 3 -25.00% BenchmarkUnmapped-8 18 4 -77.78% benchmark old bytes new bytes delta BenchmarkIssue10335-8 320 312 -2.50% BenchmarkUnmapped-8 568 344 -39.44% Fixes #17914, improves #10335 Change-Id: I7d4258a94eb287c0fe49e7334795209b90434cd0 Reviewed-on: https://go-review.googlesource.com/33276 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-10encoding/json: clarify documention for Unmarshal into a pointer.Tuo Shan
Fixes #18730. Change-Id: If3ef28e62f7e449d4c8dc1dfd78f7d6f5a87ed26 Reviewed-on: https://go-review.googlesource.com/36478 Reviewed-by: Russ Cox <rsc@golang.org>
2016-10-24encoding/json: fix bad formatting introduced in CL 20356Russ Cox
Change-Id: I39a8b543e472e5ec5d4807a9b7f61657465c5ce5 Reviewed-on: https://go-review.googlesource.com/31816 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-10-17encoding/json: fix decoding of null into Unmarshaler, TextUnmarshalerRuss Cox
1. Define behavior for Unmarshal of JSON null into Unmarshaler and TextUnmarshaler. Specifically, an Unmarshaler will be given the literal null and can decide what to do (because otherwise json.RawMessage is impossible to implement), and a TextUnmarshaler will be skipped over (because there is no text to unmarshal), like most other inappropriate types. Document this in Unmarshal, with a reminder in UnmarshalJSON about handling null. 2. Test all this. 3. Fix the TextUnmarshaler case, which was returning an unmarshalling error, to match the definition. 4. Fix the error that had been used for the TextUnmarshaler, since it was claiming that there was a JSON string when in fact the problem was NOT having a string. 5. Adjust time.Time and big.Int's UnmarshalJSON to ignore null, as is conventional. Fixes #9037. Change-Id: If78350414eb8dda712867dc8f4ca35a9db041b0c Reviewed-on: https://go-review.googlesource.com/30944 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-13encoding/json: handle misspelled JSON literals in ,stringRuss Cox
Fixes #15146. Change-Id: I229611b9cc995a1391681c492c4d742195c787ea Reviewed-on: https://go-review.googlesource.com/30943 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-05encoding/json: add struct and field name to UnmarshalTypeError messageJirka Daněk
The UnmarshalTypeError has two new fields Struct and Field, used when constructing the error message. Fixes #6716. Change-Id: I67da171480a9491960b3ae81893770644180f848 Reviewed-on: https://go-review.googlesource.com/18692 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-05-10encoding/json: support maps with integer keysCaleb Spare
This change makes encoding and decoding support integer types in map keys, converting to/from JSON string keys. JSON object keys are still sorted lexically, even though the keys may be integer strings. For backwards-compatibility, the existing Text(Un)Marshaler support for map keys (added in CL 20356) does not take precedence over the default encoding for string types. There is no such concern for integer types, so integer map key encoding is only used as a fallback if the map key type is not a Text(Un)Marshaler. Fixes #12529. Change-Id: I7e68c34f9cd19704b1d233a9862da15fabf0908a Reviewed-on: https://go-review.googlesource.com/22060 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-04-16encoding/json: update docs to not use misuse the term "object"Brad Fitzpatrick
In JSON terminology, "object" is a collect of key/value pairs. But a JSON object is only one type of JSON value (others are string, number, array, true, false, null). This updates the Go docs (at least the public godoc) to not use "object" when we mean any JSON value. Change-Id: Ieb1c456c703693714d63d9d09d306f4d9e8f4597 Reviewed-on: https://go-review.googlesource.com/22003 Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-04-05encoding/json: allow non-string type keys for (un-)marshalAugusto Roman
This CL allows JSON-encoding & -decoding maps whose keys are types that implement encoding.TextMarshaler / TextUnmarshaler. During encode, the map keys are marshaled upfront so that they can be sorted. Fixes #12146 Change-Id: I43809750a7ad82a3603662f095c7baf75fd172da Reviewed-on: https://go-review.googlesource.com/20356 Run-TryBot: Caleb Spare <cespare@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-03-02all: single space after period.Brad Fitzpatrick
The tree's pretty inconsistent about single space vs double space after a period in documentation. Make it consistently a single space, per earlier decisions. This means contributors won't be confused by misleading precedence. This CL doesn't use go/doc to parse. It only addresses // comments. It was generated with: $ perl -i -npe 's,^(\s*// .+[a-z]\.) +([A-Z]),$1 $2,' $(git grep -l -E '^\s*//(.+\.) +([A-Z])') $ go test go/doc -update Change-Id: Iccdb99c37c797ef1f804a94b22ba5ee4b500c4f7 Reviewed-on: https://go-review.googlesource.com/20022 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Dave Day <djd@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-01-08encoding/json: doc: Decode only writes to exported fieldsIan Lance Taylor
Fixes #13867. Change-Id: I6c0a6c64369681840df60f63036c2eece27de8b8 Reviewed-on: https://go-review.googlesource.com/18394 Reviewed-by: Russ Cox <rsc@golang.org>
2015-12-04encoding/json: streamline, unexport valid Number checkingRuss Cox
Followup to CL 12250. For #10281. Change-Id: If25d9cac92f10327bb355f2d11b00c625b464661 Reviewed-on: https://go-review.googlesource.com/17199 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-12-03encoding/json: revise docs for Unmarshal into map, slice, arrayRuss Cox
Fixes #12972. Change-Id: Id0611667e6149753c351c0c5e01211340a87d3fd Reviewed-on: https://go-review.googlesource.com/17230 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-11-25encoding/json: check if Number is validErik Dubbelboer
json.Number is a special case which didn't have any checks and could result in invalid JSON. Fixes #10281 Change-Id: Ie3e726e4d6bf6a6aba535d36f6107013ceac913a Reviewed-on: https://go-review.googlesource.com/12250 Reviewed-by: Russ Cox <rsc@golang.org>
2015-11-14encoding/json: use reflect.SetBytes when decoding bytesHåvard Haugen
This allows slices of custom types with byte as underlying type to be decoded, fixing a regression introduced in CL 9371. Fixes #12921. Change-Id: I62a715eaeaaa912b6bc599e94f9981a9ba5cb242 Reviewed-on: https://go-review.googlesource.com/16303 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-09-23encoding/json: spell "marshaling" and "unmarshaling" consistentlyAndrew Gerrand
Fixes #12431 Change-Id: I67c42bf2cd9285f471387248fd9c22a16b158349 Reviewed-on: https://go-review.googlesource.com/14150 Reviewed-by: Dmitri Shuralyov <shurcool@gmail.com> Reviewed-by: Rob Pike <r@golang.org>
2015-09-21encoding/json: scanner: use byte, more consistentMarvin Stenger
The fields step and redoState of struct scanner are now defined as `func(s *scanner, c byte) int` instead of `func(s *scanner, c int) int`, since bytes are sufficient. Further changes improve the consistency in the scanner.go file. Change-Id: Ifb85f2130d728d2b936d79914d87a1f0b5c6ee7d Reviewed-on: https://go-review.googlesource.com/14801 Reviewed-by: Andrew Gerrand <adg@golang.org> Run-TryBot: Andrew Gerrand <adg@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-07-30encoding/json: revert "fix decoding of JSON null values"Russ Cox
Fixes #11912. Fixes #11937. This reverts commit 1a99ba55df902a2657d1ccfc52a60024c22dba98. Change-Id: I32b76053fdabc59f28ca5bedf1b15c0baa8afae1 Reviewed-on: https://go-review.googlesource.com/12893 Reviewed-by: Didier Spezia <didier.06@gmail.com> Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-07-22encoding/json: fix decoding of JSON null valuesDidier Spezia
JSON decoding currently fails for null values bound to any type which does implement the JSON Unmarshaler interface without checking for null values (such as time.Time). It also fails for types implementing the TextUnmarshaler interface. The expected behavior of the JSON decoding engine in such case is to process null by keeping the value unchanged without producing any error. Make sure null values are handled by the decoding engine itself, and never passed to the UnmarshalText or UnmarshalJSON methods. Fixes #9037 Change-Id: I261d85587ba543ef6f1815555b2af9311034d5bb Reviewed-on: https://go-review.googlesource.com/9376 Reviewed-by: Russ Cox <rsc@golang.org>
2015-07-15encoding/json: document and test overwrite of slice, map during UnmarshalRuss Cox
Fixes #8837. Change-Id: Iaaecbb0b324004cb74b16b764126b01315e6a16e Reviewed-on: https://go-review.googlesource.com/12209 Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-07-15encoding/json: fix out of phase error unmarshaling non-string into ↵Russ Cox
TextUnmarshaler Fixes #9650. Change-Id: I45b879124691e485b86c1e99a3227032283850d2 Reviewed-on: https://go-review.googlesource.com/12208 Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-05-15encoding/json: fix decoding of types with '[]byte' as underlying typeHåvard Haugen
All slice types which have elements of kind reflect.Uint8 are marshalled into base64 for compactness. When decoding such data into a custom type based on []byte the decoder checked the slice kind instead of the slice element kind, so no appropriate decoder was found. Fixed by letting the decoder check slice element kind like the encoder. This guarantees that already encoded data can still be successfully decoded. Fixes #8962. Change-Id: Ia320d4dc2c6e9e5fe6d8dc15788c81da23d20c4f Reviewed-on: https://go-review.googlesource.com/9371 Reviewed-by: Peter Waldschmidt <peter@waldschmidt.com> Reviewed-by: Russ Cox <rsc@golang.org>
2015-01-29encoding/json: add UnmarshalTypeError.OffsetAlex Plugaru
Fixes #9693 Change-Id: Ibf07199729bfc883b2a7e051cafd98185f912acd Reviewed-on: https://go-review.googlesource.com/3283 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2014-12-28encoding/json: address go vet reportsEmil Hessman
The error message for decoding a unquoted value into a struct field with the ,string option specified has two arguments when one is needed. Make the error message take one argument and add a test in order to cover the case when a unquoted value is specified. Also add error value as the missing argument for Fatalf call in test. Fixes the following go vet reports: decode.go:602: wrong number of args for format in Errorf call: 1 needed but 2 args decode_test.go:1088: missing argument for Fatalf("%v"): format reads arg 1, have only 0 args Change-Id: Id036e10c54c4a7c1ee9952f6910858ecc2b84134 Reviewed-on: https://go-review.googlesource.com/2109 Reviewed-by: Mikio Hara <mikioh.mikioh@gmail.com>
2014-10-07encoding/json: fix handling of null with ,string fieldsRuss Cox
Fixes #8587. LGTM=bradfitz R=golang-codereviews, bradfitz CC=golang-codereviews, iant, r https://golang.org/cl/152270044