Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add option to decode to *big.Int instead of big.Int when decoding CBOR bignum into any #444

Closed
extemporalgenome opened this issue Dec 1, 2023 · 2 comments · Fixed by #456
Assignees
Milestone

Comments

@extemporalgenome
Copy link

What version of fxamacker/cbor are you using?

v2.5.0

Does this issue reproduce with the latest release?

yes

What OS and CPU architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN='/Users/kgillette/usr/bin'
GOCACHE='/Users/kgillette/Library/Caches/go-build'
GOENV='/Users/kgillette/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/kgillette/go/pkg/mod'
GOOS='darwin'
GOPATH='/Users/kgillette/go'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.21.0'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/kgillette/src/github.com/fxamacker/cbor/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/bh/9j45c9dj7ps89q48n_34m44c0000gn/T/go-build560026312=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

Decode CBOR big integer into any:

https://go.dev/play/p/qDEgHDEJXum

What did you expect to see?

The stored type would be *big.Int

What did you see instead?

The stored type is big.Int

Context: *big.Int is designed to be pointerized: all *big.Int methods take and return pointers, and in general, code using Go big integers will have no reason to dereference (or deal with dereferenced) values.

Dealing with dereferenced big integers at depth can be a pain (such as when the big integers are arbitrarily nested within maps/slices), especially when interoperating with other code which expects *big.Int; this can require post-process recursive "fixups" of the data this library produces.

Furthermore, since a big.Int is not pointer-sized or smaller, storing it in an interface requires an additional heap allocation compared to storing the standard *big.Int in an interface (which requires no additional allocations).

@fxamacker fxamacker changed the title bug: big.Int is handled as a non-ptr, though *big.Int is intended to be used as a pointer feature: add option to decode to *big.Int instead of big.Int when decoding CBOR bignum into any Dec 2, 2023
@fxamacker
Copy link
Owner

fxamacker commented Dec 2, 2023

@extemporalgenome Thanks for opening this issue! 👍 I can see how it would be useful to decode into *big.Int instead of big.Int. I will add this to the next release.

Go playground: https://go.dev/play/p/W8Xvr80bOk3

import (
	"encoding/hex"
	"fmt"
	"log"

	"github.com/fxamacker/cbor/v2"
)

func main() {
	data, err := hex.DecodeString("c250ffffffffffffffffffffffffffffffff") // CBOR bignum
	if err != nil {
		log.Fatalln(err) // bad (non-hex) hardcoded data
	}

	var v any

	err = cbor.Unmarshal(data, &v)
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Printf("%T\n", v)

	// Desired Output: *big.Int
	//  Actual Output: big.Int
}

@extemporalgenome
Copy link
Author

extemporalgenome commented Feb 5, 2024

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants