1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package json
6
7import (
8	"bytes"
9	"fmt"
10	"math"
11	"reflect"
12	"testing"
13	"unicode"
14)
15
16type Optionals struct {
17	Sr string `json:"sr"`
18	So string `json:"so,omitempty"`
19	Sw string `json:"-"`
20
21	Ir int `json:"omitempty"` // actually named omitempty, not an option
22	Io int `json:"io,omitempty"`
23
24	Slr []string `json:"slr,random"`
25	Slo []string `json:"slo,omitempty"`
26
27	Mr map[string]interface{} `json:"mr"`
28	Mo map[string]interface{} `json:",omitempty"`
29
30	Fr float64 `json:"fr"`
31	Fo float64 `json:"fo,omitempty"`
32
33	Br bool `json:"br"`
34	Bo bool `json:"bo,omitempty"`
35
36	Ur uint `json:"ur"`
37	Uo uint `json:"uo,omitempty"`
38
39	Str struct{} `json:"str"`
40	Sto struct{} `json:"sto,omitempty"`
41}
42
43var optionalsExpected = `{
44 "sr": "",
45 "omitempty": 0,
46 "slr": null,
47 "mr": {},
48 "fr": 0,
49 "br": false,
50 "ur": 0,
51 "str": {},
52 "sto": {}
53}`
54
55func TestOmitEmpty(t *testing.T) {
56	var o Optionals
57	o.Sw = "something"
58	o.Mr = map[string]interface{}{}
59	o.Mo = map[string]interface{}{}
60
61	got, err := MarshalIndent(&o, "", " ")
62	if err != nil {
63		t.Fatal(err)
64	}
65	if got := string(got); got != optionalsExpected {
66		t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
67	}
68}
69
70type StringTag struct {
71	BoolStr bool   `json:",string"`
72	IntStr  int64  `json:",string"`
73	StrStr  string `json:",string"`
74}
75
76var stringTagExpected = `{
77 "BoolStr": "true",
78 "IntStr": "42",
79 "StrStr": "\"xzbit\""
80}`
81
82func TestStringTag(t *testing.T) {
83	var s StringTag
84	s.BoolStr = true
85	s.IntStr = 42
86	s.StrStr = "xzbit"
87	got, err := MarshalIndent(&s, "", " ")
88	if err != nil {
89		t.Fatal(err)
90	}
91	if got := string(got); got != stringTagExpected {
92		t.Fatalf(" got: %s\nwant: %s\n", got, stringTagExpected)
93	}
94
95	// Verify that it round-trips.
96	var s2 StringTag
97	err = NewDecoder(bytes.NewReader(got)).Decode(&s2)
98	if err != nil {
99		t.Fatalf("Decode: %v", err)
100	}
101	if !reflect.DeepEqual(s, s2) {
102		t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
103	}
104}
105
106// byte slices are special even if they're renamed types.
107type renamedByte byte
108type renamedByteSlice []byte
109type renamedRenamedByteSlice []renamedByte
110
111func TestEncodeRenamedByteSlice(t *testing.T) {
112	s := renamedByteSlice("abc")
113	result, err := Marshal(s)
114	if err != nil {
115		t.Fatal(err)
116	}
117	expect := `"YWJj"`
118	if string(result) != expect {
119		t.Errorf(" got %s want %s", result, expect)
120	}
121	r := renamedRenamedByteSlice("abc")
122	result, err = Marshal(r)
123	if err != nil {
124		t.Fatal(err)
125	}
126	if string(result) != expect {
127		t.Errorf(" got %s want %s", result, expect)
128	}
129}
130
131var unsupportedValues = []interface{}{
132	math.NaN(),
133	math.Inf(-1),
134	math.Inf(1),
135}
136
137func TestUnsupportedValues(t *testing.T) {
138	for _, v := range unsupportedValues {
139		if _, err := Marshal(v); err != nil {
140			if _, ok := err.(*UnsupportedValueError); !ok {
141				t.Errorf("for %v, got %T want UnsupportedValueError", v, err)
142			}
143		} else {
144			t.Errorf("for %v, expected error", v)
145		}
146	}
147}
148
149// Ref has Marshaler and Unmarshaler methods with pointer receiver.
150type Ref int
151
152func (*Ref) MarshalJSON() ([]byte, error) {
153	return []byte(`"ref"`), nil
154}
155
156func (r *Ref) UnmarshalJSON([]byte) error {
157	*r = 12
158	return nil
159}
160
161// Val has Marshaler methods with value receiver.
162type Val int
163
164func (Val) MarshalJSON() ([]byte, error) {
165	return []byte(`"val"`), nil
166}
167
168// RefText has Marshaler and Unmarshaler methods with pointer receiver.
169type RefText int
170
171func (*RefText) MarshalText() ([]byte, error) {
172	return []byte(`"ref"`), nil
173}
174
175func (r *RefText) UnmarshalText([]byte) error {
176	*r = 13
177	return nil
178}
179
180// ValText has Marshaler methods with value receiver.
181type ValText int
182
183func (ValText) MarshalText() ([]byte, error) {
184	return []byte(`"val"`), nil
185}
186
187func TestRefValMarshal(t *testing.T) {
188	var s = struct {
189		R0 Ref
190		R1 *Ref
191		R2 RefText
192		R3 *RefText
193		V0 Val
194		V1 *Val
195		V2 ValText
196		V3 *ValText
197	}{
198		R0: 12,
199		R1: new(Ref),
200		R2: 14,
201		R3: new(RefText),
202		V0: 13,
203		V1: new(Val),
204		V2: 15,
205		V3: new(ValText),
206	}
207	const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
208	b, err := Marshal(&s)
209	if err != nil {
210		t.Fatalf("Marshal: %v", err)
211	}
212	if got := string(b); got != want {
213		t.Errorf("got %q, want %q", got, want)
214	}
215}
216
217// C implements Marshaler and returns unescaped JSON.
218type C int
219
220func (C) MarshalJSON() ([]byte, error) {
221	return []byte(`"<&>"`), nil
222}
223
224// CText implements Marshaler and returns unescaped text.
225type CText int
226
227func (CText) MarshalText() ([]byte, error) {
228	return []byte(`"<&>"`), nil
229}
230
231func TestMarshalerEscaping(t *testing.T) {
232	var c C
233	want := `"\u003c\u0026\u003e"`
234	b, err := Marshal(c)
235	if err != nil {
236		t.Fatalf("Marshal(c): %v", err)
237	}
238	if got := string(b); got != want {
239		t.Errorf("Marshal(c) = %#q, want %#q", got, want)
240	}
241
242	var ct CText
243	want = `"\"\u003c\u0026\u003e\""`
244	b, err = Marshal(ct)
245	if err != nil {
246		t.Fatalf("Marshal(ct): %v", err)
247	}
248	if got := string(b); got != want {
249		t.Errorf("Marshal(ct) = %#q, want %#q", got, want)
250	}
251}
252
253type IntType int
254
255type MyStruct struct {
256	IntType
257}
258
259func TestAnonymousNonstruct(t *testing.T) {
260	var i IntType = 11
261	a := MyStruct{i}
262	const want = `{"IntType":11}`
263
264	b, err := Marshal(a)
265	if err != nil {
266		t.Fatalf("Marshal: %v", err)
267	}
268	if got := string(b); got != want {
269		t.Errorf("got %q, want %q", got, want)
270	}
271}
272
273type BugA struct {
274	S string
275}
276
277type BugB struct {
278	BugA
279	S string
280}
281
282type BugC struct {
283	S string
284}
285
286// Legal Go: We never use the repeated embedded field (S).
287type BugX struct {
288	A int
289	BugA
290	BugB
291}
292
293// Issue 5245.
294func TestEmbeddedBug(t *testing.T) {
295	v := BugB{
296		BugA{"A"},
297		"B",
298	}
299	b, err := Marshal(v)
300	if err != nil {
301		t.Fatal("Marshal:", err)
302	}
303	want := `{"S":"B"}`
304	got := string(b)
305	if got != want {
306		t.Fatalf("Marshal: got %s want %s", got, want)
307	}
308	// Now check that the duplicate field, S, does not appear.
309	x := BugX{
310		A: 23,
311	}
312	b, err = Marshal(x)
313	if err != nil {
314		t.Fatal("Marshal:", err)
315	}
316	want = `{"A":23}`
317	got = string(b)
318	if got != want {
319		t.Fatalf("Marshal: got %s want %s", got, want)
320	}
321}
322
323type BugD struct { // Same as BugA after tagging.
324	XXX string `json:"S"`
325}
326
327// BugD's tagged S field should dominate BugA's.
328type BugY struct {
329	BugA
330	BugD
331}
332
333// Test that a field with a tag dominates untagged fields.
334func TestTaggedFieldDominates(t *testing.T) {
335	v := BugY{
336		BugA{"BugA"},
337		BugD{"BugD"},
338	}
339	b, err := Marshal(v)
340	if err != nil {
341		t.Fatal("Marshal:", err)
342	}
343	want := `{"S":"BugD"}`
344	got := string(b)
345	if got != want {
346		t.Fatalf("Marshal: got %s want %s", got, want)
347	}
348}
349
350// There are no tags here, so S should not appear.
351type BugZ struct {
352	BugA
353	BugC
354	BugY // Contains a tagged S field through BugD; should not dominate.
355}
356
357func TestDuplicatedFieldDisappears(t *testing.T) {
358	v := BugZ{
359		BugA{"BugA"},
360		BugC{"BugC"},
361		BugY{
362			BugA{"nested BugA"},
363			BugD{"nested BugD"},
364		},
365	}
366	b, err := Marshal(v)
367	if err != nil {
368		t.Fatal("Marshal:", err)
369	}
370	want := `{}`
371	got := string(b)
372	if got != want {
373		t.Fatalf("Marshal: got %s want %s", got, want)
374	}
375}
376
377func TestStringBytes(t *testing.T) {
378	// Test that encodeState.stringBytes and encodeState.string use the same encoding.
379	var r []rune
380	for i := '\u0000'; i <= unicode.MaxRune; i++ {
381		r = append(r, i)
382	}
383	s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too
384
385	for _, escapeHTML := range []bool{true, false} {
386		es := &encodeState{}
387		es.string(s, escapeHTML)
388
389		esBytes := &encodeState{}
390		esBytes.stringBytes([]byte(s), escapeHTML)
391
392		enc := es.Buffer.String()
393		encBytes := esBytes.Buffer.String()
394		if enc != encBytes {
395			i := 0
396			for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] {
397				i++
398			}
399			enc = enc[i:]
400			encBytes = encBytes[i:]
401			i = 0
402			for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] {
403				i++
404			}
405			enc = enc[:len(enc)-i]
406			encBytes = encBytes[:len(encBytes)-i]
407
408			if len(enc) > 20 {
409				enc = enc[:20] + "..."
410			}
411			if len(encBytes) > 20 {
412				encBytes = encBytes[:20] + "..."
413			}
414
415			t.Errorf("with escapeHTML=%t, encodings differ at %#q vs %#q",
416				escapeHTML, enc, encBytes)
417		}
418	}
419}
420
421func TestIssue6458(t *testing.T) {
422	type Foo struct {
423		M RawMessage
424	}
425	x := Foo{RawMessage(`"foo"`)}
426
427	b, err := Marshal(&x)
428	if err != nil {
429		t.Fatal(err)
430	}
431	if want := `{"M":"foo"}`; string(b) != want {
432		t.Errorf("Marshal(&x) = %#q; want %#q", b, want)
433	}
434
435	b, err = Marshal(x)
436	if err != nil {
437		t.Fatal(err)
438	}
439
440	if want := `{"M":"ImZvbyI="}`; string(b) != want {
441		t.Errorf("Marshal(x) = %#q; want %#q", b, want)
442	}
443}
444
445func TestIssue10281(t *testing.T) {
446	type Foo struct {
447		N Number
448	}
449	x := Foo{Number(`invalid`)}
450
451	b, err := Marshal(&x)
452	if err == nil {
453		t.Errorf("Marshal(&x) = %#q; want error", b)
454	}
455}
456
457func TestHTMLEscape(t *testing.T) {
458	var b, want bytes.Buffer
459	m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
460	want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
461	HTMLEscape(&b, []byte(m))
462	if !bytes.Equal(b.Bytes(), want.Bytes()) {
463		t.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b.Bytes(), want.Bytes())
464	}
465}
466
467// golang.org/issue/8582
468func TestEncodePointerString(t *testing.T) {
469	type stringPointer struct {
470		N *int64 `json:"n,string"`
471	}
472	var n int64 = 42
473	b, err := Marshal(stringPointer{N: &n})
474	if err != nil {
475		t.Fatalf("Marshal: %v", err)
476	}
477	if got, want := string(b), `{"n":"42"}`; got != want {
478		t.Errorf("Marshal = %s, want %s", got, want)
479	}
480	var back stringPointer
481	err = Unmarshal(b, &back)
482	if err != nil {
483		t.Fatalf("Unmarshal: %v", err)
484	}
485	if back.N == nil {
486		t.Fatalf("Unmarshalled nil N field")
487	}
488	if *back.N != 42 {
489		t.Fatalf("*N = %d; want 42", *back.N)
490	}
491}
492
493var encodeStringTests = []struct {
494	in  string
495	out string
496}{
497	{"\x00", `"\u0000"`},
498	{"\x01", `"\u0001"`},
499	{"\x02", `"\u0002"`},
500	{"\x03", `"\u0003"`},
501	{"\x04", `"\u0004"`},
502	{"\x05", `"\u0005"`},
503	{"\x06", `"\u0006"`},
504	{"\x07", `"\u0007"`},
505	{"\x08", `"\u0008"`},
506	{"\x09", `"\t"`},
507	{"\x0a", `"\n"`},
508	{"\x0b", `"\u000b"`},
509	{"\x0c", `"\u000c"`},
510	{"\x0d", `"\r"`},
511	{"\x0e", `"\u000e"`},
512	{"\x0f", `"\u000f"`},
513	{"\x10", `"\u0010"`},
514	{"\x11", `"\u0011"`},
515	{"\x12", `"\u0012"`},
516	{"\x13", `"\u0013"`},
517	{"\x14", `"\u0014"`},
518	{"\x15", `"\u0015"`},
519	{"\x16", `"\u0016"`},
520	{"\x17", `"\u0017"`},
521	{"\x18", `"\u0018"`},
522	{"\x19", `"\u0019"`},
523	{"\x1a", `"\u001a"`},
524	{"\x1b", `"\u001b"`},
525	{"\x1c", `"\u001c"`},
526	{"\x1d", `"\u001d"`},
527	{"\x1e", `"\u001e"`},
528	{"\x1f", `"\u001f"`},
529}
530
531func TestEncodeString(t *testing.T) {
532	for _, tt := range encodeStringTests {
533		b, err := Marshal(tt.in)
534		if err != nil {
535			t.Errorf("Marshal(%q): %v", tt.in, err)
536			continue
537		}
538		out := string(b)
539		if out != tt.out {
540			t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out)
541		}
542	}
543}
544
545type jsonbyte byte
546
547func (b jsonbyte) MarshalJSON() ([]byte, error) { return tenc(`{"JB":%d}`, b) }
548
549type textbyte byte
550
551func (b textbyte) MarshalText() ([]byte, error) { return tenc(`TB:%d`, b) }
552
553type jsonint int
554
555func (i jsonint) MarshalJSON() ([]byte, error) { return tenc(`{"JI":%d}`, i) }
556
557type textint int
558
559func (i textint) MarshalText() ([]byte, error) { return tenc(`TI:%d`, i) }
560
561func tenc(format string, a ...interface{}) ([]byte, error) {
562	var buf bytes.Buffer
563	fmt.Fprintf(&buf, format, a...)
564	return buf.Bytes(), nil
565}
566
567// Issue 13783
568func TestEncodeBytekind(t *testing.T) {
569	testdata := []struct {
570		data interface{}
571		want string
572	}{
573		{byte(7), "7"},
574		{jsonbyte(7), `{"JB":7}`},
575		{textbyte(4), `"TB:4"`},
576		{jsonint(5), `{"JI":5}`},
577		{textint(1), `"TI:1"`},
578		{[]byte{0, 1}, `"AAE="`},
579		{[]jsonbyte{0, 1}, `[{"JB":0},{"JB":1}]`},
580		{[][]jsonbyte{{0, 1}, {3}}, `[[{"JB":0},{"JB":1}],[{"JB":3}]]`},
581		{[]textbyte{2, 3}, `["TB:2","TB:3"]`},
582		{[]jsonint{5, 4}, `[{"JI":5},{"JI":4}]`},
583		{[]textint{9, 3}, `["TI:9","TI:3"]`},
584		{[]int{9, 3}, `[9,3]`},
585	}
586	for _, d := range testdata {
587		js, err := Marshal(d.data)
588		if err != nil {
589			t.Error(err)
590			continue
591		}
592		got, want := string(js), d.want
593		if got != want {
594			t.Errorf("got %s, want %s", got, want)
595		}
596	}
597}
598
599func TestTextMarshalerMapKeysAreSorted(t *testing.T) {
600	b, err := Marshal(map[unmarshalerText]int{
601		{"x", "y"}: 1,
602		{"y", "x"}: 2,
603		{"a", "z"}: 3,
604		{"z", "a"}: 4,
605	})
606	if err != nil {
607		t.Fatalf("Failed to Marshal text.Marshaler: %v", err)
608	}
609	const want = `{"a:z":3,"x:y":1,"y:x":2,"z:a":4}`
610	if string(b) != want {
611		t.Errorf("Marshal map with text.Marshaler keys: got %#q, want %#q", b, want)
612	}
613}
614