Fix for a bug in cbor decodeFloat (#51)

This commit is contained in:
Ravi Raju 2018-04-13 00:13:41 -07:00 committed by Olivier Poitrey
parent 2ccfab3e07
commit 70bea47cc0
3 changed files with 25 additions and 21 deletions

View File

@ -19,15 +19,15 @@ func TestArray(t *testing.T) {
Uint16(8). Uint16(8).
Uint32(9). Uint32(9).
Uint64(10). Uint64(10).
Float32(11). Float32(11.98122).
Float64(12). Float64(12.987654321).
Str("a"). Str("a").
Bytes([]byte("b")). Bytes([]byte("b")).
Hex([]byte{0x1f}). Hex([]byte{0x1f}).
Time(time.Time{}). Time(time.Time{}).
IPAddr(net.IP{192, 168, 0, 10}). IPAddr(net.IP{192, 168, 0, 10}).
Dur(0) Dur(0)
want := `[true,1,2,3,4,5,6,7,8,9,10,11,12,"a","b","1f","0001-01-01T00:00:00Z","192.168.0.10",0]` want := `[true,1,2,3,4,5,6,7,8,9,10,11.98122,12.987654321,"a","b","1f","0001-01-01T00:00:00Z","192.168.0.10",0]`
if got := decodeObjectToStr(a.write([]byte{})); got != want { if got := decodeObjectToStr(a.write([]byte{})); got != want {
t.Errorf("Array.write()\ngot: %s\nwant: %s", got, want) t.Errorf("Array.write()\ngot: %s\nwant: %s", got, want)
} }

View File

@ -20,6 +20,9 @@ var decodeTimeZone *time.Location
const hexTable = "0123456789abcdef" const hexTable = "0123456789abcdef"
const isFloat32 = 4
const isFloat64 = 8
func readNBytes(src *bufio.Reader, n int) []byte { func readNBytes(src *bufio.Reader, n int) []byte {
ret := make([]byte, n) ret := make([]byte, n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
@ -97,11 +100,11 @@ func decodeFloat(src *bufio.Reader) (float64, int) {
pb := readNBytes(src, 4) pb := readNBytes(src, 4)
switch string(pb) { switch string(pb) {
case float32Nan: case float32Nan:
return math.NaN(), 4 return math.NaN(), isFloat32
case float32PosInfinity: case float32PosInfinity:
return math.Inf(0), 4 return math.Inf(0), isFloat32
case float32NegInfinity: case float32NegInfinity:
return math.Inf(-1), 4 return math.Inf(-1), isFloat32
} }
n := uint32(0) n := uint32(0)
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
@ -109,16 +112,16 @@ func decodeFloat(src *bufio.Reader) (float64, int) {
n += uint32(pb[i]) n += uint32(pb[i])
} }
val := math.Float32frombits(n) val := math.Float32frombits(n)
return float64(val), 4 return float64(val), isFloat32
case additionalTypeFloat64: case additionalTypeFloat64:
pb := readNBytes(src, 8) pb := readNBytes(src, 8)
switch string(pb) { switch string(pb) {
case float64Nan: case float64Nan:
return math.NaN(), 8 return math.NaN(), isFloat64
case float64PosInfinity: case float64PosInfinity:
return math.Inf(0), 8 return math.Inf(0), isFloat64
case float64NegInfinity: case float64NegInfinity:
return math.Inf(-1), 8 return math.Inf(-1), isFloat64
} }
n := uint64(0) n := uint64(0)
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
@ -126,14 +129,13 @@ func decodeFloat(src *bufio.Reader) (float64, int) {
n += uint64(pb[i]) n += uint64(pb[i])
} }
val := math.Float64frombits(n) val := math.Float64frombits(n)
return val, 8 return val, isFloat64
} }
panic(fmt.Errorf("Invalid Additional Type: %d in decodeFloat", minor)) panic(fmt.Errorf("Invalid Additional Type: %d in decodeFloat", minor))
} }
func decodeStringComplex(dst []byte, s string, pos uint) []byte { func decodeStringComplex(dst []byte, s string, pos uint) []byte {
i := int(pos) i := int(pos)
const hex = "0123456789abcdef"
start := 0 start := 0
for i < len(s) { for i < len(s) {
@ -180,7 +182,7 @@ func decodeStringComplex(dst []byte, s string, pos uint) []byte {
case '\t': case '\t':
dst = append(dst, '\\', 't') dst = append(dst, '\\', 't')
default: default:
dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF]) dst = append(dst, '\\', 'u', '0', '0', hexTable[b>>4], hexTable[b&0xF])
} }
i++ i++
start = i start = i
@ -481,10 +483,12 @@ func decodeSimpleFloat(src *bufio.Reader) []byte {
case math.IsInf(v, -1): case math.IsInf(v, -1):
return []byte("\"-Inf\"") return []byte("\"-Inf\"")
} }
if bc == 5 { if bc == isFloat32 {
ba = strconv.AppendFloat(ba, v, 'f', -1, 32) ba = strconv.AppendFloat(ba, v, 'f', -1, 32)
} else { } else if bc == isFloat64 {
ba = strconv.AppendFloat(ba, v, 'f', -1, 64) ba = strconv.AppendFloat(ba, v, 'f', -1, 64)
} else {
panic(fmt.Errorf("Invalid Float precision from decodeFloat: %d", bc))
} }
return ba return ba
default: default:

View File

@ -95,14 +95,14 @@ func TestWith(t *testing.T) {
Uint16("uint16", 8). Uint16("uint16", 8).
Uint32("uint32", 9). Uint32("uint32", 9).
Uint64("uint64", 10). Uint64("uint64", 10).
Float32("float32", 11). Float32("float32", 11.101).
Float64("float64", 12). Float64("float64", 12.30303).
Time("time", time.Time{}) Time("time", time.Time{})
_, file, line, _ := runtime.Caller(0) _, file, line, _ := runtime.Caller(0)
caller := fmt.Sprintf("%s:%d", file, line+3) caller := fmt.Sprintf("%s:%d", file, line+3)
log := ctx.Caller().Logger() log := ctx.Caller().Logger()
log.Log().Msg("") log.Log().Msg("")
if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11,"float64":12,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want { if got, want := decodeIfBinaryToString(out.Bytes()), `{"string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"float32":11.101,"float64":12.30303,"time":"0001-01-01T00:00:00Z","caller":"`+caller+`"}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
} }
} }
@ -192,13 +192,13 @@ func TestFields(t *testing.T) {
IPAddr("IPv6", net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34}). IPAddr("IPv6", net.IP{0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34}).
MACAddr("Mac", net.HardwareAddr{0x00, 0x14, 0x22, 0x01, 0x23, 0x45}). MACAddr("Mac", net.HardwareAddr{0x00, 0x14, 0x22, 0x01, 0x23, 0x45}).
IPPrefix("Prefix", net.IPNet{IP: net.IP{192, 168, 0, 100}, Mask: net.CIDRMask(24, 32)}). IPPrefix("Prefix", net.IPNet{IP: net.IP{192, 168, 0, 100}, Mask: net.CIDRMask(24, 32)}).
Float32("float32", 11). Float32("float32", 11.1234).
Float64("float64", 12). Float64("float64", 12.321321321).
Dur("dur", 1*time.Second). Dur("dur", 1*time.Second).
Time("time", time.Time{}). Time("time", time.Time{}).
TimeDiff("diff", now, now.Add(-10*time.Second)). TimeDiff("diff", now, now.Add(-10*time.Second)).
Msg("") Msg("")
if got, want := decodeIfBinaryToString(out.Bytes()), `{"caller":"`+caller+`","string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"IPv4":"192.168.0.100","IPv6":"2001:db8:85a3::8a2e:370:7334","Mac":"00:14:22:01:23:45","Prefix":"192.168.0.100/24","float32":11,"float64":12,"dur":1000,"time":"0001-01-01T00:00:00Z","diff":10000}`+"\n"; got != want { if got, want := decodeIfBinaryToString(out.Bytes()), `{"caller":"`+caller+`","string":"foo","bytes":"bar","hex":"12ef","json":{"some":"json"},"error":"some error","bool":true,"int":1,"int8":2,"int16":3,"int32":4,"int64":5,"uint":6,"uint8":7,"uint16":8,"uint32":9,"uint64":10,"IPv4":"192.168.0.100","IPv6":"2001:db8:85a3::8a2e:370:7334","Mac":"00:14:22:01:23:45","Prefix":"192.168.0.100/24","float32":11.1234,"float64":12.321321321,"dur":1000,"time":"0001-01-01T00:00:00Z","diff":10000}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want) t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
} }
} }