Skip to content

Commit

Permalink
Add RequireSafeStrings to prevent unsafe string unmarshalling; see sh…
Browse files Browse the repository at this point in the history
  • Loading branch information
swdunlop authored Jul 10, 2021
1 parent 85f28ad commit f12f294
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 7 deletions.
4 changes: 2 additions & 2 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import "github.com/shamaton/msgpack/v2/internal/decoding"
// UnmarshalAsMap decodes data that is encoded as map format.
// This is the same thing that StructAsArray sets false.
func UnmarshalAsMap(data []byte, v interface{}) error {
return decoding.Decode(data, v, false)
return decoding.Decode(data, v, false, RequireSafeStrings)
}

// UnmarshalAsArray decodes data that is encoded as array format.
// This is the same thing that StructAsArray sets true.
func UnmarshalAsArray(data []byte, v interface{}) error {
return decoding.Decode(data, v, true)
return decoding.Decode(data, v, true, RequireSafeStrings)
}
9 changes: 5 additions & 4 deletions internal/decoding/decoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ import (
)

type decoder struct {
data []byte
asArray bool
data []byte
asArray bool
stringSafety bool
common.Common
}

// Decode analyzes the MessagePack-encoded data and stores
// the result into the pointer of v.
func Decode(data []byte, v interface{}, asArray bool) error {
d := decoder{data: data, asArray: asArray}
func Decode(data []byte, v interface{}, asArray, stringSafety bool) error {
d := decoder{data: data, asArray: asArray, stringSafety: stringSafety}

rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Ptr {
Expand Down
3 changes: 3 additions & 0 deletions internal/decoding/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ func (d *decoder) asString(offset int, k reflect.Kind) (string, int, error) {
return emptyString, 0, err
}
bs, offset := d.asStringByte(offset, l, k)
if d.stringSafety {
return string(bs), offset, nil
}
return *(*string)(unsafe.Pointer(&bs)), offset, nil
}

Expand Down
6 changes: 5 additions & 1 deletion msgpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import (
// If this option sets true, default encoding sets to array-format.
var StructAsArray = false

// RequireSafeStrings disables the use of unsafe to decode strings. This is much slower, but makes
// unmarshaled strings immutable.
var RequireSafeStrings = false

// Marshal returns the MessagePack-encoded byte array of v.
func Marshal(v interface{}) ([]byte, error) {
return encoding.Encode(v, StructAsArray)
Expand All @@ -21,7 +25,7 @@ func Marshal(v interface{}) ([]byte, error) {
// Unmarshal analyzes the MessagePack-encoded data and stores
// the result into the pointer of v.
func Unmarshal(data []byte, v interface{}) error {
return decoding.Decode(data, v, StructAsArray)
return decoding.Decode(data, v, StructAsArray, RequireSafeStrings)
}

// AddExtCoder adds encoders for extension types.
Expand Down

0 comments on commit f12f294

Please sign in to comment.