From 3f60749013faf637eb2591de9644ba26ce95a240 Mon Sep 17 00:00:00 2001 From: Eric Halpern Date: Wed, 23 Nov 2016 15:39:14 -0800 Subject: [PATCH] Fix race conditions in encoder to address photo-dedup segfault (#2852) toward: #2849 --- go/marshal/encode.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/go/marshal/encode.go b/go/marshal/encode.go index 98660fcb6d..d7ad06937f 100644 --- a/go/marshal/encode.go +++ b/go/marshal/encode.go @@ -153,9 +153,9 @@ func float64Encoder(v reflect.Value) types.Value { } func intEncoder(v reflect.Value) types.Value { - return types.Number(float64(v.Int())) } + func uintEncoder(v reflect.Value) types.Value { return types.Number(float64(v.Uint())) } @@ -443,7 +443,13 @@ func listEncoder(t reflect.Type, parentStructTypes []reflect.Type) encoderFunc { } var elemEncoder encoderFunc + // lock e until encoder(s) are initialized + var init sync.RWMutex + init.Lock() + defer init.Unlock() e = func(v reflect.Value) types.Value { + init.RLock() + defer init.RUnlock() values := make([]types.Value, v.Len(), v.Len()) for i := 0; i < v.Len(); i++ { values[i] = elemEncoder(v.Index(i)) @@ -463,7 +469,13 @@ func setEncoder(t reflect.Type, parentStructTypes []reflect.Type) encoderFunc { } var encoder encoderFunc + // lock e until encoder(s) are initialized + var init sync.RWMutex + init.Lock() + defer init.Unlock() e = func(v reflect.Value) types.Value { + init.RLock() + defer init.RUnlock() values := make([]types.Value, v.Len(), v.Len()) for i, k := range v.MapKeys() { values[i] = encoder(k) @@ -484,7 +496,13 @@ func mapEncoder(t reflect.Type, parentStructTypes []reflect.Type) encoderFunc { var keyEncoder encoderFunc var valueEncoder encoderFunc + // lock e until encoder(s) are initialized + var init sync.RWMutex + init.Lock() + defer init.Unlock() e = func(v reflect.Value) types.Value { + init.RLock() + defer init.RUnlock() keys := v.MapKeys() kvs := make([]types.Value, 2*len(keys)) for i, k := range keys {