1
2
3
4
5 package gob
6
7 import (
8 "encoding"
9 "errors"
10 "fmt"
11 "os"
12 "reflect"
13 "sync"
14 "sync/atomic"
15 "unicode"
16 "unicode/utf8"
17 )
18
19
20
21
22 type userTypeInfo struct {
23 user reflect.Type
24 base reflect.Type
25 indir int
26 externalEnc int
27 externalDec int
28 encIndir int8
29 decIndir int8
30 }
31
32
33 const (
34 xGob = 1 + iota
35 xBinary
36 xText
37 )
38
39 var userTypeCache sync.Map
40
41
42
43
44 func validUserType(rt reflect.Type) (*userTypeInfo, error) {
45 if ui, ok := userTypeCache.Load(rt); ok {
46 return ui.(*userTypeInfo), nil
47 }
48
49
50
51
52
53 ut := new(userTypeInfo)
54 ut.base = rt
55 ut.user = rt
56
57
58
59
60
61 slowpoke := ut.base
62 for {
63 pt := ut.base
64 if pt.Kind() != reflect.Pointer {
65 break
66 }
67 ut.base = pt.Elem()
68 if ut.base == slowpoke {
69
70 return nil, errors.New("can't represent recursive pointer type " + ut.base.String())
71 }
72 if ut.indir%2 == 0 {
73 slowpoke = slowpoke.Elem()
74 }
75 ut.indir++
76 }
77
78 if ok, indir := implementsInterface(ut.user, gobEncoderInterfaceType); ok {
79 ut.externalEnc, ut.encIndir = xGob, indir
80 } else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
81 ut.externalEnc, ut.encIndir = xBinary, indir
82 }
83
84
85
86
87
88
89
90 if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
91 ut.externalDec, ut.decIndir = xGob, indir
92 } else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
93 ut.externalDec, ut.decIndir = xBinary, indir
94 }
95
96
97
98
99
100
101 ui, _ := userTypeCache.LoadOrStore(rt, ut)
102 return ui.(*userTypeInfo), nil
103 }
104
105 var (
106 gobEncoderInterfaceType = reflect.TypeFor[GobEncoder]()
107 gobDecoderInterfaceType = reflect.TypeFor[GobDecoder]()
108 binaryMarshalerInterfaceType = reflect.TypeFor[encoding.BinaryMarshaler]()
109 binaryUnmarshalerInterfaceType = reflect.TypeFor[encoding.BinaryUnmarshaler]()
110 textMarshalerInterfaceType = reflect.TypeFor[encoding.TextMarshaler]()
111 textUnmarshalerInterfaceType = reflect.TypeFor[encoding.TextUnmarshaler]()
112
113 wireTypeType = reflect.TypeFor[wireType]()
114 )
115
116
117
118
119
120 func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
121 if typ == nil {
122 return
123 }
124 rt := typ
125
126
127 for {
128 if rt.Implements(gobEncDecType) {
129 return true, indir
130 }
131 if p := rt; p.Kind() == reflect.Pointer {
132 indir++
133 if indir > 100 {
134 return false, 0
135 }
136 rt = p.Elem()
137 continue
138 }
139 break
140 }
141
142 if typ.Kind() != reflect.Pointer {
143
144 if reflect.PointerTo(typ).Implements(gobEncDecType) {
145 return true, -1
146 }
147 }
148 return false, 0
149 }
150
151
152
153 func userType(rt reflect.Type) *userTypeInfo {
154 ut, err := validUserType(rt)
155 if err != nil {
156 error_(err)
157 }
158 return ut
159 }
160
161
162
163 type typeId int32
164
165 var typeLock sync.Mutex
166 const firstUserId = 64
167
168 type gobType interface {
169 id() typeId
170 setId(id typeId)
171 name() string
172 string() string
173 safeString(seen map[typeId]bool) string
174 }
175
176 var (
177 types = make(map[reflect.Type]gobType, 32)
178 idToTypeSlice = make([]gobType, 1, firstUserId)
179 builtinIdToTypeSlice [firstUserId]gobType
180 )
181
182 func idToType(id typeId) gobType {
183 if id < 0 || int(id) >= len(idToTypeSlice) {
184 return nil
185 }
186 return idToTypeSlice[id]
187 }
188
189 func builtinIdToType(id typeId) gobType {
190 if id < 0 || int(id) >= len(builtinIdToTypeSlice) {
191 return nil
192 }
193 return builtinIdToTypeSlice[id]
194 }
195
196 func setTypeId(typ gobType) {
197
198 if typ.id() != 0 {
199 return
200 }
201 nextId := typeId(len(idToTypeSlice))
202 typ.setId(nextId)
203 idToTypeSlice = append(idToTypeSlice, typ)
204 }
205
206 func (t typeId) gobType() gobType {
207 if t == 0 {
208 return nil
209 }
210 return idToType(t)
211 }
212
213
214 func (t typeId) string() string {
215 if t.gobType() == nil {
216 return "<nil>"
217 }
218 return t.gobType().string()
219 }
220
221
222 func (t typeId) name() string {
223 if t.gobType() == nil {
224 return "<nil>"
225 }
226 return t.gobType().name()
227 }
228
229
230
231
232
233 type CommonType struct {
234 Name string
235 Id typeId
236 }
237
238 func (t *CommonType) id() typeId { return t.Id }
239
240 func (t *CommonType) setId(id typeId) { t.Id = id }
241
242 func (t *CommonType) string() string { return t.Name }
243
244 func (t *CommonType) safeString(seen map[typeId]bool) string {
245 return t.Name
246 }
247
248 func (t *CommonType) name() string { return t.Name }
249
250
251
252
253 var (
254
255
256
257 tBool = bootstrapType("bool", (*bool)(nil))
258 tInt = bootstrapType("int", (*int)(nil))
259 tUint = bootstrapType("uint", (*uint)(nil))
260 tFloat = bootstrapType("float", (*float64)(nil))
261 tBytes = bootstrapType("bytes", (*[]byte)(nil))
262 tString = bootstrapType("string", (*string)(nil))
263 tComplex = bootstrapType("complex", (*complex128)(nil))
264 tInterface = bootstrapType("interface", (*any)(nil))
265
266 tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil))
267 tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil))
268 tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil))
269 tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil))
270 tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil))
271 tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil))
272 tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil))
273 )
274
275
276 var tWireType = mustGetTypeInfo(wireTypeType).id
277 var wireTypeUserInfo *userTypeInfo
278
279 func init() {
280
281 checkId(16, tWireType)
282 checkId(17, mustGetTypeInfo(reflect.TypeFor[arrayType]()).id)
283 checkId(18, mustGetTypeInfo(reflect.TypeFor[CommonType]()).id)
284 checkId(19, mustGetTypeInfo(reflect.TypeFor[sliceType]()).id)
285 checkId(20, mustGetTypeInfo(reflect.TypeFor[structType]()).id)
286 checkId(21, mustGetTypeInfo(reflect.TypeFor[fieldType]()).id)
287 checkId(23, mustGetTypeInfo(reflect.TypeFor[mapType]()).id)
288
289 copy(builtinIdToTypeSlice[:], idToTypeSlice)
290
291
292
293 if nextId := len(idToTypeSlice); nextId > firstUserId {
294 panic(fmt.Sprintln("nextId too large:", nextId))
295 }
296 idToTypeSlice = idToTypeSlice[:firstUserId]
297 registerBasics()
298 wireTypeUserInfo = userType(wireTypeType)
299 }
300
301
302 type arrayType struct {
303 CommonType
304 Elem typeId
305 Len int
306 }
307
308 func newArrayType(name string) *arrayType {
309 a := &arrayType{CommonType{Name: name}, 0, 0}
310 return a
311 }
312
313 func (a *arrayType) init(elem gobType, len int) {
314
315 setTypeId(a)
316 a.Elem = elem.id()
317 a.Len = len
318 }
319
320 func (a *arrayType) safeString(seen map[typeId]bool) string {
321 if seen[a.Id] {
322 return a.Name
323 }
324 seen[a.Id] = true
325 return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
326 }
327
328 func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
329
330
331 type gobEncoderType struct {
332 CommonType
333 }
334
335 func newGobEncoderType(name string) *gobEncoderType {
336 g := &gobEncoderType{CommonType{Name: name}}
337 setTypeId(g)
338 return g
339 }
340
341 func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
342 return g.Name
343 }
344
345 func (g *gobEncoderType) string() string { return g.Name }
346
347
348 type mapType struct {
349 CommonType
350 Key typeId
351 Elem typeId
352 }
353
354 func newMapType(name string) *mapType {
355 m := &mapType{CommonType{Name: name}, 0, 0}
356 return m
357 }
358
359 func (m *mapType) init(key, elem gobType) {
360
361 setTypeId(m)
362 m.Key = key.id()
363 m.Elem = elem.id()
364 }
365
366 func (m *mapType) safeString(seen map[typeId]bool) string {
367 if seen[m.Id] {
368 return m.Name
369 }
370 seen[m.Id] = true
371 key := m.Key.gobType().safeString(seen)
372 elem := m.Elem.gobType().safeString(seen)
373 return fmt.Sprintf("map[%s]%s", key, elem)
374 }
375
376 func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
377
378
379 type sliceType struct {
380 CommonType
381 Elem typeId
382 }
383
384 func newSliceType(name string) *sliceType {
385 s := &sliceType{CommonType{Name: name}, 0}
386 return s
387 }
388
389 func (s *sliceType) init(elem gobType) {
390
391 setTypeId(s)
392
393
394 if elem.id() == 0 {
395 setTypeId(elem)
396 }
397 s.Elem = elem.id()
398 }
399
400 func (s *sliceType) safeString(seen map[typeId]bool) string {
401 if seen[s.Id] {
402 return s.Name
403 }
404 seen[s.Id] = true
405 return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
406 }
407
408 func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
409
410
411 type fieldType struct {
412 Name string
413 Id typeId
414 }
415
416 type structType struct {
417 CommonType
418 Field []fieldType
419 }
420
421 func (s *structType) safeString(seen map[typeId]bool) string {
422 if s == nil {
423 return "<nil>"
424 }
425 if _, ok := seen[s.Id]; ok {
426 return s.Name
427 }
428 seen[s.Id] = true
429 str := s.Name + " = struct { "
430 for _, f := range s.Field {
431 str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
432 }
433 str += "}"
434 return str
435 }
436
437 func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
438
439 func newStructType(name string) *structType {
440 s := &structType{CommonType{Name: name}, nil}
441
442
443 setTypeId(s)
444 return s
445 }
446
447
448
449
450
451
452 func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
453
454 if ut.externalEnc != 0 {
455 return newGobEncoderType(name), nil
456 }
457 var err error
458 var type0, type1 gobType
459 defer func() {
460 if err != nil {
461 delete(types, rt)
462 }
463 }()
464
465
466 switch t := rt; t.Kind() {
467
468 case reflect.Bool:
469 return tBool.gobType(), nil
470
471 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
472 return tInt.gobType(), nil
473
474 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
475 return tUint.gobType(), nil
476
477 case reflect.Float32, reflect.Float64:
478 return tFloat.gobType(), nil
479
480 case reflect.Complex64, reflect.Complex128:
481 return tComplex.gobType(), nil
482
483 case reflect.String:
484 return tString.gobType(), nil
485
486 case reflect.Interface:
487 return tInterface.gobType(), nil
488
489 case reflect.Array:
490 at := newArrayType(name)
491 types[rt] = at
492 type0, err = getBaseType("", t.Elem())
493 if err != nil {
494 return nil, err
495 }
496
497
498
499
500
501
502
503
504 at.init(type0, t.Len())
505 return at, nil
506
507 case reflect.Map:
508 mt := newMapType(name)
509 types[rt] = mt
510 type0, err = getBaseType("", t.Key())
511 if err != nil {
512 return nil, err
513 }
514 type1, err = getBaseType("", t.Elem())
515 if err != nil {
516 return nil, err
517 }
518 mt.init(type0, type1)
519 return mt, nil
520
521 case reflect.Slice:
522
523 if t.Elem().Kind() == reflect.Uint8 {
524 return tBytes.gobType(), nil
525 }
526 st := newSliceType(name)
527 types[rt] = st
528 type0, err = getBaseType(t.Elem().Name(), t.Elem())
529 if err != nil {
530 return nil, err
531 }
532 st.init(type0)
533 return st, nil
534
535 case reflect.Struct:
536 st := newStructType(name)
537 types[rt] = st
538 idToTypeSlice[st.id()] = st
539 for i := 0; i < t.NumField(); i++ {
540 f := t.Field(i)
541 if !isSent(t, &f) {
542 continue
543 }
544 typ := userType(f.Type).base
545 tname := typ.Name()
546 if tname == "" {
547 t := userType(f.Type).base
548 tname = t.String()
549 }
550 gt, err := getBaseType(tname, f.Type)
551 if err != nil {
552 return nil, err
553 }
554
555
556
557
558 if gt.id() == 0 {
559 setTypeId(gt)
560 }
561 st.Field = append(st.Field, fieldType{f.Name, gt.id()})
562 }
563 return st, nil
564
565 default:
566 return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
567 }
568 }
569
570
571 func isExported(name string) bool {
572 rune, _ := utf8.DecodeRuneInString(name)
573 return unicode.IsUpper(rune)
574 }
575
576
577
578
579 func isSent(struct_ reflect.Type, field *reflect.StructField) bool {
580 if !isExported(field.Name) {
581 return false
582 }
583
584
585 typ := field.Type
586 for typ.Kind() == reflect.Pointer {
587 typ = typ.Elem()
588 }
589 if typ.Kind() == reflect.Chan || typ.Kind() == reflect.Func {
590 return false
591 }
592
593
594
595
596
597
598
599 if field.Name == "Policies" && struct_.PkgPath() == "crypto/x509" && struct_.Name() == "Certificate" {
600 return false
601 }
602
603 return true
604 }
605
606
607
608 func getBaseType(name string, rt reflect.Type) (gobType, error) {
609 ut := userType(rt)
610 return getType(name, ut, ut.base)
611 }
612
613
614
615
616
617
618 func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
619 typ, present := types[rt]
620 if present {
621 return typ, nil
622 }
623 typ, err := newTypeObject(name, ut, rt)
624 if err == nil {
625 types[rt] = typ
626 }
627 return typ, err
628 }
629
630 func checkId(want, got typeId) {
631 if want != got {
632 fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
633 panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
634 }
635 }
636
637
638
639 func bootstrapType(name string, e any) typeId {
640 rt := reflect.TypeOf(e).Elem()
641 _, present := types[rt]
642 if present {
643 panic("bootstrap type already present: " + name + ", " + rt.String())
644 }
645 typ := &CommonType{Name: name}
646 types[rt] = typ
647 setTypeId(typ)
648 return typ.id()
649 }
650
651
652
653
654
655
656
657
658
659
660
661
662 type wireType struct {
663 ArrayT *arrayType
664 SliceT *sliceType
665 StructT *structType
666 MapT *mapType
667 GobEncoderT *gobEncoderType
668 BinaryMarshalerT *gobEncoderType
669 TextMarshalerT *gobEncoderType
670 }
671
672 func (w *wireType) string() string {
673 const unknown = "unknown type"
674 if w == nil {
675 return unknown
676 }
677 switch {
678 case w.ArrayT != nil:
679 return w.ArrayT.Name
680 case w.SliceT != nil:
681 return w.SliceT.Name
682 case w.StructT != nil:
683 return w.StructT.Name
684 case w.MapT != nil:
685 return w.MapT.Name
686 case w.GobEncoderT != nil:
687 return w.GobEncoderT.Name
688 case w.BinaryMarshalerT != nil:
689 return w.BinaryMarshalerT.Name
690 case w.TextMarshalerT != nil:
691 return w.TextMarshalerT.Name
692 }
693 return unknown
694 }
695
696 type typeInfo struct {
697 id typeId
698 encInit sync.Mutex
699 encoder atomic.Pointer[encEngine]
700 wire wireType
701 }
702
703
704
705
706
707
708
709 var typeInfoMap atomic.Value
710
711
712
713
714
715 var typeInfoMapInit = make(map[reflect.Type]*typeInfo, 16)
716
717 func lookupTypeInfo(rt reflect.Type) *typeInfo {
718 if m := typeInfoMapInit; m != nil {
719 return m[rt]
720 }
721 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
722 return m[rt]
723 }
724
725 func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
726 rt := ut.base
727 if ut.externalEnc != 0 {
728
729 rt = ut.user
730 }
731 if info := lookupTypeInfo(rt); info != nil {
732 return info, nil
733 }
734 return buildTypeInfo(ut, rt)
735 }
736
737
738
739 func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
740 typeLock.Lock()
741 defer typeLock.Unlock()
742
743 if info := lookupTypeInfo(rt); info != nil {
744 return info, nil
745 }
746
747 gt, err := getBaseType(rt.Name(), rt)
748 if err != nil {
749 return nil, err
750 }
751 info := &typeInfo{id: gt.id()}
752
753 if ut.externalEnc != 0 {
754 userType, err := getType(rt.Name(), ut, rt)
755 if err != nil {
756 return nil, err
757 }
758 gt := userType.id().gobType().(*gobEncoderType)
759 switch ut.externalEnc {
760 case xGob:
761 info.wire.GobEncoderT = gt
762 case xBinary:
763 info.wire.BinaryMarshalerT = gt
764 case xText:
765 info.wire.TextMarshalerT = gt
766 }
767 rt = ut.user
768 } else {
769 t := info.id.gobType()
770 switch typ := rt; typ.Kind() {
771 case reflect.Array:
772 info.wire.ArrayT = t.(*arrayType)
773 case reflect.Map:
774 info.wire.MapT = t.(*mapType)
775 case reflect.Slice:
776
777 if typ.Elem().Kind() != reflect.Uint8 {
778 info.wire.SliceT = t.(*sliceType)
779 }
780 case reflect.Struct:
781 info.wire.StructT = t.(*structType)
782 }
783 }
784
785 if m := typeInfoMapInit; m != nil {
786 m[rt] = info
787 return info, nil
788 }
789
790
791 m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
792 newm := make(map[reflect.Type]*typeInfo, len(m))
793 for k, v := range m {
794 newm[k] = v
795 }
796 newm[rt] = info
797 typeInfoMap.Store(newm)
798 return info, nil
799 }
800
801
802 func mustGetTypeInfo(rt reflect.Type) *typeInfo {
803 t, err := getTypeInfo(userType(rt))
804 if err != nil {
805 panic("getTypeInfo: " + err.Error())
806 }
807 return t
808 }
809
810
811
812
813
814
815
816
817
818
819
820
821 type GobEncoder interface {
822
823
824
825 GobEncode() ([]byte, error)
826 }
827
828
829
830 type GobDecoder interface {
831
832
833
834 GobDecode([]byte) error
835 }
836
837 var (
838 nameToConcreteType sync.Map
839 concreteTypeToName sync.Map
840 )
841
842
843
844 func RegisterName(name string, value any) {
845 if name == "" {
846
847 panic("attempt to register empty name")
848 }
849
850 ut := userType(reflect.TypeOf(value))
851
852
853
854
855
856 if t, dup := nameToConcreteType.LoadOrStore(name, reflect.TypeOf(value)); dup && t != ut.user {
857 panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
858 }
859
860
861 if n, dup := concreteTypeToName.LoadOrStore(ut.base, name); dup && n != name {
862 nameToConcreteType.Delete(name)
863 panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
864 }
865 }
866
867
868
869
870
871
872
873 func Register(value any) {
874
875 rt := reflect.TypeOf(value)
876 name := rt.String()
877
878
879
880 star := ""
881 if rt.Name() == "" {
882 if pt := rt; pt.Kind() == reflect.Pointer {
883 star = "*"
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900 rt = pt
901 }
902 }
903 if rt.Name() != "" {
904 if rt.PkgPath() == "" {
905 name = star + rt.Name()
906 } else {
907 name = star + rt.PkgPath() + "." + rt.Name()
908 }
909 }
910
911 RegisterName(name, value)
912 }
913
914 func registerBasics() {
915 Register(int(0))
916 Register(int8(0))
917 Register(int16(0))
918 Register(int32(0))
919 Register(int64(0))
920 Register(uint(0))
921 Register(uint8(0))
922 Register(uint16(0))
923 Register(uint32(0))
924 Register(uint64(0))
925 Register(float32(0))
926 Register(float64(0))
927 Register(complex64(0i))
928 Register(complex128(0i))
929 Register(uintptr(0))
930 Register(false)
931 Register("")
932 Register([]byte(nil))
933 Register([]int(nil))
934 Register([]int8(nil))
935 Register([]int16(nil))
936 Register([]int32(nil))
937 Register([]int64(nil))
938 Register([]uint(nil))
939 Register([]uint8(nil))
940 Register([]uint16(nil))
941 Register([]uint32(nil))
942 Register([]uint64(nil))
943 Register([]float32(nil))
944 Register([]float64(nil))
945 Register([]complex64(nil))
946 Register([]complex128(nil))
947 Register([]uintptr(nil))
948 Register([]bool(nil))
949 Register([]string(nil))
950 }
951
952 func init() {
953 typeInfoMap.Store(typeInfoMapInit)
954 typeInfoMapInit = nil
955 }
956
View as plain text