Fix nil pointer dereference when call Fields with a typed nil value (#112)

This commit is contained in:
anthony 2018-10-31 18:40:46 +01:00 committed by Olivier Poitrey
parent 8e36cbf881
commit baa31cfa85
2 changed files with 126 additions and 16 deletions

View File

@ -99,37 +99,101 @@ func appendFields(dst []byte, fields map[string]interface{}) []byte {
case time.Duration: case time.Duration:
dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger) dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger)
case *string: case *string:
dst = enc.AppendString(dst, *val) if val != nil {
dst = enc.AppendString(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *bool: case *bool:
dst = enc.AppendBool(dst, *val) if val != nil {
dst = enc.AppendBool(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *int: case *int:
dst = enc.AppendInt(dst, *val) if val != nil {
dst = enc.AppendInt(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *int8: case *int8:
dst = enc.AppendInt8(dst, *val) if val != nil {
dst = enc.AppendInt8(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *int16: case *int16:
dst = enc.AppendInt16(dst, *val) if val != nil {
dst = enc.AppendInt16(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *int32: case *int32:
dst = enc.AppendInt32(dst, *val) if val != nil {
dst = enc.AppendInt32(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *int64: case *int64:
dst = enc.AppendInt64(dst, *val) if val != nil {
dst = enc.AppendInt64(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *uint: case *uint:
dst = enc.AppendUint(dst, *val) if val != nil {
dst = enc.AppendUint(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *uint8: case *uint8:
dst = enc.AppendUint8(dst, *val) if val != nil {
dst = enc.AppendUint8(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *uint16: case *uint16:
dst = enc.AppendUint16(dst, *val) if val != nil {
dst = enc.AppendUint16(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *uint32: case *uint32:
dst = enc.AppendUint32(dst, *val) if val != nil {
dst = enc.AppendUint32(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *uint64: case *uint64:
dst = enc.AppendUint64(dst, *val) if val != nil {
dst = enc.AppendUint64(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *float32: case *float32:
dst = enc.AppendFloat32(dst, *val) if val != nil {
dst = enc.AppendFloat32(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *float64: case *float64:
dst = enc.AppendFloat64(dst, *val) if val != nil {
dst = enc.AppendFloat64(dst, *val)
} else {
dst = enc.AppendNil(dst)
}
case *time.Time: case *time.Time:
dst = enc.AppendTime(dst, *val, TimeFieldFormat) if val != nil {
dst = enc.AppendTime(dst, *val, TimeFieldFormat)
} else {
dst = enc.AppendNil(dst)
}
case *time.Duration: case *time.Duration:
dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger) if val != nil {
dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger)
} else {
dst = enc.AppendNil(dst)
}
case []string: case []string:
dst = enc.AppendStrings(dst, val) dst = enc.AppendStrings(dst, val)
case []bool: case []bool:

View File

@ -164,6 +164,52 @@ func TestFieldsMapPnt(t *testing.T) {
} }
} }
func TestFieldsMapNilPnt(t *testing.T) {
var (
stringPnt *string
boolPnt *bool
intPnt *int
int8Pnt *int8
int16Pnt *int16
int32Pnt *int32
int64Pnt *int64
uintPnt *uint
uint8Pnt *uint8
uint16Pnt *uint16
uint32Pnt *uint32
uint64Pnt *uint64
float32Pnt *float32
float64Pnt *float64
durPnt *time.Duration
timePnt *time.Time
)
out := &bytes.Buffer{}
log := New(out)
fields := map[string]interface{}{
"string": stringPnt,
"bool": boolPnt,
"int": intPnt,
"int8": int8Pnt,
"int16": int16Pnt,
"int32": int32Pnt,
"int64": int64Pnt,
"uint": uintPnt,
"uint8": uint8Pnt,
"uint16": uint16Pnt,
"uint32": uint32Pnt,
"uint64": uint64Pnt,
"float32": float32Pnt,
"float64": float64Pnt,
"dur": durPnt,
"time": timePnt,
}
log.Log().Fields(fields).Msg("")
if got, want := decodeIfBinaryToString(out.Bytes()), `{"bool":null,"dur":null,"float32":null,"float64":null,"int":null,"int16":null,"int32":null,"int64":null,"int8":null,"string":null,"time":null,"uint":null,"uint16":null,"uint32":null,"uint64":null,"uint8":null}`+"\n"; got != want {
t.Errorf("invalid log output:\ngot: %v\nwant: %v", got, want)
}
}
func TestFields(t *testing.T) { func TestFields(t *testing.T) {
out := &bytes.Buffer{} out := &bytes.Buffer{}
log := New(out) log := New(out)