1// Copyright 2009 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 gob
6
7import (
8	"bytes"
9	"errors"
10	"flag"
11	"math"
12	"math/rand"
13	"reflect"
14	"strings"
15	"testing"
16	"time"
17	"unsafe"
18)
19
20var doFuzzTests = flag.Bool("gob.fuzz", false, "run the fuzz tests, which are large and very slow")
21
22// Guarantee encoding format by comparing some encodings to hand-written values
23type EncodeT struct {
24	x uint64
25	b []byte
26}
27
28var encodeT = []EncodeT{
29	{0x00, []byte{0x00}},
30	{0x0F, []byte{0x0F}},
31	{0xFF, []byte{0xFF, 0xFF}},
32	{0xFFFF, []byte{0xFE, 0xFF, 0xFF}},
33	{0xFFFFFF, []byte{0xFD, 0xFF, 0xFF, 0xFF}},
34	{0xFFFFFFFF, []byte{0xFC, 0xFF, 0xFF, 0xFF, 0xFF}},
35	{0xFFFFFFFFFF, []byte{0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
36	{0xFFFFFFFFFFFF, []byte{0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
37	{0xFFFFFFFFFFFFFF, []byte{0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
38	{0xFFFFFFFFFFFFFFFF, []byte{0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
39	{0x1111, []byte{0xFE, 0x11, 0x11}},
40	{0x1111111111111111, []byte{0xF8, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},
41	{0x8888888888888888, []byte{0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}},
42	{1 << 63, []byte{0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
43}
44
45// testError is meant to be used as a deferred function to turn a panic(gobError) into a
46// plain test.Error call.
47func testError(t *testing.T) {
48	if e := recover(); e != nil {
49		t.Error(e.(gobError).err) // Will re-panic if not one of our errors, such as a runtime error.
50	}
51	return
52}
53
54// Test basic encode/decode routines for unsigned integers
55func TestUintCodec(t *testing.T) {
56	defer testError(t)
57	b := new(bytes.Buffer)
58	encState := newEncoderState(b)
59	for _, tt := range encodeT {
60		b.Reset()
61		encState.encodeUint(tt.x)
62		if !bytes.Equal(tt.b, b.Bytes()) {
63			t.Errorf("encodeUint: %#x encode: expected % x got % x", tt.x, tt.b, b.Bytes())
64		}
65	}
66	decState := newDecodeState(b)
67	for u := uint64(0); ; u = (u + 1) * 7 {
68		b.Reset()
69		encState.encodeUint(u)
70		v := decState.decodeUint()
71		if u != v {
72			t.Errorf("Encode/Decode: sent %#x received %#x", u, v)
73		}
74		if u&(1<<63) != 0 {
75			break
76		}
77	}
78}
79
80func verifyInt(i int64, t *testing.T) {
81	defer testError(t)
82	var b = new(bytes.Buffer)
83	encState := newEncoderState(b)
84	encState.encodeInt(i)
85	decState := newDecodeState(b)
86	decState.buf = make([]byte, 8)
87	j := decState.decodeInt()
88	if i != j {
89		t.Errorf("Encode/Decode: sent %#x received %#x", uint64(i), uint64(j))
90	}
91}
92
93// Test basic encode/decode routines for signed integers
94func TestIntCodec(t *testing.T) {
95	for u := uint64(0); ; u = (u + 1) * 7 {
96		// Do positive and negative values
97		i := int64(u)
98		verifyInt(i, t)
99		verifyInt(-i, t)
100		verifyInt(^i, t)
101		if u&(1<<63) != 0 {
102			break
103		}
104	}
105	verifyInt(-1<<63, t) // a tricky case
106}
107
108// The result of encoding a true boolean with field number 7
109var boolResult = []byte{0x07, 0x01}
110
111// The result of encoding a number 17 with field number 7
112var signedResult = []byte{0x07, 2 * 17}
113var unsignedResult = []byte{0x07, 17}
114var floatResult = []byte{0x07, 0xFE, 0x31, 0x40}
115
116// The result of encoding a number 17+19i with field number 7
117var complexResult = []byte{0x07, 0xFE, 0x31, 0x40, 0xFE, 0x33, 0x40}
118
119// The result of encoding "hello" with field number 7
120var bytesResult = []byte{0x07, 0x05, 'h', 'e', 'l', 'l', 'o'}
121
122func newDecodeState(buf *bytes.Buffer) *decoderState {
123	d := new(decoderState)
124	d.b = buf
125	d.buf = make([]byte, uint64Size)
126	return d
127}
128
129func newEncoderState(b *bytes.Buffer) *encoderState {
130	b.Reset()
131	state := &encoderState{enc: nil, b: b}
132	state.fieldnum = -1
133	return state
134}
135
136// Test instruction execution for encoding.
137// Do not run the machine yet; instead do individual instructions crafted by hand.
138func TestScalarEncInstructions(t *testing.T) {
139	var b = new(bytes.Buffer)
140
141	// bool
142	{
143		data := struct{ a bool }{true}
144		instr := &encInstr{encBool, 6, 0, 0}
145		state := newEncoderState(b)
146		instr.op(instr, state, unsafe.Pointer(&data))
147		if !bytes.Equal(boolResult, b.Bytes()) {
148			t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Bytes())
149		}
150	}
151
152	// int
153	{
154		b.Reset()
155		data := struct{ a int }{17}
156		instr := &encInstr{encInt, 6, 0, 0}
157		state := newEncoderState(b)
158		instr.op(instr, state, unsafe.Pointer(&data))
159		if !bytes.Equal(signedResult, b.Bytes()) {
160			t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Bytes())
161		}
162	}
163
164	// uint
165	{
166		b.Reset()
167		data := struct{ a uint }{17}
168		instr := &encInstr{encUint, 6, 0, 0}
169		state := newEncoderState(b)
170		instr.op(instr, state, unsafe.Pointer(&data))
171		if !bytes.Equal(unsignedResult, b.Bytes()) {
172			t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Bytes())
173		}
174	}
175
176	// int8
177	{
178		b.Reset()
179		data := struct{ a int8 }{17}
180		instr := &encInstr{encInt8, 6, 0, 0}
181		state := newEncoderState(b)
182		instr.op(instr, state, unsafe.Pointer(&data))
183		if !bytes.Equal(signedResult, b.Bytes()) {
184			t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Bytes())
185		}
186	}
187
188	// uint8
189	{
190		b.Reset()
191		data := struct{ a uint8 }{17}
192		instr := &encInstr{encUint8, 6, 0, 0}
193		state := newEncoderState(b)
194		instr.op(instr, state, unsafe.Pointer(&data))
195		if !bytes.Equal(unsignedResult, b.Bytes()) {
196			t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
197		}
198	}
199
200	// int16
201	{
202		b.Reset()
203		data := struct{ a int16 }{17}
204		instr := &encInstr{encInt16, 6, 0, 0}
205		state := newEncoderState(b)
206		instr.op(instr, state, unsafe.Pointer(&data))
207		if !bytes.Equal(signedResult, b.Bytes()) {
208			t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Bytes())
209		}
210	}
211
212	// uint16
213	{
214		b.Reset()
215		data := struct{ a uint16 }{17}
216		instr := &encInstr{encUint16, 6, 0, 0}
217		state := newEncoderState(b)
218		instr.op(instr, state, unsafe.Pointer(&data))
219		if !bytes.Equal(unsignedResult, b.Bytes()) {
220			t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
221		}
222	}
223
224	// int32
225	{
226		b.Reset()
227		data := struct{ a int32 }{17}
228		instr := &encInstr{encInt32, 6, 0, 0}
229		state := newEncoderState(b)
230		instr.op(instr, state, unsafe.Pointer(&data))
231		if !bytes.Equal(signedResult, b.Bytes()) {
232			t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Bytes())
233		}
234	}
235
236	// uint32
237	{
238		b.Reset()
239		data := struct{ a uint32 }{17}
240		instr := &encInstr{encUint32, 6, 0, 0}
241		state := newEncoderState(b)
242		instr.op(instr, state, unsafe.Pointer(&data))
243		if !bytes.Equal(unsignedResult, b.Bytes()) {
244			t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
245		}
246	}
247
248	// int64
249	{
250		b.Reset()
251		data := struct{ a int64 }{17}
252		instr := &encInstr{encInt64, 6, 0, 0}
253		state := newEncoderState(b)
254		instr.op(instr, state, unsafe.Pointer(&data))
255		if !bytes.Equal(signedResult, b.Bytes()) {
256			t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Bytes())
257		}
258	}
259
260	// uint64
261	{
262		b.Reset()
263		data := struct{ a uint64 }{17}
264		instr := &encInstr{encUint64, 6, 0, 0}
265		state := newEncoderState(b)
266		instr.op(instr, state, unsafe.Pointer(&data))
267		if !bytes.Equal(unsignedResult, b.Bytes()) {
268			t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
269		}
270	}
271
272	// float32
273	{
274		b.Reset()
275		data := struct{ a float32 }{17}
276		instr := &encInstr{encFloat32, 6, 0, 0}
277		state := newEncoderState(b)
278		instr.op(instr, state, unsafe.Pointer(&data))
279		if !bytes.Equal(floatResult, b.Bytes()) {
280			t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Bytes())
281		}
282	}
283
284	// float64
285	{
286		b.Reset()
287		data := struct{ a float64 }{17}
288		instr := &encInstr{encFloat64, 6, 0, 0}
289		state := newEncoderState(b)
290		instr.op(instr, state, unsafe.Pointer(&data))
291		if !bytes.Equal(floatResult, b.Bytes()) {
292			t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Bytes())
293		}
294	}
295
296	// bytes == []uint8
297	{
298		b.Reset()
299		data := struct{ a []byte }{[]byte("hello")}
300		instr := &encInstr{encUint8Array, 6, 0, 0}
301		state := newEncoderState(b)
302		instr.op(instr, state, unsafe.Pointer(&data))
303		if !bytes.Equal(bytesResult, b.Bytes()) {
304			t.Errorf("bytes enc instructions: expected % x got % x", bytesResult, b.Bytes())
305		}
306	}
307
308	// string
309	{
310		b.Reset()
311		data := struct{ a string }{"hello"}
312		instr := &encInstr{encString, 6, 0, 0}
313		state := newEncoderState(b)
314		instr.op(instr, state, unsafe.Pointer(&data))
315		if !bytes.Equal(bytesResult, b.Bytes()) {
316			t.Errorf("string enc instructions: expected % x got % x", bytesResult, b.Bytes())
317		}
318	}
319}
320
321func execDec(typ string, instr *decInstr, state *decoderState, t *testing.T, p unsafe.Pointer) {
322	defer testError(t)
323	v := int(state.decodeUint())
324	if v+state.fieldnum != 6 {
325		t.Fatalf("decoding field number %d, got %d", 6, v+state.fieldnum)
326	}
327	instr.op(instr, state, decIndirect(p, instr.indir))
328	state.fieldnum = 6
329}
330
331func newDecodeStateFromData(data []byte) *decoderState {
332	b := bytes.NewBuffer(data)
333	state := newDecodeState(b)
334	state.fieldnum = -1
335	return state
336}
337
338// Test instruction execution for decoding.
339// Do not run the machine yet; instead do individual instructions crafted by hand.
340func TestScalarDecInstructions(t *testing.T) {
341	ovfl := errors.New("overflow")
342
343	// bool
344	{
345		var data struct {
346			a bool
347		}
348		instr := &decInstr{decBool, 6, 0, 0, ovfl}
349		state := newDecodeStateFromData(boolResult)
350		execDec("bool", instr, state, t, unsafe.Pointer(&data))
351		if data.a != true {
352			t.Errorf("bool a = %v not true", data.a)
353		}
354	}
355	// int
356	{
357		var data struct {
358			a int
359		}
360		instr := &decInstr{decOpTable[reflect.Int], 6, 0, 0, ovfl}
361		state := newDecodeStateFromData(signedResult)
362		execDec("int", instr, state, t, unsafe.Pointer(&data))
363		if data.a != 17 {
364			t.Errorf("int a = %v not 17", data.a)
365		}
366	}
367
368	// uint
369	{
370		var data struct {
371			a uint
372		}
373		instr := &decInstr{decOpTable[reflect.Uint], 6, 0, 0, ovfl}
374		state := newDecodeStateFromData(unsignedResult)
375		execDec("uint", instr, state, t, unsafe.Pointer(&data))
376		if data.a != 17 {
377			t.Errorf("uint a = %v not 17", data.a)
378		}
379	}
380
381	// int8
382	{
383		var data struct {
384			a int8
385		}
386		instr := &decInstr{decInt8, 6, 0, 0, ovfl}
387		state := newDecodeStateFromData(signedResult)
388		execDec("int8", instr, state, t, unsafe.Pointer(&data))
389		if data.a != 17 {
390			t.Errorf("int8 a = %v not 17", data.a)
391		}
392	}
393
394	// uint8
395	{
396		var data struct {
397			a uint8
398		}
399		instr := &decInstr{decUint8, 6, 0, 0, ovfl}
400		state := newDecodeStateFromData(unsignedResult)
401		execDec("uint8", instr, state, t, unsafe.Pointer(&data))
402		if data.a != 17 {
403			t.Errorf("uint8 a = %v not 17", data.a)
404		}
405	}
406
407	// int16
408	{
409		var data struct {
410			a int16
411		}
412		instr := &decInstr{decInt16, 6, 0, 0, ovfl}
413		state := newDecodeStateFromData(signedResult)
414		execDec("int16", instr, state, t, unsafe.Pointer(&data))
415		if data.a != 17 {
416			t.Errorf("int16 a = %v not 17", data.a)
417		}
418	}
419
420	// uint16
421	{
422		var data struct {
423			a uint16
424		}
425		instr := &decInstr{decUint16, 6, 0, 0, ovfl}
426		state := newDecodeStateFromData(unsignedResult)
427		execDec("uint16", instr, state, t, unsafe.Pointer(&data))
428		if data.a != 17 {
429			t.Errorf("uint16 a = %v not 17", data.a)
430		}
431	}
432
433	// int32
434	{
435		var data struct {
436			a int32
437		}
438		instr := &decInstr{decInt32, 6, 0, 0, ovfl}
439		state := newDecodeStateFromData(signedResult)
440		execDec("int32", instr, state, t, unsafe.Pointer(&data))
441		if data.a != 17 {
442			t.Errorf("int32 a = %v not 17", data.a)
443		}
444	}
445
446	// uint32
447	{
448		var data struct {
449			a uint32
450		}
451		instr := &decInstr{decUint32, 6, 0, 0, ovfl}
452		state := newDecodeStateFromData(unsignedResult)
453		execDec("uint32", instr, state, t, unsafe.Pointer(&data))
454		if data.a != 17 {
455			t.Errorf("uint32 a = %v not 17", data.a)
456		}
457	}
458
459	// uintptr
460	{
461		var data struct {
462			a uintptr
463		}
464		instr := &decInstr{decOpTable[reflect.Uintptr], 6, 0, 0, ovfl}
465		state := newDecodeStateFromData(unsignedResult)
466		execDec("uintptr", instr, state, t, unsafe.Pointer(&data))
467		if data.a != 17 {
468			t.Errorf("uintptr a = %v not 17", data.a)
469		}
470	}
471
472	// int64
473	{
474		var data struct {
475			a int64
476		}
477		instr := &decInstr{decInt64, 6, 0, 0, ovfl}
478		state := newDecodeStateFromData(signedResult)
479		execDec("int64", instr, state, t, unsafe.Pointer(&data))
480		if data.a != 17 {
481			t.Errorf("int64 a = %v not 17", data.a)
482		}
483	}
484
485	// uint64
486	{
487		var data struct {
488			a uint64
489		}
490		instr := &decInstr{decUint64, 6, 0, 0, ovfl}
491		state := newDecodeStateFromData(unsignedResult)
492		execDec("uint64", instr, state, t, unsafe.Pointer(&data))
493		if data.a != 17 {
494			t.Errorf("uint64 a = %v not 17", data.a)
495		}
496	}
497
498	// float32
499	{
500		var data struct {
501			a float32
502		}
503		instr := &decInstr{decFloat32, 6, 0, 0, ovfl}
504		state := newDecodeStateFromData(floatResult)
505		execDec("float32", instr, state, t, unsafe.Pointer(&data))
506		if data.a != 17 {
507			t.Errorf("float32 a = %v not 17", data.a)
508		}
509	}
510
511	// float64
512	{
513		var data struct {
514			a float64
515		}
516		instr := &decInstr{decFloat64, 6, 0, 0, ovfl}
517		state := newDecodeStateFromData(floatResult)
518		execDec("float64", instr, state, t, unsafe.Pointer(&data))
519		if data.a != 17 {
520			t.Errorf("float64 a = %v not 17", data.a)
521		}
522	}
523
524	// complex64
525	{
526		var data struct {
527			a complex64
528		}
529		instr := &decInstr{decOpTable[reflect.Complex64], 6, 0, 0, ovfl}
530		state := newDecodeStateFromData(complexResult)
531		execDec("complex", instr, state, t, unsafe.Pointer(&data))
532		if data.a != 17+19i {
533			t.Errorf("complex a = %v not 17+19i", data.a)
534		}
535	}
536
537	// complex128
538	{
539		var data struct {
540			a complex128
541		}
542		instr := &decInstr{decOpTable[reflect.Complex128], 6, 0, 0, ovfl}
543		state := newDecodeStateFromData(complexResult)
544		execDec("complex", instr, state, t, unsafe.Pointer(&data))
545		if data.a != 17+19i {
546			t.Errorf("complex a = %v not 17+19i", data.a)
547		}
548	}
549
550	// bytes == []uint8
551	{
552		var data struct {
553			a []byte
554		}
555		instr := &decInstr{decUint8Slice, 6, 0, 0, ovfl}
556		state := newDecodeStateFromData(bytesResult)
557		execDec("bytes", instr, state, t, unsafe.Pointer(&data))
558		if string(data.a) != "hello" {
559			t.Errorf(`bytes a = %q not "hello"`, string(data.a))
560		}
561	}
562
563	// string
564	{
565		var data struct {
566			a string
567		}
568		instr := &decInstr{decString, 6, 0, 0, ovfl}
569		state := newDecodeStateFromData(bytesResult)
570		execDec("bytes", instr, state, t, unsafe.Pointer(&data))
571		if data.a != "hello" {
572			t.Errorf(`bytes a = %q not "hello"`, data.a)
573		}
574	}
575}
576
577func TestEndToEnd(t *testing.T) {
578	type T2 struct {
579		T string
580	}
581	s1 := "string1"
582	s2 := "string2"
583	type T1 struct {
584		A, B, C  int
585		M        map[string]*float64
586		EmptyMap map[string]int // to check that we receive a non-nil map.
587		N        *[3]float64
588		Strs     *[2]string
589		Int64s   *[]int64
590		RI       complex64
591		S        string
592		Y        []byte
593		T        *T2
594	}
595	pi := 3.14159
596	e := 2.71828
597	t1 := &T1{
598		A:        17,
599		B:        18,
600		C:        -5,
601		M:        map[string]*float64{"pi": &pi, "e": &e},
602		EmptyMap: make(map[string]int),
603		N:        &[3]float64{1.5, 2.5, 3.5},
604		Strs:     &[2]string{s1, s2},
605		Int64s:   &[]int64{77, 89, 123412342134},
606		RI:       17 - 23i,
607		S:        "Now is the time",
608		Y:        []byte("hello, sailor"),
609		T:        &T2{"this is T2"},
610	}
611	b := new(bytes.Buffer)
612	err := NewEncoder(b).Encode(t1)
613	if err != nil {
614		t.Error("encode:", err)
615	}
616	var _t1 T1
617	err = NewDecoder(b).Decode(&_t1)
618	if err != nil {
619		t.Fatal("decode:", err)
620	}
621	if !reflect.DeepEqual(t1, &_t1) {
622		t.Errorf("encode expected %v got %v", *t1, _t1)
623	}
624	// Be absolutely sure the received map is non-nil.
625	if t1.EmptyMap == nil {
626		t.Errorf("nil map sent")
627	}
628	if _t1.EmptyMap == nil {
629		t.Errorf("nil map received")
630	}
631}
632
633func TestOverflow(t *testing.T) {
634	type inputT struct {
635		Maxi int64
636		Mini int64
637		Maxu uint64
638		Maxf float64
639		Minf float64
640		Maxc complex128
641		Minc complex128
642	}
643	var it inputT
644	var err error
645	b := new(bytes.Buffer)
646	enc := NewEncoder(b)
647	dec := NewDecoder(b)
648
649	// int8
650	b.Reset()
651	it = inputT{
652		Maxi: math.MaxInt8 + 1,
653	}
654	type outi8 struct {
655		Maxi int8
656		Mini int8
657	}
658	var o1 outi8
659	enc.Encode(it)
660	err = dec.Decode(&o1)
661	if err == nil || err.Error() != `value for "Maxi" out of range` {
662		t.Error("wrong overflow error for int8:", err)
663	}
664	it = inputT{
665		Mini: math.MinInt8 - 1,
666	}
667	b.Reset()
668	enc.Encode(it)
669	err = dec.Decode(&o1)
670	if err == nil || err.Error() != `value for "Mini" out of range` {
671		t.Error("wrong underflow error for int8:", err)
672	}
673
674	// int16
675	b.Reset()
676	it = inputT{
677		Maxi: math.MaxInt16 + 1,
678	}
679	type outi16 struct {
680		Maxi int16
681		Mini int16
682	}
683	var o2 outi16
684	enc.Encode(it)
685	err = dec.Decode(&o2)
686	if err == nil || err.Error() != `value for "Maxi" out of range` {
687		t.Error("wrong overflow error for int16:", err)
688	}
689	it = inputT{
690		Mini: math.MinInt16 - 1,
691	}
692	b.Reset()
693	enc.Encode(it)
694	err = dec.Decode(&o2)
695	if err == nil || err.Error() != `value for "Mini" out of range` {
696		t.Error("wrong underflow error for int16:", err)
697	}
698
699	// int32
700	b.Reset()
701	it = inputT{
702		Maxi: math.MaxInt32 + 1,
703	}
704	type outi32 struct {
705		Maxi int32
706		Mini int32
707	}
708	var o3 outi32
709	enc.Encode(it)
710	err = dec.Decode(&o3)
711	if err == nil || err.Error() != `value for "Maxi" out of range` {
712		t.Error("wrong overflow error for int32:", err)
713	}
714	it = inputT{
715		Mini: math.MinInt32 - 1,
716	}
717	b.Reset()
718	enc.Encode(it)
719	err = dec.Decode(&o3)
720	if err == nil || err.Error() != `value for "Mini" out of range` {
721		t.Error("wrong underflow error for int32:", err)
722	}
723
724	// uint8
725	b.Reset()
726	it = inputT{
727		Maxu: math.MaxUint8 + 1,
728	}
729	type outu8 struct {
730		Maxu uint8
731	}
732	var o4 outu8
733	enc.Encode(it)
734	err = dec.Decode(&o4)
735	if err == nil || err.Error() != `value for "Maxu" out of range` {
736		t.Error("wrong overflow error for uint8:", err)
737	}
738
739	// uint16
740	b.Reset()
741	it = inputT{
742		Maxu: math.MaxUint16 + 1,
743	}
744	type outu16 struct {
745		Maxu uint16
746	}
747	var o5 outu16
748	enc.Encode(it)
749	err = dec.Decode(&o5)
750	if err == nil || err.Error() != `value for "Maxu" out of range` {
751		t.Error("wrong overflow error for uint16:", err)
752	}
753
754	// uint32
755	b.Reset()
756	it = inputT{
757		Maxu: math.MaxUint32 + 1,
758	}
759	type outu32 struct {
760		Maxu uint32
761	}
762	var o6 outu32
763	enc.Encode(it)
764	err = dec.Decode(&o6)
765	if err == nil || err.Error() != `value for "Maxu" out of range` {
766		t.Error("wrong overflow error for uint32:", err)
767	}
768
769	// float32
770	b.Reset()
771	it = inputT{
772		Maxf: math.MaxFloat32 * 2,
773	}
774	type outf32 struct {
775		Maxf float32
776		Minf float32
777	}
778	var o7 outf32
779	enc.Encode(it)
780	err = dec.Decode(&o7)
781	if err == nil || err.Error() != `value for "Maxf" out of range` {
782		t.Error("wrong overflow error for float32:", err)
783	}
784
785	// complex64
786	b.Reset()
787	it = inputT{
788		Maxc: complex(math.MaxFloat32*2, math.MaxFloat32*2),
789	}
790	type outc64 struct {
791		Maxc complex64
792		Minc complex64
793	}
794	var o8 outc64
795	enc.Encode(it)
796	err = dec.Decode(&o8)
797	if err == nil || err.Error() != `value for "Maxc" out of range` {
798		t.Error("wrong overflow error for complex64:", err)
799	}
800}
801
802func TestNesting(t *testing.T) {
803	type RT struct {
804		A    string
805		Next *RT
806	}
807	rt := new(RT)
808	rt.A = "level1"
809	rt.Next = new(RT)
810	rt.Next.A = "level2"
811	b := new(bytes.Buffer)
812	NewEncoder(b).Encode(rt)
813	var drt RT
814	dec := NewDecoder(b)
815	err := dec.Decode(&drt)
816	if err != nil {
817		t.Fatal("decoder error:", err)
818	}
819	if drt.A != rt.A {
820		t.Errorf("nesting: encode expected %v got %v", *rt, drt)
821	}
822	if drt.Next == nil {
823		t.Errorf("nesting: recursion failed")
824	}
825	if drt.Next.A != rt.Next.A {
826		t.Errorf("nesting: encode expected %v got %v", *rt.Next, *drt.Next)
827	}
828}
829
830// These three structures have the same data with different indirections
831type T0 struct {
832	A int
833	B int
834	C int
835	D int
836}
837type T1 struct {
838	A int
839	B *int
840	C **int
841	D ***int
842}
843type T2 struct {
844	A ***int
845	B **int
846	C *int
847	D int
848}
849
850func TestAutoIndirection(t *testing.T) {
851	// First transfer t1 into t0
852	var t1 T1
853	t1.A = 17
854	t1.B = new(int)
855	*t1.B = 177
856	t1.C = new(*int)
857	*t1.C = new(int)
858	**t1.C = 1777
859	t1.D = new(**int)
860	*t1.D = new(*int)
861	**t1.D = new(int)
862	***t1.D = 17777
863	b := new(bytes.Buffer)
864	enc := NewEncoder(b)
865	enc.Encode(t1)
866	dec := NewDecoder(b)
867	var t0 T0
868	dec.Decode(&t0)
869	if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {
870		t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0)
871	}
872
873	// Now transfer t2 into t0
874	var t2 T2
875	t2.D = 17777
876	t2.C = new(int)
877	*t2.C = 1777
878	t2.B = new(*int)
879	*t2.B = new(int)
880	**t2.B = 177
881	t2.A = new(**int)
882	*t2.A = new(*int)
883	**t2.A = new(int)
884	***t2.A = 17
885	b.Reset()
886	enc.Encode(t2)
887	t0 = T0{}
888	dec.Decode(&t0)
889	if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {
890		t.Errorf("t2->t0 expected {17 177 1777 17777}; got %v", t0)
891	}
892
893	// Now transfer t0 into t1
894	t0 = T0{17, 177, 1777, 17777}
895	b.Reset()
896	enc.Encode(t0)
897	t1 = T1{}
898	dec.Decode(&t1)
899	if t1.A != 17 || *t1.B != 177 || **t1.C != 1777 || ***t1.D != 17777 {
900		t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.A, *t1.B, **t1.C, ***t1.D)
901	}
902
903	// Now transfer t0 into t2
904	b.Reset()
905	enc.Encode(t0)
906	t2 = T2{}
907	dec.Decode(&t2)
908	if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {
909		t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)
910	}
911
912	// Now do t2 again but without pre-allocated pointers.
913	b.Reset()
914	enc.Encode(t0)
915	***t2.A = 0
916	**t2.B = 0
917	*t2.C = 0
918	t2.D = 0
919	dec.Decode(&t2)
920	if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {
921		t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)
922	}
923}
924
925type RT0 struct {
926	A int
927	B string
928	C float64
929}
930type RT1 struct {
931	C      float64
932	B      string
933	A      int
934	NotSet string
935}
936
937func TestReorderedFields(t *testing.T) {
938	var rt0 RT0
939	rt0.A = 17
940	rt0.B = "hello"
941	rt0.C = 3.14159
942	b := new(bytes.Buffer)
943	NewEncoder(b).Encode(rt0)
944	dec := NewDecoder(b)
945	var rt1 RT1
946	// Wire type is RT0, local type is RT1.
947	err := dec.Decode(&rt1)
948	if err != nil {
949		t.Fatal("decode error:", err)
950	}
951	if rt0.A != rt1.A || rt0.B != rt1.B || rt0.C != rt1.C {
952		t.Errorf("rt1->rt0: expected %v; got %v", rt0, rt1)
953	}
954}
955
956// Like an RT0 but with fields we'll ignore on the decode side.
957type IT0 struct {
958	A        int64
959	B        string
960	Ignore_d []int
961	Ignore_e [3]float64
962	Ignore_f bool
963	Ignore_g string
964	Ignore_h []byte
965	Ignore_i *RT1
966	Ignore_m map[string]int
967	C        float64
968}
969
970func TestIgnoredFields(t *testing.T) {
971	var it0 IT0
972	it0.A = 17
973	it0.B = "hello"
974	it0.C = 3.14159
975	it0.Ignore_d = []int{1, 2, 3}
976	it0.Ignore_e[0] = 1.0
977	it0.Ignore_e[1] = 2.0
978	it0.Ignore_e[2] = 3.0
979	it0.Ignore_f = true
980	it0.Ignore_g = "pay no attention"
981	it0.Ignore_h = []byte("to the curtain")
982	it0.Ignore_i = &RT1{3.1, "hi", 7, "hello"}
983	it0.Ignore_m = map[string]int{"one": 1, "two": 2}
984
985	b := new(bytes.Buffer)
986	NewEncoder(b).Encode(it0)
987	dec := NewDecoder(b)
988	var rt1 RT1
989	// Wire type is IT0, local type is RT1.
990	err := dec.Decode(&rt1)
991	if err != nil {
992		t.Error("error: ", err)
993	}
994	if int(it0.A) != rt1.A || it0.B != rt1.B || it0.C != rt1.C {
995		t.Errorf("rt0->rt1: expected %v; got %v", it0, rt1)
996	}
997}
998
999func TestBadRecursiveType(t *testing.T) {
1000	type Rec ***Rec
1001	var rec Rec
1002	b := new(bytes.Buffer)
1003	err := NewEncoder(b).Encode(&rec)
1004	if err == nil {
1005		t.Error("expected error; got none")
1006	} else if strings.Index(err.Error(), "recursive") < 0 {
1007		t.Error("expected recursive type error; got", err)
1008	}
1009	// Can't test decode easily because we can't encode one, so we can't pass one to a Decoder.
1010}
1011
1012type Bad0 struct {
1013	CH chan int
1014	C  float64
1015}
1016
1017func TestInvalidField(t *testing.T) {
1018	var bad0 Bad0
1019	bad0.CH = make(chan int)
1020	b := new(bytes.Buffer)
1021	dummyEncoder := new(Encoder) // sufficient for this purpose.
1022	dummyEncoder.encode(b, reflect.ValueOf(&bad0), userType(reflect.TypeOf(&bad0)))
1023	if err := dummyEncoder.err; err == nil {
1024		t.Error("expected error; got none")
1025	} else if strings.Index(err.Error(), "type") < 0 {
1026		t.Error("expected type error; got", err)
1027	}
1028}
1029
1030type Indirect struct {
1031	A ***[3]int
1032	S ***[]int
1033	M ****map[string]int
1034}
1035
1036type Direct struct {
1037	A [3]int
1038	S []int
1039	M map[string]int
1040}
1041
1042func TestIndirectSliceMapArray(t *testing.T) {
1043	// Marshal indirect, unmarshal to direct.
1044	i := new(Indirect)
1045	i.A = new(**[3]int)
1046	*i.A = new(*[3]int)
1047	**i.A = new([3]int)
1048	***i.A = [3]int{1, 2, 3}
1049	i.S = new(**[]int)
1050	*i.S = new(*[]int)
1051	**i.S = new([]int)
1052	***i.S = []int{4, 5, 6}
1053	i.M = new(***map[string]int)
1054	*i.M = new(**map[string]int)
1055	**i.M = new(*map[string]int)
1056	***i.M = new(map[string]int)
1057	****i.M = map[string]int{"one": 1, "two": 2, "three": 3}
1058	b := new(bytes.Buffer)
1059	NewEncoder(b).Encode(i)
1060	dec := NewDecoder(b)
1061	var d Direct
1062	err := dec.Decode(&d)
1063	if err != nil {
1064		t.Error("error: ", err)
1065	}
1066	if len(d.A) != 3 || d.A[0] != 1 || d.A[1] != 2 || d.A[2] != 3 {
1067		t.Errorf("indirect to direct: d.A is %v not %v", d.A, ***i.A)
1068	}
1069	if len(d.S) != 3 || d.S[0] != 4 || d.S[1] != 5 || d.S[2] != 6 {
1070		t.Errorf("indirect to direct: d.S is %v not %v", d.S, ***i.S)
1071	}
1072	if len(d.M) != 3 || d.M["one"] != 1 || d.M["two"] != 2 || d.M["three"] != 3 {
1073		t.Errorf("indirect to direct: d.M is %v not %v", d.M, ***i.M)
1074	}
1075	// Marshal direct, unmarshal to indirect.
1076	d.A = [3]int{11, 22, 33}
1077	d.S = []int{44, 55, 66}
1078	d.M = map[string]int{"four": 4, "five": 5, "six": 6}
1079	i = new(Indirect)
1080	b.Reset()
1081	NewEncoder(b).Encode(d)
1082	dec = NewDecoder(b)
1083	err = dec.Decode(&i)
1084	if err != nil {
1085		t.Fatal("error: ", err)
1086	}
1087	if len(***i.A) != 3 || (***i.A)[0] != 11 || (***i.A)[1] != 22 || (***i.A)[2] != 33 {
1088		t.Errorf("direct to indirect: ***i.A is %v not %v", ***i.A, d.A)
1089	}
1090	if len(***i.S) != 3 || (***i.S)[0] != 44 || (***i.S)[1] != 55 || (***i.S)[2] != 66 {
1091		t.Errorf("direct to indirect: ***i.S is %v not %v", ***i.S, ***i.S)
1092	}
1093	if len(****i.M) != 3 || (****i.M)["four"] != 4 || (****i.M)["five"] != 5 || (****i.M)["six"] != 6 {
1094		t.Errorf("direct to indirect: ****i.M is %v not %v", ****i.M, d.M)
1095	}
1096}
1097
1098// An interface with several implementations
1099type Squarer interface {
1100	Square() int
1101}
1102
1103type Int int
1104
1105func (i Int) Square() int {
1106	return int(i * i)
1107}
1108
1109type Float float64
1110
1111func (f Float) Square() int {
1112	return int(f * f)
1113}
1114
1115type Vector []int
1116
1117func (v Vector) Square() int {
1118	sum := 0
1119	for _, x := range v {
1120		sum += x * x
1121	}
1122	return sum
1123}
1124
1125type Point struct {
1126	X, Y int
1127}
1128
1129func (p Point) Square() int {
1130	return p.X*p.X + p.Y*p.Y
1131}
1132
1133// A struct with interfaces in it.
1134type InterfaceItem struct {
1135	I             int
1136	Sq1, Sq2, Sq3 Squarer
1137	F             float64
1138	Sq            []Squarer
1139}
1140
1141// The same struct without interfaces
1142type NoInterfaceItem struct {
1143	I int
1144	F float64
1145}
1146
1147func TestInterface(t *testing.T) {
1148	iVal := Int(3)
1149	fVal := Float(5)
1150	// Sending a Vector will require that the receiver define a type in the middle of
1151	// receiving the value for item2.
1152	vVal := Vector{1, 2, 3}
1153	b := new(bytes.Buffer)
1154	item1 := &InterfaceItem{1, iVal, fVal, vVal, 11.5, []Squarer{iVal, fVal, nil, vVal}}
1155	// Register the types.
1156	Register(Int(0))
1157	Register(Float(0))
1158	Register(Vector{})
1159	err := NewEncoder(b).Encode(item1)
1160	if err != nil {
1161		t.Error("expected no encode error; got", err)
1162	}
1163
1164	item2 := InterfaceItem{}
1165	err = NewDecoder(b).Decode(&item2)
1166	if err != nil {
1167		t.Fatal("decode:", err)
1168	}
1169	if item2.I != item1.I {
1170		t.Error("normal int did not decode correctly")
1171	}
1172	if item2.Sq1 == nil || item2.Sq1.Square() != iVal.Square() {
1173		t.Error("Int did not decode correctly")
1174	}
1175	if item2.Sq2 == nil || item2.Sq2.Square() != fVal.Square() {
1176		t.Error("Float did not decode correctly")
1177	}
1178	if item2.Sq3 == nil || item2.Sq3.Square() != vVal.Square() {
1179		t.Error("Vector did not decode correctly")
1180	}
1181	if item2.F != item1.F {
1182		t.Error("normal float did not decode correctly")
1183	}
1184	// Now check that we received a slice of Squarers correctly, including a nil element
1185	if len(item1.Sq) != len(item2.Sq) {
1186		t.Fatalf("[]Squarer length wrong: got %d; expected %d", len(item2.Sq), len(item1.Sq))
1187	}
1188	for i, v1 := range item1.Sq {
1189		v2 := item2.Sq[i]
1190		if v1 == nil || v2 == nil {
1191			if v1 != nil || v2 != nil {
1192				t.Errorf("item %d inconsistent nils", i)
1193			}
1194		} else if v1.Square() != v2.Square() {
1195			t.Errorf("item %d inconsistent values: %v %v", i, v1, v2)
1196		}
1197	}
1198}
1199
1200// A struct with all basic types, stored in interfaces.
1201type BasicInterfaceItem struct {
1202	Int, Int8, Int16, Int32, Int64      interface{}
1203	Uint, Uint8, Uint16, Uint32, Uint64 interface{}
1204	Float32, Float64                    interface{}
1205	Complex64, Complex128               interface{}
1206	Bool                                interface{}
1207	String                              interface{}
1208	Bytes                               interface{}
1209}
1210
1211func TestInterfaceBasic(t *testing.T) {
1212	b := new(bytes.Buffer)
1213	item1 := &BasicInterfaceItem{
1214		int(1), int8(1), int16(1), int32(1), int64(1),
1215		uint(1), uint8(1), uint16(1), uint32(1), uint64(1),
1216		float32(1), 1.0,
1217		complex64(1i), complex128(1i),
1218		true,
1219		"hello",
1220		[]byte("sailor"),
1221	}
1222	err := NewEncoder(b).Encode(item1)
1223	if err != nil {
1224		t.Error("expected no encode error; got", err)
1225	}
1226
1227	item2 := &BasicInterfaceItem{}
1228	err = NewDecoder(b).Decode(&item2)
1229	if err != nil {
1230		t.Fatal("decode:", err)
1231	}
1232	if !reflect.DeepEqual(item1, item2) {
1233		t.Errorf("encode expected %v got %v", item1, item2)
1234	}
1235	// Hand check a couple for correct types.
1236	if v, ok := item2.Bool.(bool); !ok || !v {
1237		t.Error("boolean should be true")
1238	}
1239	if v, ok := item2.String.(string); !ok || v != item1.String.(string) {
1240		t.Errorf("string should be %v is %v", item1.String, v)
1241	}
1242}
1243
1244type String string
1245
1246type PtrInterfaceItem struct {
1247	Str1 interface{} // basic
1248	Str2 interface{} // derived
1249}
1250
1251// We'll send pointers; should receive values.
1252// Also check that we can register T but send *T.
1253func TestInterfacePointer(t *testing.T) {
1254	b := new(bytes.Buffer)
1255	str1 := "howdy"
1256	str2 := String("kiddo")
1257	item1 := &PtrInterfaceItem{
1258		&str1,
1259		&str2,
1260	}
1261	// Register the type.
1262	Register(str2)
1263	err := NewEncoder(b).Encode(item1)
1264	if err != nil {
1265		t.Error("expected no encode error; got", err)
1266	}
1267
1268	item2 := &PtrInterfaceItem{}
1269	err = NewDecoder(b).Decode(&item2)
1270	if err != nil {
1271		t.Fatal("decode:", err)
1272	}
1273	// Hand test for correct types and values.
1274	if v, ok := item2.Str1.(string); !ok || v != str1 {
1275		t.Errorf("basic string failed: %q should be %q", v, str1)
1276	}
1277	if v, ok := item2.Str2.(String); !ok || v != str2 {
1278		t.Errorf("derived type String failed: %q should be %q", v, str2)
1279	}
1280}
1281
1282func TestIgnoreInterface(t *testing.T) {
1283	iVal := Int(3)
1284	fVal := Float(5)
1285	// Sending a Point will require that the receiver define a type in the middle of
1286	// receiving the value for item2.
1287	pVal := Point{2, 3}
1288	b := new(bytes.Buffer)
1289	item1 := &InterfaceItem{1, iVal, fVal, pVal, 11.5, nil}
1290	// Register the types.
1291	Register(Int(0))
1292	Register(Float(0))
1293	Register(Point{})
1294	err := NewEncoder(b).Encode(item1)
1295	if err != nil {
1296		t.Error("expected no encode error; got", err)
1297	}
1298
1299	item2 := NoInterfaceItem{}
1300	err = NewDecoder(b).Decode(&item2)
1301	if err != nil {
1302		t.Fatal("decode:", err)
1303	}
1304	if item2.I != item1.I {
1305		t.Error("normal int did not decode correctly")
1306	}
1307	if item2.F != item2.F {
1308		t.Error("normal float did not decode correctly")
1309	}
1310}
1311
1312type U struct {
1313	A int
1314	B string
1315	c float64
1316	D uint
1317}
1318
1319func TestUnexportedFields(t *testing.T) {
1320	var u0 U
1321	u0.A = 17
1322	u0.B = "hello"
1323	u0.c = 3.14159
1324	u0.D = 23
1325	b := new(bytes.Buffer)
1326	NewEncoder(b).Encode(u0)
1327	dec := NewDecoder(b)
1328	var u1 U
1329	u1.c = 1234.
1330	err := dec.Decode(&u1)
1331	if err != nil {
1332		t.Fatal("decode error:", err)
1333	}
1334	if u0.A != u0.A || u0.B != u1.B || u0.D != u1.D {
1335		t.Errorf("u1->u0: expected %v; got %v", u0, u1)
1336	}
1337	if u1.c != 1234. {
1338		t.Error("u1.c modified")
1339	}
1340}
1341
1342var singletons = []interface{}{
1343	true,
1344	7,
1345	3.2,
1346	"hello",
1347	[3]int{11, 22, 33},
1348	[]float32{0.5, 0.25, 0.125},
1349	map[string]int{"one": 1, "two": 2},
1350}
1351
1352func TestDebugSingleton(t *testing.T) {
1353	if debugFunc == nil {
1354		return
1355	}
1356	b := new(bytes.Buffer)
1357	// Accumulate a number of values and print them out all at once.
1358	for _, x := range singletons {
1359		err := NewEncoder(b).Encode(x)
1360		if err != nil {
1361			t.Fatal("encode:", err)
1362		}
1363	}
1364	debugFunc(b)
1365}
1366
1367// A type that won't be defined in the gob until we send it in an interface value.
1368type OnTheFly struct {
1369	A int
1370}
1371
1372type DT struct {
1373	//	X OnTheFly
1374	A     int
1375	B     string
1376	C     float64
1377	I     interface{}
1378	J     interface{}
1379	I_nil interface{}
1380	M     map[string]int
1381	T     [3]int
1382	S     []string
1383}
1384
1385func TestDebugStruct(t *testing.T) {
1386	if debugFunc == nil {
1387		return
1388	}
1389	Register(OnTheFly{})
1390	var dt DT
1391	dt.A = 17
1392	dt.B = "hello"
1393	dt.C = 3.14159
1394	dt.I = 271828
1395	dt.J = OnTheFly{3}
1396	dt.I_nil = nil
1397	dt.M = map[string]int{"one": 1, "two": 2}
1398	dt.T = [3]int{11, 22, 33}
1399	dt.S = []string{"hi", "joe"}
1400	b := new(bytes.Buffer)
1401	err := NewEncoder(b).Encode(dt)
1402	if err != nil {
1403		t.Fatal("encode:", err)
1404	}
1405	debugBuffer := bytes.NewBuffer(b.Bytes())
1406	dt2 := &DT{}
1407	err = NewDecoder(b).Decode(&dt2)
1408	if err != nil {
1409		t.Error("decode:", err)
1410	}
1411	debugFunc(debugBuffer)
1412}
1413
1414func encFuzzDec(rng *rand.Rand, in interface{}) error {
1415	buf := new(bytes.Buffer)
1416	enc := NewEncoder(buf)
1417	if err := enc.Encode(&in); err != nil {
1418		return err
1419	}
1420
1421	b := buf.Bytes()
1422	for i, bi := range b {
1423		if rng.Intn(10) < 3 {
1424			b[i] = bi + uint8(rng.Intn(256))
1425		}
1426	}
1427
1428	dec := NewDecoder(buf)
1429	var e interface{}
1430	if err := dec.Decode(&e); err != nil {
1431		return err
1432	}
1433	return nil
1434}
1435
1436// This does some "fuzz testing" by attempting to decode a sequence of random bytes.
1437func TestFuzz(t *testing.T) {
1438	if !*doFuzzTests {
1439		t.Logf("disabled; run with -gob.fuzz to enable")
1440		return
1441	}
1442
1443	// all possible inputs
1444	input := []interface{}{
1445		new(int),
1446		new(float32),
1447		new(float64),
1448		new(complex128),
1449		&ByteStruct{255},
1450		&ArrayStruct{},
1451		&StringStruct{"hello"},
1452		&GobTest1{0, &StringStruct{"hello"}},
1453	}
1454	testFuzz(t, time.Now().UnixNano(), 100, input...)
1455}
1456
1457func TestFuzzRegressions(t *testing.T) {
1458	if !*doFuzzTests {
1459		t.Logf("disabled; run with -gob.fuzz to enable")
1460		return
1461	}
1462
1463	// An instance triggering a type name of length ~102 GB.
1464	testFuzz(t, 1328492090837718000, 100, new(float32))
1465	// An instance triggering a type name of 1.6 GB.
1466	// Note: can take several minutes to run.
1467	testFuzz(t, 1330522872628565000, 100, new(int))
1468}
1469
1470func testFuzz(t *testing.T, seed int64, n int, input ...interface{}) {
1471	for _, e := range input {
1472		t.Logf("seed=%d n=%d e=%T", seed, n, e)
1473		rng := rand.New(rand.NewSource(seed))
1474		for i := 0; i < n; i++ {
1475			encFuzzDec(rng, e)
1476		}
1477	}
1478}
1479