internal/core/convert: fix conversion from float
Conversion from Go types big.Float, float32 and
float64 always added an error to the OpContext even
when no error had occured.
Fixes #749
Closes #761
https://github.com/cuelang/cue/pull/761
GitOrigin-RevId: 3476e9fc96bde56801c1cadda0004c529e70af39
Change-Id: I253846087ddaf5dbfd9bd2ade4cf917101e482e5
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/8721
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/testdata/script/issue749.txt b/cmd/cue/cmd/testdata/script/issue749.txt
new file mode 100644
index 0000000..397c181
--- /dev/null
+++ b/cmd/cue/cmd/testdata/script/issue749.txt
@@ -0,0 +1,13 @@
+cue eval ./float.cue
+cmp stderr expect-stderr
+cmp stdout expect-stdout
+-- float.cue --
+import "strconv"
+
+x : strconv.ParseFloat("3.14", 32)
+y : strconv.ParseFloat("3.14", 64)
+
+-- expect-stderr --
+-- expect-stdout --
+x: 3.140000104904175
+y: 3.14
\ No newline at end of file
diff --git a/cue/types_test.go b/cue/types_test.go
index fed0acd..d8212fb 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -978,6 +978,38 @@
}
}
+func TestFillFloat(t *testing.T) {
+ // This tests panics for issue #749
+
+ want := `{
+ x: 3.14
+}`
+
+ filltest := func(x interface{}) {
+ r := &Runtime{}
+ i, err := r.Compile("test", `
+ x: number
+ `)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ i, err = i.Fill(x, "x")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ got := fmt.Sprint(i.Value())
+ if got != want {
+ t.Errorf("got: %s\nwant: %s", got, want)
+ }
+ }
+
+ filltest(float32(3.14))
+ filltest(float64(3.14))
+ filltest(big.NewFloat(3.14))
+}
+
func TestValue_LookupDef(t *testing.T) {
r := &Runtime{}
diff --git a/internal/core/convert/go.go b/internal/core/convert/go.go
index 2f0fdc5..5191467 100644
--- a/internal/core/convert/go.go
+++ b/internal/core/convert/go.go
@@ -274,7 +274,9 @@
case *big.Float:
n := &adt.Num{Src: src, K: adt.FloatKind}
_, _, err := n.X.SetString(v.String())
- ctx.AddErr(errors.Promote(err, "invalid float"))
+ if err != nil {
+ return ctx.AddErr(errors.Promote(err, "invalid float"))
+ }
return n
case *apd.Decimal:
@@ -355,13 +357,17 @@
return toUint(ctx, uint64(v))
case float64:
n := &adt.Num{Src: src, K: adt.FloatKind}
- _, _, err := n.X.SetString(fmt.Sprintf("%g", v))
- ctx.AddErr(errors.Promote(err, "invalid float"))
+ _, _, err := n.X.SetString(fmt.Sprint(v))
+ if err != nil {
+ return ctx.AddErr(errors.Promote(err, "invalid float"))
+ }
return n
case float32:
n := &adt.Num{Src: src, K: adt.FloatKind}
- _, _, err := n.X.SetString(fmt.Sprintf("%g", v))
- ctx.AddErr(errors.Promote(err, "invalid float"))
+ _, _, err := n.X.SetString(fmt.Sprint(v))
+ if err != nil {
+ return ctx.AddErr(errors.Promote(err, "invalid float"))
+ }
return n
case reflect.Value: