Skip to content

math/big: Big.Int inconsistently marshals to JSON #28946

@TACIXAT

Description

@TACIXAT

What version of Go are you using (go version)?

$ go version
go version go1.11 linux/amd64

Does this issue reproduce with the latest release?

Reproduces on go playground.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/dg/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/dg/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build283450947=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Marshal a big.Int to JSON and it doesn't work.

Marshal a big.Int to JSON when inside a struct and it doesn't work.

Marshal a big.Int to JSON when it's inside a slice of structs and it does work.

package main

import (
	"fmt"
	"math/big"
	"encoding/json"
)

type Simple struct {
	I big.Int
}

type List struct {
	S []Simple
}

func main() {
	i := big.Int{}
	b := []byte{
		0x55, 0x55, 0x55, 0x55, 0x55, 
		0x55, 0x55, 0x55, 0x55, 0x55}
		
	i.SetBytes(b)
	
	fmt.Println("b", b)
	fmt.Println("i", i)
	
	// marshal and unmarshal big int
	j, _ := json.Marshal(i)
	// fmt.Println("ji", j)
	
	i2 := big.Int{}
	_ = json.Unmarshal(j, &i2)
	fmt.Println("i2", i2)
	
	// marshal and unmarshal big int in struct
	s := Simple{
		I: i}
		
	j, _ = json.Marshal(s)
	// fmt.Println("js", j)
	
	s2 := Simple{}
	_ = json.Unmarshal(j, &s2)
	fmt.Println("s2", s2)
	
	// marshal and unmarshal big int in struct in list
	l := List{}
	l.S = append(l.S, s)
	
	j, _ = json.Marshal(l)
	// fmt.Println("jl", j)
	
	l2 := List{}
	_ = json.Unmarshal(j, &l2)
	fmt.Println("l2", l2)
}
b [85 85 85 85 85 85 85 85 85 85]
i {false [1431655765 1431655765 21845]}
i2 {false []}
s2 {{false []}}
l2 {[{{false [1431655765 1431655765 21845]}}]}

https://play.golang.org/p/1pI0OCtLQDa

What did you expect to see?

Either it to fail consistently or work consistently.

What did you see instead?

The big.Int sometimes marshals correctly and sometimes does not.

What do you want out of this issue?

I'm mostly just curious why it works sometimes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions