Commit graph

44 commits

Author SHA1 Message Date
Daniel Martí
95c3c43072 encoding/json: fix the broken "overwriting of data" tests
Because TestUnmarshal actually allocates a new value to decode into
using ptr's pointer type, any existing data is thrown away. This was
harmless in alomst all of the test cases, minus the "overwriting of
data" ones added in 2015 in CL 12209.

I spotted that nothing covered decoding a JSON array with few elements
into a slice which already had many elements. I initially assumed that
the code was buggy or that some code could be removed, when in fact
there simply wasn't any code covering the edge case.

Move those two tests to TestPrefilled, which already served a very
similar purpose. Remove the map case, as TestPrefilled already has
plenty of prefilled map cases. Moreover, we no longer reset an entire
map when decoding, as per the godoc:

	To unmarshal a JSON object into a map, Unmarshal first
	establishes a map to use. If the map is nil, Unmarshal allocates
	a new map. Otherwise Unmarshal reuses the existing map, keeping
	existing entries.

Finally, to ensure that ptr is used correctly in the future, make
TestUnmarshal error if it's anything other than a pointer to a zero
value. That is, the only correct use should be new(type). Don't rename
the ptr field, as that would be extremely noisy and cause unwanted merge
conflicts.

Change-Id: I41e3ecfeae42d877ac5443a6bd622ac3d6c8120c
Reviewed-on: https://go-review.googlesource.com/c/go/+/185738
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
2019-08-27 16:50:56 +00:00
Filippo Valsorda
eee07a8e68 Revert "encoding/json: avoid work when unquoting strings"
This reverts CL 151157.

CL 151157 introduced a crash when decoding into ",string" fields. It
came with a moderate speedup, so at this stage of the release cycle
let's just revert it, and reapply it in Go 1.14 with the fix in CL 190659.

Also applied the test cases from CL 190659.

Updates #33728

Change-Id: Ie46e2bc15224b251888580daf6b79d5865f3878e
Reviewed-on: https://go-review.googlesource.com/c/go/+/190909
Run-TryBot: Andrew Bonventre <andybons@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Bonventre <andybons@golang.org>
2019-08-21 15:20:00 +00:00
LE Manh Cuong
dcb84828a6 encoding/json: fix Unmarshal hang on recursive pointers
indirect walks down v until it gets to a non-pointer. But it does not
handle the case when v is a pointer to itself, like in:

	var v interface{}
	v = &v
	Unmarshal(b, v)

So just stop immediately if we see v is a pointer to itself.

Fixes #31740

Change-Id: Ie396264119e24d70284cd9bf76dcb2050babb069
Reviewed-on: https://go-review.googlesource.com/c/go/+/174337
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-04-30 04:57:42 +00:00
Daniel Martí
e5f6e2d1c8 encoding/json: fix performance regression in the decoder
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-18 07:58:23 +00:00
LE Manh Cuong
29bc4f1258 encoding/json: add Path to UnmarshalTypeError
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>
2019-03-05 12:34:11 +00:00
Marcel van Lohuizen
b9596aea50 encoding/json: remove use of DeepEqual for testing errors
Comparing errors using DeepEqual breaks if frame information
is added as proposed in Issue #29934.

Updates #29934.

Change-Id: Ib430c9ddbe588dd1dd51314c408c74c07285e1ff
Reviewed-on: https://go-review.googlesource.com/c/162179
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
2019-02-27 18:24:23 +00:00
Daniel Martí
4b36e129f8 encoding/json: always verify we can get a field's value
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-16 14:02:52 +00:00
Daniel Martí
5eff6bfdbc encoding/json: fix "data changed underfoot?" panic
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-10-16 13:45:08 +00:00
Daniel Martí
dc3680865a encoding/json: more tests to cover decoding edge cases
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-12 06:48:09 +00:00
Ian Davis
22afb3571c encoding/json: recover saved error context when unmarshalling
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-09-06 08:38:44 +00:00
Taesu Pyo
21e85c293d encoding/json: fix UnmarshalTypeError without field and struct values
Fixes #26444
Fixes #27275

Change-Id: I9e8cbff79f7643ca8964c572c1a98172b6831730
GitHub-Last-Rev: 7eea2158b6
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-28 16:00:33 +00:00
Daniel Martí
2d3599e57d encoding/json: encode struct field names ahead of time
Struct field names are static, so we can run HTMLEscape on them when
building each struct type encoder. Then, when running the struct
encoder, we can select either the original or the escaped field name to
write directly.

When the encoder is not escaping HTML, using the original string works
because neither Go struct field names nor JSON tags allow any characters
that would need to be escaped, like '"', '\\', or '\n'.

When the encoder is escaping HTML, the only difference is that '<', '>',
and '&' are allowed via JSON struct field tags, hence why we use
HTMLEscape to properly escape them.

All of the above lets us encode field names with a simple if/else and
WriteString calls, which are considerably simpler and faster than
encoding an arbitrary string.

While at it, also include the quotes and colon in these strings, to
avoid three WriteByte calls in the loop hot path.

Also added a few tests, to ensure that the behavior in these edge cases
is not broken. The output of the tests is the same if this optimization
is reverted.

name           old time/op    new time/op    delta
CodeEncoder-4    7.12ms ± 0%    6.14ms ± 0%  -13.85%  (p=0.004 n=6+5)

name           old speed      new speed      delta
CodeEncoder-4   272MB/s ± 0%   316MB/s ± 0%  +16.08%  (p=0.004 n=6+5)

name           old alloc/op   new alloc/op   delta
CodeEncoder-4    91.9kB ± 0%    93.2kB ± 0%   +1.43%  (p=0.002 n=6+6)

name           old allocs/op  new allocs/op  delta
CodeEncoder-4      0.00           0.00          ~     (all equal)

Updates #5683.

Change-Id: I6f6a340d0de4670799ce38cf95b2092822d2e3ef
Reviewed-on: https://go-review.googlesource.com/122460
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-21 09:05:48 +00:00
Robert Griesemer
542ea5ad91 go/printer, gofmt: tuned table alignment for better results
The go/printer (and thus gofmt) uses a heuristic to determine
whether to break alignment between elements of an expression
list which is spread across multiple lines. The heuristic only
kicked in if the entry sizes (character length) was above a
certain threshold (20) and the ratio between the previous and
current entry size was above a certain value (4).

This heuristic worked reasonably most of the time, but also
led to unfortunate breaks in many cases where a single entry
was suddenly much smaller (or larger) then the previous one.

The behavior of gofmt was sufficiently mysterious in some of
these situations that many issues were filed against it.

The simplest solution to address this problem is to remove
the heuristic altogether and have a programmer introduce
empty lines to force different alignments if it improves
readability. The problem with that approach is that the
places where it really matters, very long tables with many
(hundreds, or more) entries, may be machine-generated and
not "post-processed" by a human (e.g., unicode/utf8/tables.go).

If a single one of those entries is overlong, the result
would be that the alignment would force all comments or
values in key:value pairs to be adjusted to that overlong
value, making the table hard to read (e.g., that entry may
not even be visible on screen and all other entries seem
spaced out too wide).

Instead, we opted for a slightly improved heuristic that
behaves much better for "normal", human-written code.

1) The threshold is increased from 20 to 40. This disables
the heuristic for many common cases yet even if the alignment
is not "ideal", 40 is not that many characters per line with
todays screens, making it very likely that the entire line
remains "visible" in an editor.

2) Changed the heuristic to not simply look at the size ratio
between current and previous line, but instead considering the
geometric mean of the sizes of the previous (aligned) lines.
This emphasizes the "overall picture" of the previous lines,
rather than a single one (which might be an outlier).

3) Changed the ratio from 4 to 2.5. Now that we ignore sizes
below 40, a ratio of 4 would mean that a new entry would have
to be 4 times bigger (160) or smaller (10) before alignment
would be broken. A ratio of 2.5 seems more sensible.

Applied updated gofmt to all of src and misc. Also tested
against several former issues that complained about this
and verified that the output for the given examples is
satisfactory (added respective test cases).

Some of the files changed because they were not gofmt-ed
in the first place.

For #644.
For #7335.
For #10392.
(and probably more related issues)

Fixes #22852.

Change-Id: I5e48b3d3b157a5cf2d649833b7297b33f43a6f6e
2018-04-04 13:39:34 -07:00
Joe Tsai
4338518da8 encoding/json: avoid assuming side-effect free reflect.Value.Addr().Elem()
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-03-01 00:16:20 +00:00
Joe Tsai
91a6a2a30f encoding/json: make error capture logic in recover more type safe
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>
2018-02-14 21:34:26 +00:00
Joe Tsai
70f441bc49 encoding/json: error when trying to set an embedded pointer to unexported 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-12-06 19:27:26 +00:00
Joe Tsai
0cee4b7b78 encoding/json: always ignore embedded pointers to unexported struct types
CL 60410 fixes a bug in reflect that allows assignments to an embedded
field of a pointer to an unexported struct type.
This breaks the json package because unmarshal is now unable to assign
a newly allocated struct to such fields.

In order to be consistent in the behavior for marshal and unmarshal,
this CL changes both marshal and unmarshal to always ignore
embedded pointers to unexported structs.

Fixes #21357

Change-Id: If62ea11155555e61115ebb9cfa5305caf101bde5
Reviewed-on: https://go-review.googlesource.com/76851
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-11-13 18:23:38 +00:00
Ian Lance Taylor
ed3d672766 encoding/json: permit encoding uintptr as a string
Fixes #22629

Change-Id: I31e85f9faa125ee0dfd6d3c5fa89334b00d61e6e
Reviewed-on: https://go-review.googlesource.com/76530
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Joe Tsai <joetsai@google.com>
2017-11-08 20:34:55 +00:00
Ivan Bertona
2596a0c075 encoding/json: disallow unknown fields in Decoder
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-31 22:28:36 +00:00
Marvin Stenger
5e42658fc0 all: prefer bytes.IndexByte over bytes.Index
bytes.IndexByte can be used wherever the second argument to
strings.Index is exactly one byte long, so we do that with this change.

This avoids generating unnecessary string symbols/converison and saves
a few calls to bytes.Index.

Change-Id: If31c775790e01edfece1169e398ad6a754fb4428
Reviewed-on: https://go-review.googlesource.com/66373
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2017-09-27 01:09:13 +00:00
Dmitri Shuralyov
d8264de868 all: spell "marshal" and "unmarshal" consistently
The tree is inconsistent about single l vs double l in those
words in documentation, test messages, and one error value text.

	$ git grep -E '[Mm]arshall(|s|er|ers|ed|ing)' | wc -l
	      42
	$ git grep -E '[Mm]arshal(|s|er|ers|ed|ing)' | wc -l
	    1694

Make it consistently a single l, per earlier decisions. This means
contributors won't be confused by misleading precedence, and it helps
consistency.

Change the spelling in one error value text in newRawAttributes of
crypto/x509 package to be consistent.

This change was generated with:

	perl -i -npe 's,([Mm]arshal)l(|s|er|ers|ed|ing),$1$2,' $(git grep -l -E '[Mm]arshall' | grep -v AUTHORS | grep -v CONTRIBUTORS)

Updates #12431.
Follows https://golang.org/cl/14150.

Change-Id: I85d28a2d7692862ccb02d6a09f5d18538b6049a2
Reviewed-on: https://go-review.googlesource.com/33017
Run-TryBot: Minux Ma <minux@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-11-12 00:13:35 +00:00
Russ Cox
f444b48fe4 encoding/json: fix decoding of null into Unmarshaler, TextUnmarshaler
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-17 15:21:33 +00:00
Russ Cox
0da30d5cbd encoding/json: handle misspelled JSON literals in ,string
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-13 17:30:39 +00:00
Jirka Daněk
b9fd510cd0 encoding/json: add struct and field name to UnmarshalTypeError message
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-10-05 20:28:59 +00:00
Russ Cox
92b3e3651d encoding/json: use standard ES6 formatting for numbers during marshal
Change float32/float64 formatting to use non-exponential form
for a slightly wider range, to more closely match ES6 JSON.stringify
and other JSON generators.

Most notably:

	1e20 now formats as 100000000000000000000 (previously 1e+20)
	1e-6 now formats as 0.000001 (previously 1e-06)
	1e-7 now formats as 1e-7 (previously 1e-07)

This also brings the int64 and float64 formatting in line with each other,
for all shared representable values. For example both int64(1234567)
and float64(1234567) now format as "1234567", where before the
float64 formatted as "1.234567e+06".

The only variation now compared to ES6 JSON.stringify is that
Go continues to encode negative zero as "-0", not "0", so that
the value continues to be preserved during JSON round trips.

Fixes #6384.
Fixes #14135.

Change-Id: Ib0e0e009cd9181d75edc0424a28fe776bcc5bbf8
Reviewed-on: https://go-review.googlesource.com/30371
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-05 19:15:02 +00:00
Russ Cox
1261023637 encoding/json: additional tests and fixes for []typedByte encoding/decoding
CL 19725 changed the encoding of []typedByte to look for
typedByte.MarshalJSON and typedByte.MarshalText.
Previously it was handled like []byte, producing a base64 encoding of the underlying byte data.

CL 19725 forgot to look for (*typedByte).MarshalJSON and (*typedByte).MarshalText,
as the marshaling of other slices would. Add test and fix for those.

This CL also adds tests that the decoder can handle both the old and new encodings.
(This was true even in Go 1.6, which is the only reason we can consider this
not an incompatible change.)

For #13783.

Change-Id: I7cab8b6c0154a7f2d09335b7fa23173bcf856c37
Reviewed-on: https://go-review.googlesource.com/23294
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
2016-05-24 13:35:36 +00:00
Caleb Spare
f05c3aa24d encoding/json: support maps with integer keys
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-05-10 03:53:12 +00:00
Augusto Roman
ffbd31e9f7 encoding/json: allow non-string type keys for (un-)marshal
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-04-05 15:08:04 +00:00
Dominik Honnef
77f4b773e7 encoding/json, internal/testenv: use Fatalf
Change-Id: I64dd09e76d811000a914776fdad47808e3895690
Reviewed-on: https://go-review.googlesource.com/20989
Reviewed-by: Dave Cheney <dave@cheney.net>
2016-03-22 05:58:27 +00:00
Håvard Haugen
c60707b14d encoding/json: use reflect.SetBytes when decoding bytes
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-11-14 23:41:46 +00:00
Marcel van Lohuizen
a30dd9ceeb encoding/json: check for exported fields in embedded structs
Addresses issue #12367.

Must be checked in before CL 14010.

Change-Id: I7233c3a62d4f55d0ac7e8a87df5fc4ee7beb7207
Reviewed-on: https://go-review.googlesource.com/14011
Reviewed-by: Russ Cox <rsc@golang.org>
2015-10-26 11:23:31 +00:00
Andrew Gerrand
143f3fd0ee encoding/json: spell "marshaling" and "unmarshaling" consistently
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-23 00:48:35 +00:00
Marvin Stenger
fcf8143d63 encoding/json: scanner: use byte, more consistent
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-09-21 01:55:52 +00:00
Russ Cox
80e6d638bf encoding/json: revert "fix decoding of JSON null values"
Fixes #11912.
Fixes #11937.

This reverts commit 1a99ba55df.

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-30 20:00:56 +00:00
Didier Spezia
1a99ba55df encoding/json: fix decoding of JSON null values
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-22 15:39:54 +00:00
Russ Cox
749b391c55 encoding/json: document and test overwrite of slice, map during Unmarshal
Fixes #8837.

Change-Id: Iaaecbb0b324004cb74b16b764126b01315e6a16e
Reviewed-on: https://go-review.googlesource.com/12209
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-07-15 05:51:02 +00:00
Russ Cox
671bddf0b0 encoding/json: fix out of phase error unmarshaling non-string into TextUnmarshaler
Fixes #9650.

Change-Id: I45b879124691e485b86c1e99a3227032283850d2
Reviewed-on: https://go-review.googlesource.com/12208
Reviewed-by: Andrew Gerrand <adg@golang.org>
2015-07-15 05:34:56 +00:00
Larz Conwell
1a4e1770f6 encoding/json: Only allow string option for valid types
The "string" option only applies for strings, floats, integers, and
booleans as per the documentation. So when decoding ignore the "string"
option if the value is not of one of the types mentioned. This matches
the Marshal step which also ignores the "string" option for invalid
types.

Fixes #9812

Change-Id: I0fb2b43d0668bc0e2985886d989abbf2252070e2
Reviewed-on: https://go-review.googlesource.com/10183
Reviewed-by: Russ Cox <rsc@golang.org>
2015-07-15 01:35:56 +00:00
Håvard Haugen
4302fd0409 encoding/json: fix decoding of types with '[]byte' as underlying type
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-05-15 16:26:53 +00:00
Alex Plugaru
a257ffb178 encoding/json: add UnmarshalTypeError.Offset
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>
2015-01-29 09:54:25 +00:00
Emil Hessman
2c987e1693 encoding/json: address go vet reports
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-12-28 10:43:37 +00:00
Russ Cox
7b2b8edee6 encoding/json: fix handling of null with ,string fields
Fixes #8587.

LGTM=bradfitz
R=golang-codereviews, bradfitz
CC=golang-codereviews, iant, r
https://golang.org/cl/152270044
2014-10-07 11:07:04 -04:00
Robert Griesemer
7e8218aedd encoding/json: don't panic on incorrect map argument
Fixes #8305.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/145680044
2014-10-01 16:24:17 -07:00
Russ Cox
c007ce824d build: move package sources from src/pkg to src
Preparation was in CL 134570043.
This CL contains only the effect of 'hg mv src/pkg/* src'.
For more about the move, see golang.org/s/go14nopkg.
2014-09-08 00:08:51 -04:00
Renamed from src/pkg/encoding/json/decode_test.go (Browse further)