Skip to content

Commit 6353dde

Browse files
committed
Log Marshaler: check reflect.Value.canInterface() before casting it to time
1 parent edab19b commit 6353dde

File tree

1 file changed

+26
-19
lines changed

1 file changed

+26
-19
lines changed

log/marshallers.go

+26-19
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,23 @@ func (ms *Marshaller) Nest() *Marshaller {
4646
return ms
4747
}
4848

49+
func derefValue(v *reflect.Value) reflect.Kind {
50+
k := v.Kind()
51+
for k == reflect.Pointer || k == reflect.Interface {
52+
*v = v.Elem()
53+
k = v.Kind()
54+
}
55+
return k
56+
}
57+
4958
// NewMarshaller creates a new marshaller to serialize objects to log. If another marshaller
5059
// is provided in "other", its internal state will be copied to the newly created marshaller.
5160
func NewMarshaller(obj any, other ...*Marshaller) *Marshaller {
5261
v, ok := obj.(reflect.Value)
5362
if !ok {
5463
v = reflect.ValueOf(obj)
5564
}
56-
k := v.Kind()
57-
for k == reflect.Pointer || k == reflect.Interface {
58-
v = v.Elem()
59-
k = v.Kind()
60-
}
65+
derefValue(&v)
6166
if len(other) > 0 {
6267
return &Marshaller{
6368
value: v,
@@ -123,6 +128,16 @@ func (ms *Marshaller) marshalZerologMap(e *zerolog.Event) {
123128
}
124129
}
125130

131+
func tryCastToTime(v reflect.Value) *time.Time {
132+
if !v.CanInterface() {
133+
return nil
134+
}
135+
if t, ok := v.Interface().(time.Time); ok {
136+
return &t
137+
}
138+
return nil
139+
}
140+
126141
func (ms *Marshaller) MarshalZerologArray(a *zerolog.Array) {
127142
if k := ms.value.Kind(); k != reflect.Array && k != reflect.Slice {
128143
return
@@ -133,11 +148,7 @@ func (ms *Marshaller) MarshalZerologArray(a *zerolog.Array) {
133148
break
134149
}
135150
v := ms.value.Index(i)
136-
k := v.Kind()
137-
for k == reflect.Interface || k == reflect.Pointer {
138-
v = v.Elem()
139-
k = v.Kind()
140-
}
151+
k := derefValue(&v)
141152
if k == reflect.Invalid {
142153
continue
143154
}
@@ -185,8 +196,8 @@ func (ms *Marshaller) MarshalZerologArray(a *zerolog.Array) {
185196
case reflect.Float64:
186197
a.Float64(v.Float())
187198
case reflect.Struct, reflect.Map:
188-
if t, ok := v.Interface().(time.Time); ok {
189-
a.Time(t)
199+
if t := tryCastToTime(v); t != nil {
200+
a.Time(*t)
190201
} else if ms.nestedLevel+1 > ms.nestedLevelLimit {
191202
a.Str(v.String())
192203
} else {
@@ -218,11 +229,7 @@ func toSnakeCase(in string) string {
218229
}
219230

220231
func (ms *Marshaller) logField(e *zerolog.Event, fieldName string, field reflect.Value) {
221-
k := field.Kind()
222-
for k == reflect.Interface || k == reflect.Pointer {
223-
field = field.Elem()
224-
k = field.Kind()
225-
}
232+
k := derefValue(&field)
226233
if k == reflect.Invalid {
227234
return
228235
}
@@ -276,8 +283,8 @@ func (ms *Marshaller) logField(e *zerolog.Event, fieldName string, field reflect
276283
e.Array(fieldName, NewMarshaller(field, ms).Nest())
277284
}
278285
case reflect.Struct, reflect.Map:
279-
if t, ok := field.Interface().(time.Time); ok {
280-
e.Time(fieldName, t)
286+
if t := tryCastToTime(field); t != nil {
287+
e.Time(fieldName, *t)
281288
} else if ms.nestedLevel+1 > ms.nestedLevelLimit {
282289
e.Str(fieldName, field.String())
283290
} else {

0 commit comments

Comments
 (0)