LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package gob | 5 package gob |
6 | 6 |
7 // TODO(rsc): When garbage collector changes, revisit | 7 // TODO(rsc): When garbage collector changes, revisit |
8 // the allocations in this file that use unsafe.Pointer. | 8 // the allocations in this file that use unsafe.Pointer. |
9 | 9 |
10 import ( | 10 import ( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 } | 55 } |
56 | 56 |
57 func overflow(name string) error { | 57 func overflow(name string) error { |
58 return errors.New(`value for "` + name + `" out of range`) | 58 return errors.New(`value for "` + name + `" out of range`) |
59 } | 59 } |
60 | 60 |
61 // decodeUintReader reads an encoded unsigned integer from an io.Reader. | 61 // decodeUintReader reads an encoded unsigned integer from an io.Reader. |
62 // Used only by the Decoder to read the message length. | 62 // Used only by the Decoder to read the message length. |
63 func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error)
{ | 63 func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error)
{ |
64 width = 1 | 64 width = 1 |
65 » _, err = io.ReadFull(r, buf[0:width]) | 65 » n, err := io.ReadFull(r, buf[0:width]) |
66 » if err != nil { | 66 » if n == 0 { |
67 return | 67 return |
68 } | 68 } |
69 b := buf[0] | 69 b := buf[0] |
70 if b <= 0x7f { | 70 if b <= 0x7f { |
71 return uint64(b), width, nil | 71 return uint64(b), width, nil |
72 } | 72 } |
73 » n := -int(int8(b)) | 73 » n = -int(int8(b)) |
74 if n > uint64Size { | 74 if n > uint64Size { |
75 err = errBadUint | 75 err = errBadUint |
76 return | 76 return |
77 } | 77 } |
78 width, err = io.ReadFull(r, buf[0:n]) | 78 width, err = io.ReadFull(r, buf[0:n]) |
79 if err != nil { | 79 if err != nil { |
80 if err == io.EOF { | 80 if err == io.EOF { |
81 err = io.ErrUnexpectedEOF | 81 err = io.ErrUnexpectedEOF |
82 } | 82 } |
83 return | 83 return |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 } | 555 } |
556 instr := &engine.instr[singletonField] | 556 instr := &engine.instr[singletonField] |
557 instr.op(instr, state, unsafe.Pointer(nil)) | 557 instr.op(instr, state, unsafe.Pointer(nil)) |
558 dec.freeDecoderState(state) | 558 dec.freeDecoderState(state) |
559 } | 559 } |
560 | 560 |
561 // decodeArrayHelper does the work for decoding arrays and slices. | 561 // decodeArrayHelper does the work for decoding arrays and slices. |
562 func (dec *Decoder) decodeArrayHelper(state *decoderState, p uintptr, elemOp dec
Op, elemWid uintptr, length, elemIndir int, ovfl error) { | 562 func (dec *Decoder) decodeArrayHelper(state *decoderState, p uintptr, elemOp dec
Op, elemWid uintptr, length, elemIndir int, ovfl error) { |
563 instr := &decInstr{elemOp, 0, elemIndir, 0, ovfl} | 563 instr := &decInstr{elemOp, 0, elemIndir, 0, ovfl} |
564 for i := 0; i < length; i++ { | 564 for i := 0; i < length; i++ { |
| 565 if state.b.Len() == 0 { |
| 566 errorf("decoding array or slice: length exceeds input si
ze (%d elements)", length) |
| 567 } |
565 up := unsafe.Pointer(p) | 568 up := unsafe.Pointer(p) |
566 if elemIndir > 1 { | 569 if elemIndir > 1 { |
567 up = decIndirect(up, elemIndir) | 570 up = decIndirect(up, elemIndir) |
568 } | 571 } |
569 elemOp(instr, state, up) | 572 elemOp(instr, state, up) |
570 p += uintptr(elemWid) | 573 p += uintptr(elemWid) |
571 } | 574 } |
572 } | 575 } |
573 | 576 |
574 // decodeArray decodes an array and stores it through p, that is, p points to th
e zeroth element. | 577 // decodeArray decodes an array and stores it through p, that is, p points to th
e zeroth element. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 for i := 0; i < n; i++ { | 648 for i := 0; i < n; i++ { |
646 keyOp(keyInstr, state, nil) | 649 keyOp(keyInstr, state, nil) |
647 elemOp(elemInstr, state, nil) | 650 elemOp(elemInstr, state, nil) |
648 } | 651 } |
649 } | 652 } |
650 | 653 |
651 // decodeSlice decodes a slice and stores the slice header through p. | 654 // decodeSlice decodes a slice and stores the slice header through p. |
652 // Slices are encoded as an unsigned length followed by the elements. | 655 // Slices are encoded as an unsigned length followed by the elements. |
653 func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintpt
r, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) { | 656 func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintpt
r, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) { |
654 nr := state.decodeUint() | 657 nr := state.decodeUint() |
655 if nr > uint64(state.b.Len()) { | |
656 errorf("length of slice exceeds input size (%d elements)", nr) | |
657 } | |
658 n := int(nr) | 658 n := int(nr) |
659 if indir > 0 { | 659 if indir > 0 { |
660 up := unsafe.Pointer(p) | 660 up := unsafe.Pointer(p) |
661 if *(*unsafe.Pointer)(up) == nil { | 661 if *(*unsafe.Pointer)(up) == nil { |
662 // Allocate the slice header. | 662 // Allocate the slice header. |
663 *(*unsafe.Pointer)(up) = unsafe.Pointer(new([]unsafe.Poi
nter)) | 663 *(*unsafe.Pointer)(up) = unsafe.Pointer(new([]unsafe.Poi
nter)) |
664 } | 664 } |
665 p = *(*uintptr)(up) | 665 p = *(*uintptr)(up) |
666 } | 666 } |
667 // Allocate storage for the slice elements, that is, the underlying arra
y, | 667 // Allocate storage for the slice elements, that is, the underlying arra
y, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 if indir > 0 { | 710 if indir > 0 { |
711 p = allocate(ityp, p, 1) // All but the last level has b
een allocated by dec.Indirect | 711 p = allocate(ityp, p, 1) // All but the last level has b
een allocated by dec.Indirect |
712 } | 712 } |
713 *(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData() | 713 *(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData() |
714 return | 714 return |
715 } | 715 } |
716 if len(name) > 1024 { | 716 if len(name) > 1024 { |
717 errorf("name too long (%d bytes): %.20q...", len(name), name) | 717 errorf("name too long (%d bytes): %.20q...", len(name), name) |
718 } | 718 } |
719 // The concrete type must be registered. | 719 // The concrete type must be registered. |
| 720 registerLock.RLock() |
720 typ, ok := nameToConcreteType[name] | 721 typ, ok := nameToConcreteType[name] |
| 722 registerLock.RUnlock() |
721 if !ok { | 723 if !ok { |
722 errorf("name not registered for interface: %q", name) | 724 errorf("name not registered for interface: %q", name) |
723 } | 725 } |
724 // Read the type id of the concrete value. | 726 // Read the type id of the concrete value. |
725 concreteId := dec.decodeTypeSequence(true) | 727 concreteId := dec.decodeTypeSequence(true) |
726 if concreteId < 0 { | 728 if concreteId < 0 { |
727 error_(dec.err) | 729 error_(dec.err) |
728 } | 730 } |
729 // Byte count of value is next; we don't care what it is (it's there | 731 // Byte count of value is next; we don't care what it is (it's there |
730 // in case we want to ignore the value by skipping it completely). | 732 // in case we want to ignore the value by skipping it completely). |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 return x.UnsafeAddr() | 1293 return x.UnsafeAddr() |
1292 } | 1294 } |
1293 | 1295 |
1294 // Gob depends on being able to take the address | 1296 // Gob depends on being able to take the address |
1295 // of zeroed Values it creates, so use this wrapper instead | 1297 // of zeroed Values it creates, so use this wrapper instead |
1296 // of the standard reflect.Zero. | 1298 // of the standard reflect.Zero. |
1297 // Each call allocates once. | 1299 // Each call allocates once. |
1298 func allocValue(t reflect.Type) reflect.Value { | 1300 func allocValue(t reflect.Type) reflect.Value { |
1299 return reflect.New(t).Elem() | 1301 return reflect.New(t).Elem() |
1300 } | 1302 } |
LEFT | RIGHT |