mirror of https://github.com/tidwall/gjson.git
Fix string output for large integers
This fix makes calling String() on a JSON Number return the original value as it was represented in the JSON document for signed and unsigned integers. This ensures that very big (plus-53bit) integers are correctly returned. Floating points maintain their previous behavior [-+]?[0-9]*\.?[0-9]*. closes #74
This commit is contained in:
parent
f123b34087
commit
ba784d767a
17
gjson.go
17
gjson.go
|
@ -77,7 +77,20 @@ func (t Result) String() string {
|
|||
case False:
|
||||
return "false"
|
||||
case Number:
|
||||
return strconv.FormatFloat(t.Num, 'f', -1, 64)
|
||||
if len(t.Raw) == 0 {
|
||||
// calculated result
|
||||
return strconv.FormatFloat(t.Num, 'f', -1, 64)
|
||||
}
|
||||
var i int
|
||||
if t.Raw[0] == '-' {
|
||||
i++
|
||||
}
|
||||
for ; i < len(t.Raw); i++ {
|
||||
if t.Raw[i] < '0' || t.Raw[i] > '9' {
|
||||
return strconv.FormatFloat(t.Num, 'f', -1, 64)
|
||||
}
|
||||
}
|
||||
return t.Raw
|
||||
case String:
|
||||
return t.Str
|
||||
case JSON:
|
||||
|
@ -1288,7 +1301,7 @@ func parseArray(c *parseContext, i int, path string) (int, bool) {
|
|||
if rp.alogok {
|
||||
break
|
||||
}
|
||||
c.value.Raw = val
|
||||
c.value.Raw = ""
|
||||
c.value.Type = Number
|
||||
c.value.Num = float64(h - 1)
|
||||
c.calcd = true
|
||||
|
|
|
@ -479,7 +479,8 @@ func TestBasic4(t *testing.T) {
|
|||
}
|
||||
token = get(basicJSON, "arr.#")
|
||||
if token.String() != "6" {
|
||||
t.Fatal("expecting '6'", "got", token.String())
|
||||
fmt.Printf("%#v\n", token)
|
||||
t.Fatal("expecting 6", "got", token.String())
|
||||
}
|
||||
token = get(basicJSON, "arr.3.hello")
|
||||
if token.String() != "world" {
|
||||
|
@ -1354,3 +1355,39 @@ null
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNumUint64String(t *testing.T) {
|
||||
i := 9007199254740993 //2^53 + 1
|
||||
j := fmt.Sprintf(`{"data": [ %d, "hello" ] }`, i)
|
||||
res := Get(j, "data.0")
|
||||
if res.String() != "9007199254740993" {
|
||||
t.Fatalf("expected '%v', got '%v'", "9007199254740993", res.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumInt64String(t *testing.T) {
|
||||
i := -9007199254740993
|
||||
j := fmt.Sprintf(`{"data":[ "hello", %d ]}`, i)
|
||||
res := Get(j, "data.1")
|
||||
if res.String() != "-9007199254740993" {
|
||||
t.Fatalf("expected '%v', got '%v'", "-9007199254740993", res.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumBigString(t *testing.T) {
|
||||
i := "900719925474099301239109123101" // very big
|
||||
j := fmt.Sprintf(`{"data":[ "hello", "%s" ]}`, i)
|
||||
res := Get(j, "data.1")
|
||||
if res.String() != "900719925474099301239109123101" {
|
||||
t.Fatalf("expected '%v', got '%v'", "900719925474099301239109123101", res.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumFloatString(t *testing.T) {
|
||||
i := -9007199254740993
|
||||
j := fmt.Sprintf(`{"data":[ "hello", %d ]}`, i) //No quotes around value!!
|
||||
res := Get(j, "data.1")
|
||||
if res.String() != "-9007199254740993" {
|
||||
t.Fatalf("expected '%v', got '%v'", "-9007199254740993", res.String())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue