From 4c78c975fe7c825c6d1466c42be594d1d6f3aba6 Mon Sep 17 00:00:00 2001 From: Alex Harford Date: Wed, 25 Jan 2017 06:37:19 -0800 Subject: [PATCH] Tighten restrictions on float decoding (#171) ParseFloat() accepts strings that contain digits with a single 'e' character somewhere in the middle as valid floats. The YAML spec does not accept these. This causes problems especially when dealing with short commit hashes, e.g. `123456e1` --- decode_test.go | 9 +++++++++ resolve.go | 11 ++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/decode_test.go b/decode_test.go index 5c56a00e..a6fea0f2 100644 --- a/decode_test.go +++ b/decode_test.go @@ -581,6 +581,15 @@ var unmarshalTests = []struct { "\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n", M{"ñoño": "very yes 🟔"}, }, + + // YAML Float regex shouldn't match this + { + "a: 123456e1\n", + M{"a": "123456e1"}, + }, { + "a: 123456E1\n", + M{"a": "123456E1"}, + }, } type M map[interface{}]interface{} diff --git a/resolve.go b/resolve.go index 93a86327..232313cc 100644 --- a/resolve.go +++ b/resolve.go @@ -3,6 +3,7 @@ package yaml import ( "encoding/base64" "math" + "regexp" "strconv" "strings" "unicode/utf8" @@ -80,6 +81,8 @@ func resolvableTag(tag string) bool { return false } +var yamlStyleFloat = regexp.MustCompile(`^[-+]?[0-9]*\.?[0-9]+([eE][-+][0-9]+)?$`) + func resolve(tag string, in string) (rtag string, out interface{}) { if !resolvableTag(tag) { return tag, in @@ -135,9 +138,11 @@ func resolve(tag string, in string) (rtag string, out interface{}) { if err == nil { return yaml_INT_TAG, uintv } - floatv, err := strconv.ParseFloat(plain, 64) - if err == nil { - return yaml_FLOAT_TAG, floatv + if yamlStyleFloat.MatchString(plain) { + floatv, err := strconv.ParseFloat(plain, 64) + if err == nil { + return yaml_FLOAT_TAG, floatv + } } if strings.HasPrefix(plain, "0b") { intv, err := strconv.ParseInt(plain[2:], 2, 64)