Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions msgp/fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,21 @@ func FuzzReader(f *testing.F) {
reset()
r.ReadUint8()
reset()
r.ReadBinaryUnmarshal(encodingReader{})
reset()
r.ReadTextUnmarshal(encodingReader{})
reset()
r.ReadTextUnmarshalString(encodingReader{})
reset()
for range ReadArray(r, r.ReadInt) {
}
reset()
iter, errfn := ReadMap(r, r.ReadString, r.ReadUint64)
for range iter {
}
errfn()
reset()

r.Skip()
reset()

Expand Down Expand Up @@ -170,6 +185,14 @@ func FuzzReadBytes(f *testing.F) {
ReadUint64Bytes(data)
ReadUintBytes(data)
UnmarshalAsJSON(io.Discard, data)
iter, errfn := ReadArrayBytes(data, ReadIntBytes)
for range iter {
}
errfn()
iter2, errfn2 := ReadMapBytes(data, ReadStringBytes, ReadUint64Bytes)
for range iter2 {
}
errfn2()
Skip(data)
})
}
Expand Down Expand Up @@ -306,3 +329,13 @@ func parseCorpusValue(line []byte) ([]byte, error) {
}
return nil, fmt.Errorf("expected []byte")
}

type encodingReader struct{}

func (e encodingReader) UnmarshalBinary(data []byte) error {
return nil
}

func (e encodingReader) UnmarshalText(data []byte) error {
return nil
}
3 changes: 2 additions & 1 deletion msgp/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
// The type parameter V specifies the type of the elements in the array.
// The returned iterator implements the iter.Seq[V] interface,
// allowing for sequential access to the array elements.
// The iterator will always stop after one error has been encountered.
func ReadArray[T any](m *Reader, readFn func() (T, error)) iter.Seq2[T, error] {
return func(yield func(T, error) bool) {
// Check if nil
Expand All @@ -31,7 +32,7 @@ func ReadArray[T any](m *Reader, readFn func() (T, error)) iter.Seq2[T, error] {
for range length {
var v T
v, err = readFn()
if !yield(v, err) {
if !yield(v, err) || err != nil {
return
}
}
Expand Down
16 changes: 16 additions & 0 deletions msgp/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"math"
"strconv"
Expand Down Expand Up @@ -1571,6 +1572,11 @@ func (m *Reader) ReadIntf() (i any, err error) {

// 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])
Expand All @@ -1582,6 +1588,11 @@ func (m *Reader) ReadBinaryUnmarshal(dst encoding.BinaryUnmarshaler) (err error)

// 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])
Expand All @@ -1593,6 +1604,11 @@ func (m *Reader) ReadTextUnmarshal(dst encoding.TextUnmarshaler) (err error) {

// 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])
Expand Down
38 changes: 32 additions & 6 deletions msgp/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"io"
"math"
"reflect"
Expand Down Expand Up @@ -447,6 +448,9 @@ func (mw *Writer) WriteUint(u uint) error { return mw.WriteUint64(uint64(u)) }

// WriteBytes writes binary as 'bin' to the writer
func (mw *Writer) WriteBytes(b []byte) error {
if uint64(len(b)) > math.MaxInt32 {
return ErrLimitExceeded
}
sz := uint32(len(b))
var err error
switch {
Expand Down Expand Up @@ -489,6 +493,10 @@ func (mw *Writer) WriteBool(b bool) error {
// WriteString writes a messagepack string to the writer.
// (This is NOT an implementation of io.StringWriter)
func (mw *Writer) WriteString(s string) error {
if uint64(len(s)) > math.MaxInt32 {
return ErrLimitExceeded
}

sz := uint32(len(s))
var err error
switch {
Expand Down Expand Up @@ -527,6 +535,9 @@ func (mw *Writer) WriteStringHeader(sz uint32) error {
// WriteStringFromBytes writes a 'str' object
// from a []byte.
func (mw *Writer) WriteStringFromBytes(str []byte) error {
if uint64(len(str)) > math.MaxInt32 {
return ErrLimitExceeded
}
sz := uint32(len(str))
var err error
switch {
Expand Down Expand Up @@ -891,10 +902,15 @@ var bytesPool = sync.Pool{New: func() any { return make([]byte, 0, 1024) }}

// WriteBinaryAppender will write the bytes from the given
// encoding.BinaryAppender as a bin array.
func (mw *Writer) WriteBinaryAppender(b encoding.BinaryAppender) error {
func (mw *Writer) WriteBinaryAppender(b encoding.BinaryAppender) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("msgp: panic during AppendBinary: %v", r)
}
}()
dst := bytesPool.Get().([]byte)
defer bytesPool.Put(dst) //nolint:staticcheck
dst, err := b.AppendBinary(dst[:0])
dst, err = b.AppendBinary(dst[:0])
if err != nil {
return err
}
Expand All @@ -903,10 +919,15 @@ func (mw *Writer) WriteBinaryAppender(b encoding.BinaryAppender) error {

// WriteTextAppender will write the bytes from the given
// encoding.TextAppender as a bin array.
func (mw *Writer) WriteTextAppender(b encoding.TextAppender) error {
func (mw *Writer) WriteTextAppender(b encoding.TextAppender) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("msgp: panic during AppendText: %v", r)
}
}()
dst := bytesPool.Get().([]byte)
defer bytesPool.Put(dst) //nolint:staticcheck
dst, err := b.AppendText(dst[:0])
dst, err = b.AppendText(dst[:0])
if err != nil {
return err
}
Expand All @@ -915,10 +936,15 @@ func (mw *Writer) WriteTextAppender(b encoding.TextAppender) error {

// WriteTextAppenderString will write the bytes from the given
// encoding.TextAppender as a string.
func (mw *Writer) WriteTextAppenderString(b encoding.TextAppender) error {
func (mw *Writer) WriteTextAppenderString(b encoding.TextAppender) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("msgp: panic during AppendText: %v", r)
}
}()
dst := bytesPool.Get().([]byte)
defer bytesPool.Put(dst) //nolint:staticcheck
dst, err := b.AppendText(dst[:0])
dst, err = b.AppendText(dst[:0])
if err != nil {
return err
}
Expand Down
Loading