Skip to content

Commit

Permalink
Allow rejection of NaN and Inf float values on encode and decode.
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Luddy <[email protected]>
  • Loading branch information
benluddy committed Apr 8, 2024
1 parent 9f099e8 commit c6c93a1
Show file tree
Hide file tree
Showing 5 changed files with 619 additions and 10 deletions.
59 changes: 59 additions & 0 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,43 @@ func NewSimpleValueRegistryFromDefaults(fns ...func(*SimpleValueRegistry) error)
return &r, nil
}

// NaNMode specifies how to decode floating-point values (major type 7, additional information 25
// through 27) representing NaN (not-a-number).
type NaNMode int

const (
// NaNDecodeAllowed will decode NaN values to Go float32 or float64.
NaNDecodeAllowed NaNMode = iota

// NaNDecodeForbidden will return an UnacceptableDataItemError on an attempt to decode a NaN value.
NaNDecodeForbidden

maxNaNDecode
)

func (ndm NaNMode) valid() bool {
return ndm >= 0 && ndm < maxNaNDecode
}

// InfMode specifies how to decode floating-point values (major type 7, additional information 25
// through 27) representing positive or negative infinity.
type InfMode int

const (
// InfDecodeAllowed will decode infinite values to Go float32 or float64.
InfDecodeAllowed InfMode = iota

// InfDecodeForbidden will return an UnacceptableDataItemError on an attempt to decode an
// infinite value.
InfDecodeForbidden

maxInfDecode
)

func (idm InfMode) valid() bool {
return idm >= 0 && idm < maxInfDecode
}

// DecOptions specifies decoding options.
type DecOptions struct {
// DupMapKey specifies whether to enforce duplicate map key.
Expand Down Expand Up @@ -645,6 +682,14 @@ type DecOptions struct {
// Users may provide a custom SimpleValueRegistry constructed via
// NewSimpleValueRegistryFromDefaults.
SimpleValues *SimpleValueRegistry

// NaNDec specifies how to decode floating-point values (major type 7, additional
// information 25 through 27) representing NaN (not-a-number).
NaNDec NaNMode

// InfDec specifies how to decode floating-point values (major type 7, additional
// information 25 through 27) representing positive or negative infinity.
InfDec InfMode
}

// DecMode returns DecMode with immutable options and no tags (safe for concurrency).
Expand Down Expand Up @@ -815,6 +860,14 @@ func (opts DecOptions) decMode() (*decMode, error) {
return nil, errors.New("cbor: invalid TimeTagToAny " + strconv.Itoa(int(opts.TimeTagToAny)))
}

if !opts.NaNDec.valid() {
return nil, errors.New("cbor: invalid NaNDec " + strconv.Itoa(int(opts.NaNDec)))
}

if !opts.InfDec.valid() {
return nil, errors.New("cbor: invalid InfDec " + strconv.Itoa(int(opts.InfDec)))
}

dm := decMode{
dupMapKey: opts.DupMapKey,
timeTag: opts.TimeTag,
Expand All @@ -836,6 +889,8 @@ func (opts DecOptions) decMode() (*decMode, error) {
unrecognizedTagToAny: opts.UnrecognizedTagToAny,
timeTagToAny: opts.TimeTagToAny,
simpleValues: simpleValues,
nanDec: opts.NaNDec,
infDec: opts.InfDec,
}

return &dm, nil
Expand Down Expand Up @@ -909,6 +964,8 @@ type decMode struct {
unrecognizedTagToAny UnrecognizedTagToAnyMode
timeTagToAny TimeTagToAnyMode
simpleValues *SimpleValueRegistry
nanDec NaNMode
infDec InfMode
}

var defaultDecMode, _ = DecOptions{}.decMode()
Expand Down Expand Up @@ -943,6 +1000,8 @@ func (dm *decMode) DecOptions() DecOptions {
UnrecognizedTagToAny: dm.unrecognizedTagToAny,
TimeTagToAny: dm.timeTagToAny,
SimpleValues: simpleValues,
NaNDec: dm.nanDec,
InfDec: dm.infDec,
}
}

Expand Down
Loading

0 comments on commit c6c93a1

Please sign in to comment.