From f94bac0643ad5d39c740c57c6c8ea6a4569a1db0 Mon Sep 17 00:00:00 2001 From: Oleg Sidorov Date: Wed, 17 Jul 2019 10:21:17 +0200 Subject: [PATCH] chartutil.ReadValues is forced to unmarshal numbers into json.Number refs #1707 [dev-v3] Backport of https://github.com/helm/helm/pull/6010 to dev-v3 (the description below is a copy-paste from the original v2 branch PR). As https://github.com/helm/helm/pull/6016 is now merged to dev-v3, the change is reasonably trivial. This change is an attempt to address the common problem of json number unmarshalling where any number is converted into a float64 and represented in a scientific notation on a marshall call. This behavior breaks things like: chart versions and image tags if not converted to yaml strings explicitly. An example of this behavior: k8s failure to fetch an image tagged with a big number like: $IMAGE:20190612073634 after a few steps of yaml re-rendering turns into: $IMAGE:2.0190612073634e+13. Example issue: #1707 This commit forces yaml parser to use JSON modifiers and explicitly enables interface{} unmarshalling instead of float64. The change introduced might be breaking so should be processed with an extra care. Due to the fact helm mostly dals with human-produced data (charts), we have a decent level of confidence this change looses no functionality helm users rely upon (the scientific notation). Relevant doc: https://golang.org/pkg/encoding/json/#Decoder.UseNumber Signed-off-by: Oleg Sidorov Signed-off-by: Oleg Sidorov --- pkg/chartutil/testdata/coleridge.yaml | 1 + pkg/chartutil/values.go | 6 +++++- pkg/chartutil/values_test.go | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pkg/chartutil/testdata/coleridge.yaml b/pkg/chartutil/testdata/coleridge.yaml index b6579628b..15535988b 100644 --- a/pkg/chartutil/testdata/coleridge.yaml +++ b/pkg/chartutil/testdata/coleridge.yaml @@ -10,3 +10,4 @@ water: water: where: "everywhere" nor: "any drop to drink" + temperature: 1234567890 diff --git a/pkg/chartutil/values.go b/pkg/chartutil/values.go index f0c4f0236..f71d982ae 100644 --- a/pkg/chartutil/values.go +++ b/pkg/chartutil/values.go @@ -17,6 +17,7 @@ limitations under the License. package chartutil import ( + "encoding/json" "fmt" "io" "io/ioutil" @@ -105,7 +106,10 @@ func tableLookup(v Values, simple string) (Values, error) { // ReadValues will parse YAML byte data into a Values. func ReadValues(data []byte) (vals Values, err error) { - err = yaml.Unmarshal(data, &vals) + err = yaml.Unmarshal(data, &vals, func(d *json.Decoder) *json.Decoder { + d.UseNumber() + return d + }) if len(vals) == 0 { vals = Values{} } diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go index 0fadd897f..732f6e6f4 100644 --- a/pkg/chartutil/values_test.go +++ b/pkg/chartutil/values_test.go @@ -45,6 +45,7 @@ water: water: where: "everywhere" nor: "any drop to drink" + temperature: 1234567890 ` data, err := ReadValues([]byte(doc)) @@ -237,6 +238,12 @@ func matchValues(t *testing.T, data map[string]interface{}) { } else if o != "everywhere" { t.Errorf("Expected water water everywhere") } + + if o, err := ttpl("{{.water.water.temperature}}", data); err != nil { + t.Errorf(".water.water.temperature: %s", err) + } else if o != "1234567890" { + t.Errorf("Expected water water temperature: 1234567890, got: %s", o) + } } func ttpl(tpl string, v map[string]interface{}) (string, error) {