| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679 |
- package msgp
- import (
- "encoding"
- "encoding/binary"
- "encoding/json"
- "fmt"
- "io"
- "math"
- "strconv"
- "sync"
- "time"
- "github.com/philhofer/fwd"
- )
- // where we keep old *Readers
- var readerPool = sync.Pool{New: func() any { return &Reader{} }}
- // Type is a MessagePack wire type,
- // including this package's built-in
- // extension types.
- type Type byte
- // MessagePack Types
- //
- // The zero value of Type
- // is InvalidType.
- const (
- InvalidType Type = iota
- // MessagePack built-in types
- StrType
- BinType
- MapType
- ArrayType
- Float64Type
- Float32Type
- BoolType
- IntType
- UintType
- NilType
- DurationType
- ExtensionType
- // pseudo-types provided
- // by extensions
- Complex64Type
- Complex128Type
- TimeType
- NumberType
- _maxtype
- )
- // String implements fmt.Stringer
- func (t Type) String() string {
- switch t {
- case StrType:
- return "str"
- case BinType:
- return "bin"
- case MapType:
- return "map"
- case ArrayType:
- return "array"
- case Float64Type:
- return "float64"
- case Float32Type:
- return "float32"
- case BoolType:
- return "bool"
- case UintType:
- return "uint"
- case IntType:
- return "int"
- case ExtensionType:
- return "ext"
- case NilType:
- return "nil"
- case NumberType:
- return "number"
- default:
- return "<invalid>"
- }
- }
- func freeR(m *Reader) {
- readerPool.Put(m)
- }
- // Unmarshaler is the interface fulfilled
- // by objects that know how to unmarshal
- // themselves from MessagePack.
- // UnmarshalMsg unmarshals the object
- // from binary, returing any leftover
- // bytes and any errors encountered.
- type Unmarshaler interface {
- UnmarshalMsg([]byte) ([]byte, error)
- }
- // Decodable is the interface fulfilled
- // by objects that know how to read
- // themselves from a *Reader.
- type Decodable interface {
- DecodeMsg(*Reader) error
- }
- // Decode decodes 'd' from 'r'.
- func Decode(r io.Reader, d Decodable) error {
- rd := NewReader(r)
- err := d.DecodeMsg(rd)
- freeR(rd)
- return err
- }
- // NewReader returns a *Reader that
- // reads from the provided reader. The
- // reader will be buffered.
- func NewReader(r io.Reader) *Reader {
- p := readerPool.Get().(*Reader)
- p.recursionDepth = 0
- p.maxElements = 0
- p.maxRecursionDepth = 0
- p.maxStrLen = 0
- if p.R == nil {
- p.R = fwd.NewReader(r)
- } else {
- p.R.Reset(r)
- }
- return p
- }
- // NewReaderSize returns a *Reader with a buffer of the given size.
- // (This is vastly preferable to passing the decoder a reader that is already buffered.)
- func NewReaderSize(r io.Reader, sz int) *Reader {
- return &Reader{R: fwd.NewReaderSize(r, sz)}
- }
- // NewReaderBuf returns a *Reader with a provided buffer.
- func NewReaderBuf(r io.Reader, buf []byte) *Reader {
- return &Reader{R: fwd.NewReaderBuf(r, buf)}
- }
- // Reader wraps an io.Reader and provides
- // methods to read MessagePack-encoded values
- // from it. Readers are buffered.
- type Reader struct {
- // R is the buffered reader
- // that the Reader uses
- // to decode MessagePack.
- // The Reader itself
- // is stateless; all the
- // buffering is done
- // within R.
- R *fwd.Reader
- scratch []byte
- recursionDepth int
- maxRecursionDepth int // maximum recursion depth
- maxElements uint32 // maximum number of elements in arrays and maps
- maxStrLen uint64 // maximum number of bytes in any string
- }
- // Read implements `io.Reader`
- func (m *Reader) Read(p []byte) (int, error) {
- return m.R.Read(p)
- }
- // CopyNext reads the next object from m without decoding it and writes it to w.
- // It avoids unnecessary copies internally.
- func (m *Reader) CopyNext(w io.Writer) (int64, error) {
- sz, o, err := getNextSize(m.R)
- if err != nil {
- return 0, err
- }
- var n int64
- // Opportunistic optimization: if we can fit the whole thing in the m.R
- // buffer, then just get a pointer to that, and pass it to w.Write,
- // avoiding an allocation.
- if int(sz) >= 0 && int(sz) <= m.R.BufferSize() {
- var nn int
- var buf []byte
- buf, err = m.R.Next(int(sz))
- if err != nil {
- if err == io.ErrUnexpectedEOF {
- err = ErrShortBytes
- }
- return 0, err
- }
- nn, err = w.Write(buf)
- n += int64(nn)
- } else {
- // Fall back to io.CopyN.
- // May avoid allocating if w is a ReaderFrom (e.g. bytes.Buffer)
- n, err = io.CopyN(w, m.R, int64(sz))
- if err == io.ErrUnexpectedEOF {
- err = ErrShortBytes
- }
- }
- if err != nil {
- return n, err
- } else if n < int64(sz) {
- return n, io.ErrShortWrite
- }
- if done, err := m.recursiveCall(); err != nil {
- return n, err
- } else {
- defer done()
- }
- // for maps and slices, read elements
- for range o {
- var n2 int64
- n2, err = m.CopyNext(w)
- if err != nil {
- return n, err
- }
- n += n2
- }
- return n, nil
- }
- // SetMaxRecursionDepth sets the maximum recursion depth.
- func (m *Reader) SetMaxRecursionDepth(d int) {
- m.maxRecursionDepth = d
- }
- // GetMaxRecursionDepth returns the maximum recursion depth.
- // Set to 0 to use the default value of 100000.
- func (m *Reader) GetMaxRecursionDepth() int {
- if m.maxRecursionDepth <= 0 {
- return recursionLimit
- }
- return m.maxRecursionDepth
- }
- // SetMaxElements sets the maximum number of elements to allow in map, bin, array or extension payload.
- // Setting this to 0 will allow any number of elements - math.MaxUint32.
- // This does currently apply to generated code.
- func (m *Reader) SetMaxElements(d uint32) {
- m.maxElements = d
- }
- // GetMaxElements will return the maximum number of elements in a map, bin, array or extension payload.
- func (m *Reader) GetMaxElements() uint32 {
- if m.maxElements <= 0 {
- return math.MaxUint32
- }
- return m.maxElements
- }
- // SetMaxStringLength sets the maximum number of bytes to allow in strings.
- // Setting this == 0 will allow any number of elements - math.MaxUint64.
- func (m *Reader) SetMaxStringLength(d uint64) {
- m.maxStrLen = d
- }
- // GetMaxStringLength will return the current string length limit.
- func (m *Reader) GetMaxStringLength() uint64 {
- if m.maxStrLen <= 0 {
- return math.MaxUint64
- }
- return min(m.maxStrLen, math.MaxUint64)
- }
- // recursiveCall will increment the recursion depth and return an error if it is exceeded.
- // If a nil error is returned, done must be called to decrement the counter.
- func (m *Reader) recursiveCall() (done func(), err error) {
- if m.recursionDepth >= m.GetMaxRecursionDepth() {
- return func() {}, ErrRecursion
- }
- m.recursionDepth++
- return func() {
- m.recursionDepth--
- }, nil
- }
- // ReadFull implements `io.ReadFull`
- func (m *Reader) ReadFull(p []byte) (int, error) {
- return m.R.ReadFull(p)
- }
- // Reset resets the underlying reader.
- func (m *Reader) Reset(r io.Reader) { m.R.Reset(r) }
- // Buffered returns the number of bytes currently in the read buffer.
- func (m *Reader) Buffered() int { return m.R.Buffered() }
- // BufferSize returns the capacity of the read buffer.
- func (m *Reader) BufferSize() int { return m.R.BufferSize() }
- // NextType returns the next object type to be decoded.
- func (m *Reader) NextType() (Type, error) {
- next, err := m.R.PeekByte()
- if err != nil {
- return InvalidType, err
- }
- t := getType(next)
- if t == InvalidType {
- return t, InvalidPrefixError(next)
- }
- if t == ExtensionType {
- v, err := m.peekExtensionType()
- if err != nil {
- return InvalidType, err
- }
- switch v {
- case Complex64Extension:
- return Complex64Type, nil
- case Complex128Extension:
- return Complex128Type, nil
- case TimeExtension, MsgTimeExtension:
- return TimeType, nil
- }
- }
- return t, nil
- }
- // IsNil returns whether or not
- // the next byte is a null messagepack byte
- func (m *Reader) IsNil() bool {
- p, err := m.R.PeekByte()
- return err == nil && p == mnil
- }
- // getNextSize returns the size of the next object on the wire.
- // returns (obj size, obj elements, error)
- // only maps and arrays have non-zero obj elements
- // for maps and arrays, obj size does not include elements
- //
- // use uintptr b/c it's guaranteed to be large enough
- // to hold whatever we can fit in memory.
- func getNextSize(r *fwd.Reader) (uintptr, uintptr, error) {
- lead, err := r.PeekByte()
- if err != nil {
- return 0, 0, err
- }
- spec := getBytespec(lead)
- size, mode := spec.size, spec.extra
- if size == 0 {
- return 0, 0, InvalidPrefixError(lead)
- }
- if mode >= 0 {
- return uintptr(size), uintptr(mode), nil
- }
- b, err := r.Peek(int(size))
- if err != nil {
- return 0, 0, err
- }
- switch mode {
- case extra8:
- return uintptr(size) + uintptr(b[1]), 0, nil
- case extra16:
- return uintptr(size) + uintptr(big.Uint16(b[1:])), 0, nil
- case extra32:
- return uintptr(size) + uintptr(big.Uint32(b[1:])), 0, nil
- case map16v:
- return uintptr(size), 2 * uintptr(big.Uint16(b[1:])), nil
- case map32v:
- return uintptr(size), 2 * uintptr(big.Uint32(b[1:])), nil
- case array16v:
- return uintptr(size), uintptr(big.Uint16(b[1:])), nil
- case array32v:
- return uintptr(size), uintptr(big.Uint32(b[1:])), nil
- default:
- return 0, 0, fatal
- }
- }
- // Skip skips over the next object, regardless of
- // its type. If it is an array or map, the whole array
- // or map will be skipped.
- func (m *Reader) Skip() error {
- var (
- v uintptr // bytes
- o uintptr // objects
- err error
- p []byte
- )
- // we can use the faster
- // method if we have enough
- // buffered data
- if m.R.Buffered() >= 5 {
- p, err = m.R.Peek(5)
- if err != nil {
- return err
- }
- v, o, err = getSize(p)
- if err != nil {
- return err
- }
- } else {
- v, o, err = getNextSize(m.R)
- if err != nil {
- return err
- }
- }
- // 'v' is always non-zero
- // if err == nil
- _, err = m.R.Skip(int(v))
- if err != nil {
- return err
- }
- // for maps and slices, skip elements with recursive call
- if done, err := m.recursiveCall(); err != nil {
- return err
- } else {
- defer done()
- }
- for x := uintptr(0); x < o; x++ {
- err = m.Skip()
- if err != nil {
- return err
- }
- }
- return nil
- }
- // ReadMapHeader reads the next object
- // as a map header and returns the size
- // of the map and the number of bytes written.
- // It will return a TypeError{} if the next
- // object is not a map.
- func (m *Reader) ReadMapHeader() (sz uint32, err error) {
- var p []byte
- var lead byte
- lead, err = m.R.PeekByte()
- if err != nil {
- return
- }
- if isfixmap(lead) {
- sz = uint32(rfixmap(lead))
- _, err = m.R.Skip(1)
- return
- }
- switch lead {
- case mmap16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- sz = uint32(big.Uint16(p[1:]))
- return
- case mmap32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- sz = big.Uint32(p[1:])
- return
- default:
- err = badPrefix(MapType, lead)
- return
- }
- }
- // ReadMapKey reads either a 'str' or 'bin' field from
- // the reader and returns the value as a []byte. It uses
- // scratch for storage if it is large enough.
- func (m *Reader) ReadMapKey(scratch []byte) ([]byte, error) {
- out, err := m.ReadStringAsBytes(scratch)
- if err != nil {
- if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType {
- key, err := m.ReadBytes(scratch)
- if uint64(len(key)) > m.GetMaxStringLength() {
- return nil, ErrLimitExceeded
- }
- return key, err
- }
- return nil, err
- }
- return out, nil
- }
- // ReadMapKeyPtr returns a []byte pointing to the contents
- // of a valid map key. The key cannot be empty, and it
- // must be shorter than the total buffer size of the
- // *Reader. Additionally, the returned slice is only
- // valid until the next *Reader method call. Users
- // should exercise extreme care when using this
- // method; writing into the returned slice may
- // corrupt future reads.
- func (m *Reader) ReadMapKeyPtr() ([]byte, error) {
- lead, err := m.R.PeekByte()
- if err != nil {
- return nil, err
- }
- var read int
- var p []byte
- if isfixstr(lead) {
- read = int(rfixstr(lead))
- m.R.Skip(1)
- goto fill
- }
- switch lead {
- case mstr8, mbin8:
- p, err = m.R.Next(2)
- if err != nil {
- return nil, err
- }
- read = int(p[1])
- case mstr16, mbin16:
- p, err = m.R.Next(3)
- if err != nil {
- return nil, err
- }
- read = int(big.Uint16(p[1:]))
- case mstr32, mbin32:
- p, err = m.R.Next(5)
- if err != nil {
- return nil, err
- }
- read = int(big.Uint32(p[1:]))
- default:
- return nil, badPrefix(StrType, lead)
- }
- fill:
- if read == 0 {
- return nil, ErrShortBytes
- }
- if uint64(read) > m.GetMaxStringLength() {
- return nil, ErrLimitExceeded
- }
- return m.R.Next(read)
- }
- // ReadArrayHeader reads the next object as an
- // array header and returns the size of the array
- // and the number of bytes read.
- func (m *Reader) ReadArrayHeader() (sz uint32, err error) {
- lead, err := m.R.PeekByte()
- if err != nil {
- return
- }
- if isfixarray(lead) {
- sz = uint32(rfixarray(lead))
- _, err = m.R.Skip(1)
- return
- }
- var p []byte
- switch lead {
- case marray16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- sz = uint32(big.Uint16(p[1:]))
- return
- case marray32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- sz = big.Uint32(p[1:])
- return
- default:
- err = badPrefix(ArrayType, lead)
- return
- }
- }
- // ReadNil reads a 'nil' MessagePack byte from the reader
- func (m *Reader) ReadNil() error {
- p, err := m.R.PeekByte()
- if err != nil {
- return err
- }
- if p != mnil {
- return badPrefix(NilType, p)
- }
- _, err = m.R.Skip(1)
- return err
- }
- // ReadFloat64 reads a float64 from the reader.
- // (If the value on the wire is encoded as a float32,
- // it will be up-cast to a float64.)
- func (m *Reader) ReadFloat64() (f float64, err error) {
- var p []byte
- p, err = m.R.Peek(9)
- if err != nil {
- // we'll allow a conversion from float32 to float64,
- // since we don't lose any precision
- if err == io.EOF && len(p) > 0 && p[0] == mfloat32 {
- ef, err := m.ReadFloat32()
- return float64(ef), err
- }
- return
- }
- if p[0] != mfloat64 {
- // see above
- if p[0] == mfloat32 {
- ef, err := m.ReadFloat32()
- return float64(ef), err
- }
- err = badPrefix(Float64Type, p[0])
- return
- }
- f = math.Float64frombits(getMuint64(p))
- _, err = m.R.Skip(9)
- return
- }
- // ReadFloat32 reads a float32 from the reader
- func (m *Reader) ReadFloat32() (f float32, err error) {
- var p []byte
- p, err = m.R.Peek(5)
- if err != nil {
- return
- }
- if p[0] != mfloat32 {
- err = badPrefix(Float32Type, p[0])
- return
- }
- f = math.Float32frombits(getMuint32(p))
- _, err = m.R.Skip(5)
- return
- }
- // ReadBool reads a bool from the reader
- func (m *Reader) ReadBool() (b bool, err error) {
- var p byte
- p, err = m.R.PeekByte()
- if err != nil {
- return
- }
- switch p {
- case mtrue:
- b = true
- case mfalse:
- default:
- err = badPrefix(BoolType, p)
- return
- }
- _, err = m.R.Skip(1)
- return
- }
- // ReadDuration reads a time.Duration from the reader
- func (m *Reader) ReadDuration() (d time.Duration, err error) {
- i, err := m.ReadInt64()
- return time.Duration(i), err
- }
- // ReadInt64 reads an int64 from the reader
- func (m *Reader) ReadInt64() (i int64, err error) {
- var p []byte
- lead, err := m.R.PeekByte()
- if err != nil {
- return
- }
- if isfixint(lead) {
- i = int64(rfixint(lead))
- _, err = m.R.Skip(1)
- return
- } else if isnfixint(lead) {
- i = int64(rnfixint(lead))
- _, err = m.R.Skip(1)
- return
- }
- switch lead {
- case mint8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- i = int64(getMint8(p))
- return
- case muint8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- i = int64(getMuint8(p))
- return
- case mint16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- i = int64(getMint16(p))
- return
- case muint16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- i = int64(getMuint16(p))
- return
- case mint32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- i = int64(getMint32(p))
- return
- case muint32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- i = int64(getMuint32(p))
- return
- case mint64:
- p, err = m.R.Next(9)
- if err != nil {
- return
- }
- i = getMint64(p)
- return
- case muint64:
- p, err = m.R.Next(9)
- if err != nil {
- return
- }
- u := getMuint64(p)
- if u > math.MaxInt64 {
- err = UintOverflow{Value: u, FailedBitsize: 64}
- return
- }
- i = int64(u)
- return
- default:
- err = badPrefix(IntType, lead)
- return
- }
- }
- // ReadInt32 reads an int32 from the reader
- func (m *Reader) ReadInt32() (i int32, err error) {
- var in int64
- in, err = m.ReadInt64()
- if in > math.MaxInt32 || in < math.MinInt32 {
- err = IntOverflow{Value: in, FailedBitsize: 32}
- return
- }
- i = int32(in)
- return
- }
- // ReadInt16 reads an int16 from the reader
- func (m *Reader) ReadInt16() (i int16, err error) {
- var in int64
- in, err = m.ReadInt64()
- if in > math.MaxInt16 || in < math.MinInt16 {
- err = IntOverflow{Value: in, FailedBitsize: 16}
- return
- }
- i = int16(in)
- return
- }
- // ReadInt8 reads an int8 from the reader
- func (m *Reader) ReadInt8() (i int8, err error) {
- var in int64
- in, err = m.ReadInt64()
- if in > math.MaxInt8 || in < math.MinInt8 {
- err = IntOverflow{Value: in, FailedBitsize: 8}
- return
- }
- i = int8(in)
- return
- }
- // ReadInt reads an int from the reader
- func (m *Reader) ReadInt() (i int, err error) {
- if smallint {
- var in int32
- in, err = m.ReadInt32()
- i = int(in)
- return
- }
- var in int64
- in, err = m.ReadInt64()
- i = int(in)
- return
- }
- // ReadUint64 reads a uint64 from the reader
- func (m *Reader) ReadUint64() (u uint64, err error) {
- var p []byte
- lead, err := m.R.PeekByte()
- if err != nil {
- return
- }
- if isfixint(lead) {
- u = uint64(rfixint(lead))
- _, err = m.R.Skip(1)
- return
- }
- switch lead {
- case mint8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- v := int64(getMint8(p))
- if v < 0 {
- err = UintBelowZero{Value: v}
- return
- }
- u = uint64(v)
- return
- case muint8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- u = uint64(getMuint8(p))
- return
- case mint16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- v := int64(getMint16(p))
- if v < 0 {
- err = UintBelowZero{Value: v}
- return
- }
- u = uint64(v)
- return
- case muint16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- u = uint64(getMuint16(p))
- return
- case mint32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- v := int64(getMint32(p))
- if v < 0 {
- err = UintBelowZero{Value: v}
- return
- }
- u = uint64(v)
- return
- case muint32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- u = uint64(getMuint32(p))
- return
- case mint64:
- p, err = m.R.Next(9)
- if err != nil {
- return
- }
- v := getMint64(p)
- if v < 0 {
- err = UintBelowZero{Value: v}
- return
- }
- u = uint64(v)
- return
- case muint64:
- p, err = m.R.Next(9)
- if err != nil {
- return
- }
- u = getMuint64(p)
- return
- default:
- if isnfixint(lead) {
- err = UintBelowZero{Value: int64(rnfixint(lead))}
- } else {
- err = badPrefix(UintType, lead)
- }
- return
- }
- }
- // ReadUint32 reads a uint32 from the reader
- func (m *Reader) ReadUint32() (u uint32, err error) {
- var in uint64
- in, err = m.ReadUint64()
- if in > math.MaxUint32 {
- err = UintOverflow{Value: in, FailedBitsize: 32}
- return
- }
- u = uint32(in)
- return
- }
- // ReadUint16 reads a uint16 from the reader
- func (m *Reader) ReadUint16() (u uint16, err error) {
- var in uint64
- in, err = m.ReadUint64()
- if in > math.MaxUint16 {
- err = UintOverflow{Value: in, FailedBitsize: 16}
- return
- }
- u = uint16(in)
- return
- }
- // ReadUint8 reads a uint8 from the reader
- func (m *Reader) ReadUint8() (u uint8, err error) {
- var in uint64
- in, err = m.ReadUint64()
- if in > math.MaxUint8 {
- err = UintOverflow{Value: in, FailedBitsize: 8}
- return
- }
- u = uint8(in)
- return
- }
- // ReadUint reads a uint from the reader
- func (m *Reader) ReadUint() (u uint, err error) {
- if smallint {
- var un uint32
- un, err = m.ReadUint32()
- u = uint(un)
- return
- }
- var un uint64
- un, err = m.ReadUint64()
- u = uint(un)
- return
- }
- // ReadByte is analogous to ReadUint8.
- //
- // NOTE: this is *not* an implementation
- // of io.ByteReader.
- func (m *Reader) ReadByte() (b byte, err error) {
- var in uint64
- in, err = m.ReadUint64()
- if in > math.MaxUint8 {
- err = UintOverflow{Value: in, FailedBitsize: 8}
- return
- }
- b = byte(in)
- return
- }
- // ReadBytes reads a MessagePack 'bin' object
- // from the reader and returns its value. It may
- // use 'scratch' for storage if it is non-nil.
- func (m *Reader) ReadBytes(scratch []byte) (b []byte, err error) {
- var p []byte
- var lead byte
- p, err = m.R.Peek(2)
- if err != nil {
- return
- }
- lead = p[0]
- var read int64
- switch lead {
- case mbin8:
- read = int64(p[1])
- m.R.Skip(2)
- case mbin16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- read = int64(big.Uint16(p[1:]))
- case mbin32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- read = int64(big.Uint32(p[1:]))
- default:
- err = badPrefix(BinType, lead)
- return
- }
- if int64(cap(scratch)) < read {
- if read > int64(m.GetMaxElements()) {
- err = ErrLimitExceeded
- return
- }
- b = make([]byte, read)
- } else {
- b = scratch[0:read]
- }
- _, err = m.R.ReadFull(b)
- return
- }
- // ReadBytesLimit reads a MessagePack 'bin' object
- // from the reader and returns its value. It may
- // use 'scratch' for storage if it is non-nil.
- // If n >= 0 this will be the maximum bytes read.
- // If n < 0, the cap(scratch) will be the limit.
- // If SetMaxElements has been used on the Reader,
- // that will only be checked if the scratch is too small.
- func (m *Reader) ReadBytesLimit(scratch []byte, n int64) (b []byte, err error) {
- var p []byte
- var lead byte
- p, err = m.R.Peek(2)
- if err != nil {
- return
- }
- lead = p[0]
- var read int64
- switch lead {
- case mbin8:
- read = int64(p[1])
- m.R.Skip(2)
- case mbin16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- read = int64(big.Uint16(p[1:]))
- case mbin32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- read = int64(big.Uint32(p[1:]))
- default:
- err = badPrefix(BinType, lead)
- return
- }
- if n < 0 {
- n = int64(cap(scratch))
- }
- if read > n {
- err = ErrLimitExceeded
- return
- }
- if int64(cap(scratch)) < read {
- b = make([]byte, read)
- if read > int64(m.GetMaxElements()) {
- err = ErrLimitExceeded
- return
- }
- } else {
- b = scratch[0:read]
- }
- _, err = m.R.ReadFull(b)
- return
- }
- // ReadBytesHeader reads the size header
- // of a MessagePack 'bin' object. The user
- // is responsible for dealing with the next
- // 'sz' bytes from the reader in an application-specific
- // way.
- func (m *Reader) ReadBytesHeader() (sz uint32, err error) {
- var p []byte
- lead, err := m.R.PeekByte()
- if err != nil {
- return
- }
- switch lead {
- case mbin8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- sz = uint32(p[1])
- return
- case mbin16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- sz = uint32(big.Uint16(p[1:]))
- return
- case mbin32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- sz = big.Uint32(p[1:])
- return
- default:
- err = badPrefix(BinType, lead)
- return
- }
- }
- // ReadExactBytes reads a MessagePack 'bin'-encoded
- // object off of the wire into the provided slice. An
- // ArrayError will be returned if the object is not
- // exactly the length of the input slice.
- func (m *Reader) ReadExactBytes(into []byte) error {
- p, err := m.R.Peek(2)
- if err != nil {
- return err
- }
- lead := p[0]
- var read int64 // bytes to read
- var skip int // prefix size to skip
- switch lead {
- case mbin8:
- read = int64(p[1])
- skip = 2
- case mbin16:
- p, err = m.R.Peek(3)
- if err != nil {
- return err
- }
- read = int64(big.Uint16(p[1:]))
- skip = 3
- case mbin32:
- p, err = m.R.Peek(5)
- if err != nil {
- return err
- }
- read = int64(big.Uint32(p[1:]))
- skip = 5
- default:
- return badPrefix(BinType, lead)
- }
- if read != int64(len(into)) {
- return ArrayError{Wanted: uint32(len(into)), Got: uint32(read)}
- }
- m.R.Skip(skip)
- _, err = m.R.ReadFull(into)
- return err
- }
- // ReadStringAsBytes reads a MessagePack 'str' (utf-8) string
- // and returns its value as bytes. It may use 'scratch' for storage
- // if it is non-nil.
- func (m *Reader) ReadStringAsBytes(scratch []byte) (b []byte, err error) {
- var p []byte
- lead, err := m.R.PeekByte()
- if err != nil {
- return
- }
- var read int64
- if isfixstr(lead) {
- read = int64(rfixstr(lead))
- m.R.Skip(1)
- goto fill
- }
- switch lead {
- case mstr8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- read = int64(p[1])
- case mstr16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- read = int64(big.Uint16(p[1:]))
- case mstr32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- read = int64(big.Uint32(p[1:]))
- default:
- err = badPrefix(StrType, lead)
- return
- }
- fill:
- if uint64(read) > m.GetMaxStringLength() {
- err = ErrLimitExceeded
- return
- }
- if int64(cap(scratch)) < read {
- b = make([]byte, read)
- } else {
- b = scratch[0:read]
- }
- _, err = m.R.ReadFull(b)
- return
- }
- // ReadStringHeader reads a string header
- // off of the wire. The user is then responsible
- // for dealing with the next 'sz' bytes from
- // the reader in an application-specific manner.
- func (m *Reader) ReadStringHeader() (sz uint32, err error) {
- lead, err := m.R.PeekByte()
- if err != nil {
- return
- }
- if isfixstr(lead) {
- sz = uint32(rfixstr(lead))
- m.R.Skip(1)
- return
- }
- var p []byte
- switch lead {
- case mstr8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- sz = uint32(p[1])
- return
- case mstr16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- sz = uint32(big.Uint16(p[1:]))
- return
- case mstr32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- sz = big.Uint32(p[1:])
- return
- default:
- err = badPrefix(StrType, lead)
- return
- }
- }
- // ReadString reads a utf-8 string from the reader
- func (m *Reader) ReadString() (s string, err error) {
- var read int64
- lead, err := m.R.PeekByte()
- if err != nil {
- return
- }
- var p []byte
- if isfixstr(lead) {
- read = int64(rfixstr(lead))
- m.R.Skip(1)
- goto fill
- }
- switch lead {
- case mstr8:
- p, err = m.R.Next(2)
- if err != nil {
- return
- }
- read = int64(p[1])
- case mstr16:
- p, err = m.R.Next(3)
- if err != nil {
- return
- }
- read = int64(big.Uint16(p[1:]))
- case mstr32:
- p, err = m.R.Next(5)
- if err != nil {
- return
- }
- read = int64(big.Uint32(p[1:]))
- default:
- err = badPrefix(StrType, lead)
- return
- }
- fill:
- if read == 0 {
- s, err = "", nil
- return
- }
- if uint64(read) > m.GetMaxStringLength() {
- err = ErrLimitExceeded
- return
- }
- // reading into the memory
- // that will become the string
- // itself has vastly superior
- // worst-case performance, because
- // the reader buffer doesn't have
- // to be large enough to hold the string.
- // the idea here is to make it more
- // difficult for someone malicious
- // to cause the system to run out of
- // memory by sending very large strings.
- //
- // NOTE: this works because the argument
- // passed to (*fwd.Reader).ReadFull escapes
- // to the heap; its argument may, in turn,
- // be passed to the underlying reader, and
- // thus escape analysis *must* conclude that
- // 'out' escapes.
- out := make([]byte, read)
- _, err = m.R.ReadFull(out)
- if err != nil {
- return
- }
- s = UnsafeString(out)
- return
- }
- // ReadComplex64 reads a complex64 from the reader
- func (m *Reader) ReadComplex64() (f complex64, err error) {
- var p []byte
- p, err = m.R.Peek(10)
- if err != nil {
- return
- }
- if p[0] != mfixext8 {
- err = badPrefix(Complex64Type, p[0])
- return
- }
- if int8(p[1]) != Complex64Extension {
- err = errExt(int8(p[1]), Complex64Extension)
- return
- }
- f = complex(math.Float32frombits(big.Uint32(p[2:])),
- math.Float32frombits(big.Uint32(p[6:])))
- _, err = m.R.Skip(10)
- return
- }
- // ReadComplex128 reads a complex128 from the reader
- func (m *Reader) ReadComplex128() (f complex128, err error) {
- var p []byte
- p, err = m.R.Peek(18)
- if err != nil {
- return
- }
- if p[0] != mfixext16 {
- err = badPrefix(Complex128Type, p[0])
- return
- }
- if int8(p[1]) != Complex128Extension {
- err = errExt(int8(p[1]), Complex128Extension)
- return
- }
- f = complex(math.Float64frombits(big.Uint64(p[2:])),
- math.Float64frombits(big.Uint64(p[10:])))
- _, err = m.R.Skip(18)
- return
- }
- // ReadMapStrIntf reads a MessagePack map into a map[string]interface{}.
- // (You must pass a non-nil map into the function.)
- func (m *Reader) ReadMapStrIntf(mp map[string]any) (err error) {
- var sz uint32
- sz, err = m.ReadMapHeader()
- if err != nil {
- return
- }
- for key := range mp {
- delete(mp, key)
- }
- if sz > m.GetMaxElements() {
- err = ErrLimitExceeded
- return
- }
- for i := uint32(0); i < sz; i++ {
- var key string
- var val any
- key, err = m.ReadString()
- if err != nil {
- return
- }
- val, err = m.ReadIntf()
- if err != nil {
- return
- }
- mp[key] = val
- }
- return
- }
- // ReadTimeUTC reads a time.Time object from the reader.
- // The returned time's location will be set to UTC.
- func (m *Reader) ReadTimeUTC() (t time.Time, err error) {
- t, err = m.ReadTime()
- return t.UTC(), err
- }
- // ReadTime reads a time.Time object from the reader.
- // The returned time's location will be set to time.Local.
- func (m *Reader) ReadTime() (t time.Time, err error) {
- offset, length, extType, err := m.peekExtensionHeader()
- if err != nil {
- return t, err
- }
- switch extType {
- case TimeExtension:
- var p []byte
- p, err = m.R.Peek(15)
- if err != nil {
- return
- }
- if p[0] != mext8 || p[1] != 12 {
- err = badPrefix(TimeType, p[0])
- return
- }
- if int8(p[2]) != TimeExtension {
- err = errExt(int8(p[2]), TimeExtension)
- return
- }
- sec, nsec := getUnix(p[3:])
- t = time.Unix(sec, int64(nsec)).Local()
- _, err = m.R.Skip(15)
- return
- case MsgTimeExtension:
- switch length {
- case 4, 8, 12:
- var tmp [12]byte
- _, err = m.R.Skip(offset)
- if err != nil {
- return
- }
- var n int
- n, err = m.R.Read(tmp[:length])
- if err != nil {
- return
- }
- if n != length {
- err = ErrShortBytes
- return
- }
- b := tmp[:length]
- switch length {
- case 4:
- t = time.Unix(int64(binary.BigEndian.Uint32(b)), 0).Local()
- case 8:
- v := binary.BigEndian.Uint64(b)
- nanos := int64(v >> 34)
- if nanos > 999999999 {
- // In timestamp 64 and timestamp 96 formats, nanoseconds must not be larger than 999999999.
- err = InvalidTimestamp{Nanos: nanos}
- return
- }
- t = time.Unix(int64(v&(1<<34-1)), nanos).Local()
- case 12:
- nanos := int64(binary.BigEndian.Uint32(b))
- if nanos > 999999999 {
- // In timestamp 64 and timestamp 96 formats, nanoseconds must not be larger than 999999999.
- err = InvalidTimestamp{Nanos: nanos}
- return
- }
- ux := int64(binary.BigEndian.Uint64(b[4:]))
- t = time.Unix(ux, nanos).Local()
- }
- default:
- err = InvalidTimestamp{FieldLength: length}
- }
- default:
- err = errExt(extType, TimeExtension)
- }
- return
- }
- // ReadJSONNumber reads an integer or a float value and return as json.Number
- func (m *Reader) ReadJSONNumber() (n json.Number, err error) {
- t, err := m.NextType()
- if err != nil {
- return
- }
- switch t {
- case IntType:
- v, err := m.ReadInt64()
- if err == nil {
- return json.Number(strconv.FormatInt(v, 10)), nil
- }
- return "", err
- case UintType:
- v, err := m.ReadUint64()
- if err == nil {
- return json.Number(strconv.FormatUint(v, 10)), nil
- }
- return "", err
- case Float32Type, Float64Type:
- v, err := m.ReadFloat64()
- if err == nil {
- return json.Number(strconv.FormatFloat(v, 'f', -1, 64)), nil
- }
- return "", err
- }
- return "", TypeError{Method: NumberType, Encoded: t}
- }
- // ReadIntf reads out the next object as a raw interface{}/any.
- // Arrays are decoded as []interface{}, and maps are decoded
- // as map[string]interface{}. Integers are decoded as int64
- // and unsigned integers are decoded as uint64.
- func (m *Reader) ReadIntf() (i any, err error) {
- var t Type
- t, err = m.NextType()
- if err != nil {
- return
- }
- switch t {
- case BoolType:
- i, err = m.ReadBool()
- return
- case IntType:
- i, err = m.ReadInt64()
- return
- case UintType:
- i, err = m.ReadUint64()
- return
- case BinType:
- i, err = m.ReadBytes(nil)
- return
- case StrType:
- i, err = m.ReadString()
- return
- case Complex64Type:
- i, err = m.ReadComplex64()
- return
- case Complex128Type:
- i, err = m.ReadComplex128()
- return
- case TimeType:
- i, err = m.ReadTime()
- return
- case DurationType:
- i, err = m.ReadDuration()
- return
- case ExtensionType:
- var t int8
- t, err = m.peekExtensionType()
- if err != nil {
- return
- }
- f, ok := extensionReg[t]
- if ok {
- e := f()
- err = m.ReadExtension(e)
- i = e
- return
- }
- var e RawExtension
- e.Type = t
- err = m.ReadExtension(&e)
- i = &e
- return
- case MapType:
- // This can call back here, so treat as recursive call.
- if done, err := m.recursiveCall(); err != nil {
- return nil, err
- } else {
- defer done()
- }
- mp := make(map[string]any)
- err = m.ReadMapStrIntf(mp)
- i = mp
- return
- case NilType:
- err = m.ReadNil()
- i = nil
- return
- case Float32Type:
- i, err = m.ReadFloat32()
- return
- case Float64Type:
- i, err = m.ReadFloat64()
- return
- case ArrayType:
- var sz uint32
- sz, err = m.ReadArrayHeader()
- if err != nil {
- return
- }
- if done, err := m.recursiveCall(); err != nil {
- return nil, err
- } else {
- defer done()
- }
- if sz > m.GetMaxElements() {
- err = ErrLimitExceeded
- return
- }
- out := make([]any, int(sz))
- for j := range out {
- out[j], err = m.ReadIntf()
- if err != nil {
- return
- }
- }
- i = out
- return
- default:
- return nil, fatal // unreachable
- }
- }
- // ReadBinaryUnmarshal reads a binary-encoded object from the reader and unmarshals it into dst.
- func (m *Reader) ReadBinaryUnmarshal(dst encoding.BinaryUnmarshaler) (err error) {
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("msgp: panic during UnmarshalBinary: %v", r)
- }
- }()
- tmp := bytesPool.Get().([]byte)
- defer bytesPool.Put(tmp) //nolint:staticcheck
- tmp, err = m.ReadBytes(tmp[:0])
- if err != nil {
- return
- }
- return dst.UnmarshalBinary(tmp)
- }
- // ReadTextUnmarshal reads a text-encoded bin array from the reader and unmarshals it into dst.
- func (m *Reader) ReadTextUnmarshal(dst encoding.TextUnmarshaler) (err error) {
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("msgp: panic during UnmarshalText: %v", r)
- }
- }()
- tmp := bytesPool.Get().([]byte)
- defer bytesPool.Put(tmp) //nolint:staticcheck
- tmp, err = m.ReadBytes(tmp[:0])
- if err != nil {
- return
- }
- return dst.UnmarshalText(tmp)
- }
- // ReadTextUnmarshalString reads a text-encoded string from the reader and unmarshals it into dst.
- func (m *Reader) ReadTextUnmarshalString(dst encoding.TextUnmarshaler) (err error) {
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("msgp: panic during UnmarshalText: %v", r)
- }
- }()
- tmp := bytesPool.Get().([]byte)
- defer bytesPool.Put(tmp) //nolint:staticcheck
- tmp, err = m.ReadStringAsBytes(tmp[:0])
- if err != nil {
- return
- }
- return dst.UnmarshalText(tmp)
- }
|