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
5// Delete the next line to include in the gob package.
6//go:build ignore
7
8package gob
9
10// This file is not normally included in the gob package. Used only for debugging the package itself.
11// Except for reading uints, it is an implementation of a reader that is independent of
12// the one implemented by Decoder.
13// To enable the Debug function, delete the +build ignore line above and do
14//	go install
15
16import (
17	"bytes"
18	"fmt"
19	"io"
20	"os"
21	"strings"
22	"sync"
23)
24
25var dumpBytes = false // If true, print the remaining bytes in the input buffer at each item.
26
27// Init installs the debugging facility. If this file is not compiled in the
28// package, the tests in codec_test.go are no-ops.
29func init() {
30	debugFunc = Debug
31}
32
33var (
34	blanks = bytes.Repeat([]byte{' '}, 3*10)
35	empty  = []byte(": <empty>\n")
36	tabs   = strings.Repeat("\t", 100)
37)
38
39// tab indents itself when printed.
40type tab int
41
42func (t tab) String() string {
43	n := int(t)
44	if n > len(tabs) {
45		n = len(tabs)
46	}
47	return tabs[0:n]
48}
49
50func (t tab) print() {
51	fmt.Fprint(os.Stderr, t)
52}
53
54// A peekReader wraps an io.Reader, allowing one to peek ahead to see
55// what's coming without stealing the data from the client of the Reader.
56type peekReader struct {
57	r    io.Reader
58	data []byte // read-ahead data
59}
60
61// newPeekReader returns a peekReader that wraps r.
62func newPeekReader(r io.Reader) *peekReader {
63	return &peekReader{r: r}
64}
65
66// Read is the usual method. It will first take data that has been read ahead.
67func (p *peekReader) Read(b []byte) (n int, err error) {
68	if len(p.data) == 0 {
69		return p.r.Read(b)
70	}
71	// Satisfy what's possible from the read-ahead data.
72	n = copy(b, p.data)
73	// Move data down to beginning of slice, to avoid endless growth
74	copy(p.data, p.data[n:])
75	p.data = p.data[:len(p.data)-n]
76	return
77}
78
79// peek returns as many bytes as possible from the unread
80// portion of the stream, up to the length of b.
81func (p *peekReader) peek(b []byte) (n int, err error) {
82	if len(p.data) > 0 {
83		n = copy(b, p.data)
84		if n == len(b) {
85			return
86		}
87		b = b[n:]
88	}
89	if len(b) == 0 {
90		return
91	}
92	m, e := io.ReadFull(p.r, b)
93	if m > 0 {
94		p.data = append(p.data, b[:m]...)
95	}
96	n += m
97	if e == io.ErrUnexpectedEOF {
98		// That means m > 0 but we reached EOF. If we got data
99		// we won't complain about not being able to peek enough.
100		if n > 0 {
101			e = nil
102		} else {
103			e = io.EOF
104		}
105	}
106	return n, e
107}
108
109type debugger struct {
110	mutex          sync.Mutex
111	remain         int  // the number of bytes known to remain in the input
112	remainingKnown bool // the value of 'remain' is valid
113	r              *peekReader
114	wireType       map[typeId]*wireType
115	tmp            []byte // scratch space for decoding uints.
116}
117
118// dump prints the next nBytes of the input.
119// It arranges to print the output aligned from call to
120// call, to make it easy to see what has been consumed.
121func (deb *debugger) dump(format string, args ...any) {
122	if !dumpBytes {
123		return
124	}
125	fmt.Fprintf(os.Stderr, format+" ", args...)
126	if !deb.remainingKnown {
127		return
128	}
129	if deb.remain < 0 {
130		fmt.Fprintf(os.Stderr, "remaining byte count is negative! %d\n", deb.remain)
131		return
132	}
133	data := make([]byte, deb.remain)
134	n, _ := deb.r.peek(data)
135	if n == 0 {
136		os.Stderr.Write(empty)
137		return
138	}
139	b := new(bytes.Buffer)
140	fmt.Fprintf(b, "[%d]{\n", deb.remain)
141	// Blanks until first byte
142	lineLength := 0
143	if n := len(data); n%10 != 0 {
144		lineLength = 10 - n%10
145		fmt.Fprintf(b, "\t%s", blanks[:lineLength*3])
146	}
147	// 10 bytes per line
148	for len(data) > 0 {
149		if lineLength == 0 {
150			fmt.Fprint(b, "\t")
151		}
152		m := 10 - lineLength
153		lineLength = 0
154		if m > len(data) {
155			m = len(data)
156		}
157		fmt.Fprintf(b, "% x\n", data[:m])
158		data = data[m:]
159	}
160	fmt.Fprint(b, "}\n")
161	os.Stderr.Write(b.Bytes())
162}
163
164// Debug prints a human-readable representation of the gob data read from r.
165// It is a no-op unless debugging was enabled when the package was built.
166func Debug(r io.Reader) {
167	err := debug(r)
168	if err != nil {
169		fmt.Fprintf(os.Stderr, "gob debug: %s\n", err)
170	}
171}
172
173// debug implements Debug, but catches panics and returns
174// them as errors to be printed by Debug.
175func debug(r io.Reader) (err error) {
176	defer catchError(&err)
177	fmt.Fprintln(os.Stderr, "Start of debugging")
178	deb := &debugger{
179		r:        newPeekReader(r),
180		wireType: make(map[typeId]*wireType),
181		tmp:      make([]byte, 16),
182	}
183	if b, ok := r.(*bytes.Buffer); ok {
184		deb.remain = b.Len()
185		deb.remainingKnown = true
186	}
187	deb.gobStream()
188	return
189}
190
191// note that we've consumed some bytes
192func (deb *debugger) consumed(n int) {
193	if deb.remainingKnown {
194		deb.remain -= n
195	}
196}
197
198// int64 decodes and returns the next integer, which must be present.
199// Don't call this if you could be at EOF.
200func (deb *debugger) int64() int64 {
201	return toInt(deb.uint64())
202}
203
204// uint64 returns and decodes the next unsigned integer, which must be present.
205// Don't call this if you could be at EOF.
206// TODO: handle errors better.
207func (deb *debugger) uint64() uint64 {
208	n, w, err := decodeUintReader(deb.r, deb.tmp)
209	if err != nil {
210		errorf("debug: read error: %s", err)
211	}
212	deb.consumed(w)
213	return n
214}
215
216// GobStream:
217//	DelimitedMessage* (until EOF)
218func (deb *debugger) gobStream() {
219	// Make sure we're single-threaded through here.
220	deb.mutex.Lock()
221	defer deb.mutex.Unlock()
222
223	for deb.delimitedMessage(0) {
224	}
225}
226
227// DelimitedMessage:
228//	uint(lengthOfMessage) Message
229func (deb *debugger) delimitedMessage(indent tab) bool {
230	for {
231		n := deb.loadBlock(true)
232		if n < 0 {
233			return false
234		}
235		deb.dump("Delimited message of length %d", n)
236		deb.message(indent)
237	}
238	return true
239}
240
241// loadBlock preps us to read a message
242// of the length specified next in the input. It returns
243// the length of the block. The argument tells whether
244// an EOF is acceptable now. If it is and one is found,
245// the return value is negative.
246func (deb *debugger) loadBlock(eofOK bool) int {
247	n64, w, err := decodeUintReader(deb.r, deb.tmp) // deb.uint64 will error at EOF
248	if err != nil {
249		if eofOK && err == io.EOF {
250			return -1
251		}
252		errorf("debug: unexpected error: %s", err)
253	}
254	deb.consumed(w)
255	n := int(n64)
256	if n < 0 {
257		errorf("huge value for message length: %d", n64)
258	}
259	return int(n)
260}
261
262// Message:
263//	TypeSequence TypedValue
264// TypeSequence
265//	(TypeDefinition DelimitedTypeDefinition*)?
266// DelimitedTypeDefinition:
267//	uint(lengthOfTypeDefinition) TypeDefinition
268// TypedValue:
269//	int(typeId) Value
270func (deb *debugger) message(indent tab) bool {
271	for {
272		// Convert the uint64 to a signed integer typeId
273		uid := deb.int64()
274		id := typeId(uid)
275		deb.dump("type id=%d", id)
276		if id < 0 {
277			deb.typeDefinition(indent, -id)
278			n := deb.loadBlock(false)
279			deb.dump("Message of length %d", n)
280			continue
281		} else {
282			deb.value(indent, id)
283			break
284		}
285	}
286	return true
287}
288
289// Helper methods to make it easy to scan a type descriptor.
290
291// common returns the CommonType at the input point.
292func (deb *debugger) common() CommonType {
293	fieldNum := -1
294	name := ""
295	id := typeId(0)
296	for {
297		delta := deb.delta(-1)
298		if delta == 0 {
299			break
300		}
301		fieldNum += delta
302		switch fieldNum {
303		case 0:
304			name = deb.string()
305		case 1:
306			// Id typeId
307			id = deb.typeId()
308		default:
309			errorf("corrupted CommonType, delta is %d fieldNum is %d", delta, fieldNum)
310		}
311	}
312	return CommonType{name, id}
313}
314
315// uint returns the unsigned int at the input point, as a uint (not uint64).
316func (deb *debugger) uint() uint {
317	return uint(deb.uint64())
318}
319
320// int returns the signed int at the input point, as an int (not int64).
321func (deb *debugger) int() int {
322	return int(deb.int64())
323}
324
325// typeId returns the type id at the input point.
326func (deb *debugger) typeId() typeId {
327	return typeId(deb.int64())
328}
329
330// string returns the string at the input point.
331func (deb *debugger) string() string {
332	x := int(deb.uint64())
333	b := make([]byte, x)
334	nb, _ := deb.r.Read(b)
335	if nb != x {
336		errorf("corrupted type")
337	}
338	deb.consumed(nb)
339	return string(b)
340}
341
342// delta returns the field delta at the input point. The expect argument,
343// if non-negative, identifies what the value should be.
344func (deb *debugger) delta(expect int) int {
345	delta := int(deb.uint64())
346	if delta < 0 || (expect >= 0 && delta != expect) {
347		errorf("decode: corrupted type: delta %d expected %d", delta, expect)
348	}
349	return delta
350}
351
352// TypeDefinition:
353//	[int(-typeId) (already read)] encodingOfWireType
354func (deb *debugger) typeDefinition(indent tab, id typeId) {
355	deb.dump("type definition for id %d", id)
356	// Encoding is of a wireType. Decode the structure as usual
357	fieldNum := -1
358	wire := new(wireType)
359	// A wireType defines a single field.
360	delta := deb.delta(-1)
361	fieldNum += delta
362	switch fieldNum {
363	case 0: // array type, one field of {{Common}, elem, length}
364		// Field number 0 is CommonType
365		deb.delta(1)
366		com := deb.common()
367		// Field number 1 is type Id of elem
368		deb.delta(1)
369		id := deb.typeId()
370		// Field number 3 is length
371		deb.delta(1)
372		length := deb.int()
373		wire.ArrayT = &arrayType{com, id, length}
374
375	case 1: // slice type, one field of {{Common}, elem}
376		// Field number 0 is CommonType
377		deb.delta(1)
378		com := deb.common()
379		// Field number 1 is type Id of elem
380		deb.delta(1)
381		id := deb.typeId()
382		wire.SliceT = &sliceType{com, id}
383
384	case 2: // struct type, one field of {{Common}, []fieldType}
385		// Field number 0 is CommonType
386		deb.delta(1)
387		com := deb.common()
388		// Field number 1 is slice of FieldType
389		deb.delta(1)
390		numField := int(deb.uint())
391		field := make([]*fieldType, numField)
392		for i := 0; i < numField; i++ {
393			field[i] = new(fieldType)
394			deb.delta(1) // field 0 of fieldType: name
395			field[i].Name = deb.string()
396			deb.delta(1) // field 1 of fieldType: id
397			field[i].Id = deb.typeId()
398			deb.delta(0) // end of fieldType
399		}
400		wire.StructT = &structType{com, field}
401
402	case 3: // map type, one field of {{Common}, key, elem}
403		// Field number 0 is CommonType
404		deb.delta(1)
405		com := deb.common()
406		// Field number 1 is type Id of key
407		deb.delta(1)
408		keyId := deb.typeId()
409		// Field number 2 is type Id of elem
410		deb.delta(1)
411		elemId := deb.typeId()
412		wire.MapT = &mapType{com, keyId, elemId}
413	case 4: // GobEncoder type, one field of {{Common}}
414		// Field number 0 is CommonType
415		deb.delta(1)
416		com := deb.common()
417		wire.GobEncoderT = &gobEncoderType{com}
418	case 5: // BinaryMarshaler type, one field of {{Common}}
419		// Field number 0 is CommonType
420		deb.delta(1)
421		com := deb.common()
422		wire.BinaryMarshalerT = &gobEncoderType{com}
423	case 6: // TextMarshaler type, one field of {{Common}}
424		// Field number 0 is CommonType
425		deb.delta(1)
426		com := deb.common()
427		wire.TextMarshalerT = &gobEncoderType{com}
428	default:
429		errorf("bad field in type %d", fieldNum)
430	}
431	deb.printWireType(indent, wire)
432	deb.delta(0) // end inner type (arrayType, etc.)
433	deb.delta(0) // end wireType
434	// Remember we've seen this type.
435	deb.wireType[id] = wire
436}
437
438// Value:
439//	SingletonValue | StructValue
440func (deb *debugger) value(indent tab, id typeId) {
441	wire, ok := deb.wireType[id]
442	if ok && wire.StructT != nil {
443		deb.structValue(indent, id)
444	} else {
445		deb.singletonValue(indent, id)
446	}
447}
448
449// SingletonValue:
450//	uint(0) FieldValue
451func (deb *debugger) singletonValue(indent tab, id typeId) {
452	deb.dump("Singleton value")
453	// is it a builtin type?
454	wire := deb.wireType[id]
455	_, ok := builtinIdToType[id]
456	if !ok && wire == nil {
457		errorf("type id %d not defined", id)
458	}
459	m := deb.uint64()
460	if m != 0 {
461		errorf("expected zero; got %d", m)
462	}
463	deb.fieldValue(indent, id)
464}
465
466// InterfaceValue:
467//	NilInterfaceValue | NonNilInterfaceValue
468func (deb *debugger) interfaceValue(indent tab) {
469	deb.dump("Start of interface value")
470	if nameLen := deb.uint64(); nameLen == 0 {
471		deb.nilInterfaceValue(indent)
472	} else {
473		deb.nonNilInterfaceValue(indent, int(nameLen))
474	}
475}
476
477// NilInterfaceValue:
478//	uint(0) [already read]
479func (deb *debugger) nilInterfaceValue(indent tab) int {
480	fmt.Fprintf(os.Stderr, "%snil interface\n", indent)
481	return 0
482}
483
484// NonNilInterfaceValue:
485//	ConcreteTypeName TypeSequence InterfaceContents
486// ConcreteTypeName:
487//	uint(lengthOfName) [already read=n] name
488// InterfaceContents:
489//	int(concreteTypeId) DelimitedValue
490// DelimitedValue:
491//	uint(length) Value
492func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) {
493	// ConcreteTypeName
494	b := make([]byte, nameLen)
495	deb.r.Read(b) // TODO: CHECK THESE READS!!
496	deb.consumed(nameLen)
497	name := string(b)
498
499	for {
500		id := deb.typeId()
501		if id < 0 {
502			deb.typeDefinition(indent, -id)
503			n := deb.loadBlock(false)
504			deb.dump("Nested message of length %d", n)
505		} else {
506			// DelimitedValue
507			x := deb.uint64() // in case we want to ignore the value; we don't.
508			fmt.Fprintf(os.Stderr, "%sinterface value, type %q id=%d; valueLength %d\n", indent, name, id, x)
509			deb.value(indent, id)
510			break
511		}
512	}
513}
514
515// printCommonType prints a common type; used by printWireType.
516func (deb *debugger) printCommonType(indent tab, kind string, common *CommonType) {
517	indent.print()
518	fmt.Fprintf(os.Stderr, "%s %q id=%d\n", kind, common.Name, common.Id)
519}
520
521// printWireType prints the contents of a wireType.
522func (deb *debugger) printWireType(indent tab, wire *wireType) {
523	fmt.Fprintf(os.Stderr, "%stype definition {\n", indent)
524	indent++
525	switch {
526	case wire.ArrayT != nil:
527		deb.printCommonType(indent, "array", &wire.ArrayT.CommonType)
528		fmt.Fprintf(os.Stderr, "%slen %d\n", indent+1, wire.ArrayT.Len)
529		fmt.Fprintf(os.Stderr, "%selemid %d\n", indent+1, wire.ArrayT.Elem)
530	case wire.MapT != nil:
531		deb.printCommonType(indent, "map", &wire.MapT.CommonType)
532		fmt.Fprintf(os.Stderr, "%skey id=%d\n", indent+1, wire.MapT.Key)
533		fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.MapT.Elem)
534	case wire.SliceT != nil:
535		deb.printCommonType(indent, "slice", &wire.SliceT.CommonType)
536		fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.SliceT.Elem)
537	case wire.StructT != nil:
538		deb.printCommonType(indent, "struct", &wire.StructT.CommonType)
539		for i, field := range wire.StructT.Field {
540			fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\tid=%d\n", indent+1, i, field.Name, field.Id)
541		}
542	case wire.GobEncoderT != nil:
543		deb.printCommonType(indent, "GobEncoder", &wire.GobEncoderT.CommonType)
544	}
545	indent--
546	fmt.Fprintf(os.Stderr, "%s}\n", indent)
547}
548
549// fieldValue prints a value of any type, such as a struct field.
550// FieldValue:
551//	builtinValue | ArrayValue | MapValue | SliceValue | StructValue | InterfaceValue
552func (deb *debugger) fieldValue(indent tab, id typeId) {
553	_, ok := builtinIdToType[id]
554	if ok {
555		if id == tInterface {
556			deb.interfaceValue(indent)
557		} else {
558			deb.printBuiltin(indent, id)
559		}
560		return
561	}
562	wire, ok := deb.wireType[id]
563	if !ok {
564		errorf("type id %d not defined", id)
565	}
566	switch {
567	case wire.ArrayT != nil:
568		deb.arrayValue(indent, wire)
569	case wire.MapT != nil:
570		deb.mapValue(indent, wire)
571	case wire.SliceT != nil:
572		deb.sliceValue(indent, wire)
573	case wire.StructT != nil:
574		deb.structValue(indent, id)
575	case wire.GobEncoderT != nil:
576		deb.gobEncoderValue(indent, id)
577	default:
578		panic("bad wire type for field")
579	}
580}
581
582// printBuiltin prints a value not of a fundamental type, that is,
583// one whose type is known to gobs at bootstrap time.
584func (deb *debugger) printBuiltin(indent tab, id typeId) {
585	switch id {
586	case tBool:
587		x := deb.int64()
588		if x == 0 {
589			fmt.Fprintf(os.Stderr, "%sfalse\n", indent)
590		} else {
591			fmt.Fprintf(os.Stderr, "%strue\n", indent)
592		}
593	case tInt:
594		x := deb.int64()
595		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
596	case tUint:
597		x := deb.uint64()
598		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
599	case tFloat:
600		x := deb.uint64()
601		fmt.Fprintf(os.Stderr, "%s%g\n", indent, float64FromBits(x))
602	case tComplex:
603		r := deb.uint64()
604		i := deb.uint64()
605		fmt.Fprintf(os.Stderr, "%s%g+%gi\n", indent, float64FromBits(r), float64FromBits(i))
606	case tBytes:
607		x := int(deb.uint64())
608		b := make([]byte, x)
609		deb.r.Read(b)
610		deb.consumed(x)
611		fmt.Fprintf(os.Stderr, "%s{% x}=%q\n", indent, b, b)
612	case tString:
613		x := int(deb.uint64())
614		b := make([]byte, x)
615		deb.r.Read(b)
616		deb.consumed(x)
617		fmt.Fprintf(os.Stderr, "%s%q\n", indent, b)
618	default:
619		panic("unknown builtin")
620	}
621}
622
623// ArrayValue:
624//	uint(n) FieldValue*n
625func (deb *debugger) arrayValue(indent tab, wire *wireType) {
626	elemId := wire.ArrayT.Elem
627	u := deb.uint64()
628	length := int(u)
629	for i := 0; i < length; i++ {
630		deb.fieldValue(indent, elemId)
631	}
632	if length != wire.ArrayT.Len {
633		fmt.Fprintf(os.Stderr, "%s(wrong length for array: %d should be %d)\n", indent, length, wire.ArrayT.Len)
634	}
635}
636
637// MapValue:
638//	uint(n) (FieldValue FieldValue)*n  [n (key, value) pairs]
639func (deb *debugger) mapValue(indent tab, wire *wireType) {
640	keyId := wire.MapT.Key
641	elemId := wire.MapT.Elem
642	u := deb.uint64()
643	length := int(u)
644	for i := 0; i < length; i++ {
645		deb.fieldValue(indent+1, keyId)
646		deb.fieldValue(indent+1, elemId)
647	}
648}
649
650// SliceValue:
651//	uint(n) (n FieldValue)
652func (deb *debugger) sliceValue(indent tab, wire *wireType) {
653	elemId := wire.SliceT.Elem
654	u := deb.uint64()
655	length := int(u)
656	deb.dump("Start of slice of length %d", length)
657
658	for i := 0; i < length; i++ {
659		deb.fieldValue(indent, elemId)
660	}
661}
662
663// StructValue:
664//	(uint(fieldDelta) FieldValue)*
665func (deb *debugger) structValue(indent tab, id typeId) {
666	deb.dump("Start of struct value of %q id=%d\n<<\n", id.name(), id)
667	fmt.Fprintf(os.Stderr, "%s%s struct {\n", indent, id.name())
668	wire, ok := deb.wireType[id]
669	if !ok {
670		errorf("type id %d not defined", id)
671	}
672	strct := wire.StructT
673	fieldNum := -1
674	indent++
675	for {
676		delta := deb.uint64()
677		if delta == 0 { // struct terminator is zero delta fieldnum
678			break
679		}
680		fieldNum += int(delta)
681		if fieldNum < 0 || fieldNum >= len(strct.Field) {
682			deb.dump("field number out of range: prevField=%d delta=%d", fieldNum-int(delta), delta)
683			break
684		}
685		fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\n", indent, fieldNum, wire.StructT.Field[fieldNum].Name)
686		deb.fieldValue(indent+1, strct.Field[fieldNum].Id)
687	}
688	indent--
689	fmt.Fprintf(os.Stderr, "%s} // end %s struct\n", indent, id.name())
690	deb.dump(">> End of struct value of type %d %q", id, id.name())
691}
692
693// GobEncoderValue:
694//	uint(n) byte*n
695func (deb *debugger) gobEncoderValue(indent tab, id typeId) {
696	len := deb.uint64()
697	deb.dump("GobEncoder value of %q id=%d, length %d\n", id.name(), id, len)
698	fmt.Fprintf(os.Stderr, "%s%s (implements GobEncoder)\n", indent, id.name())
699	data := make([]byte, len)
700	_, err := deb.r.Read(data)
701	if err != nil {
702		errorf("gobEncoder data read: %s", err)
703	}
704	fmt.Fprintf(os.Stderr, "%s[% .2x]\n", indent+1, data)
705}
706