Browse Source

Change floats to ints recursively on env encoding

Fixes #6246
Docker-DCO-1.1-Signed-off-by: Alexandr Morozov <lk4d4math@gmail.com> (github: LK4D4)
LK4D4 11 years ago
parent
commit
1d3d1c5d2b
2 changed files with 58 additions and 4 deletions
  1. 17 4
      engine/env.go
  2. 41 0
      engine/env_test.go

+ 17 - 4
engine/env.go

@@ -199,6 +199,22 @@ func (env *Env) SetAuto(k string, v interface{}) {
 	}
 }
 
+func changeFloats(v interface{}) interface{} {
+	switch v := v.(type) {
+	case float64:
+		return int(v)
+	case map[string]interface{}:
+		for key, val := range v {
+			v[key] = changeFloats(val)
+		}
+	case []interface{}:
+		for idx, val := range v {
+			v[idx] = changeFloats(val)
+		}
+	}
+	return v
+}
+
 func (env *Env) Encode(dst io.Writer) error {
 	m := make(map[string]interface{})
 	for k, v := range env.Map() {
@@ -207,10 +223,7 @@ func (env *Env) Encode(dst io.Writer) error {
 			// FIXME: we fix-convert float values to int, because
 			// encoding/json decodes integers to float64, but cannot encode them back.
 			// (See http://golang.org/src/pkg/encoding/json/decode.go#L46)
-			if fval, isFloat := val.(float64); isFloat {
-				val = int(fval)
-			}
-			m[k] = val
+			m[k] = changeFloats(val)
 		} else {
 			m[k] = v
 		}

+ 41 - 0
engine/env_test.go

@@ -2,6 +2,7 @@ package engine
 
 import (
 	"bytes"
+	"encoding/json"
 	"testing"
 
 	"github.com/dotcloud/docker/pkg/testutils"
@@ -269,3 +270,43 @@ func BenchmarkDecode(b *testing.B) {
 		reader.Seek(0, 0)
 	}
 }
+
+func TestLongNumbers(t *testing.T) {
+	type T struct {
+		TestNum int64
+	}
+	v := T{67108864}
+	var buf bytes.Buffer
+	e := &Env{}
+	e.SetJson("Test", v)
+	if err := e.Encode(&buf); err != nil {
+		t.Fatal(err)
+	}
+	res := make(map[string]T)
+	if err := json.Unmarshal(buf.Bytes(), &res); err != nil {
+		t.Fatal(err)
+	}
+	if res["Test"].TestNum != v.TestNum {
+		t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum)
+	}
+}
+
+func TestLongNumbersArray(t *testing.T) {
+	type T struct {
+		TestNum []int64
+	}
+	v := T{[]int64{67108864}}
+	var buf bytes.Buffer
+	e := &Env{}
+	e.SetJson("Test", v)
+	if err := e.Encode(&buf); err != nil {
+		t.Fatal(err)
+	}
+	res := make(map[string]T)
+	if err := json.Unmarshal(buf.Bytes(), &res); err != nil {
+		t.Fatal(err)
+	}
+	if res["Test"].TestNum[0] != v.TestNum[0] {
+		t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum)
+	}
+}