From 802ef17cb43f162fae4c5dc9d4901c3ed47033a0 Mon Sep 17 00:00:00 2001
From: Philipp Heckel <pheckel@datto.com>
Date: Tue, 7 Dec 2021 16:03:01 -0500
Subject: [PATCH] Fix data races

---
 server/server.go | 3 +++
 util/util.go     | 6 +++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/server/server.go b/server/server.go
index bfc767c..654725f 100644
--- a/server/server.go
+++ b/server/server.go
@@ -386,8 +386,11 @@ func (s *Server) handleSubscribe(w http.ResponseWriter, r *http.Request, v *visi
 	if err != nil {
 		return err
 	}
+	var wlock sync.Mutex
 	poll := r.URL.Query().Has("poll")
 	sub := func(msg *message) error {
+		wlock.Lock()
+		defer wlock.Unlock()
 		m, err := encoder(msg)
 		if err != nil {
 			return err
diff --git a/util/util.go b/util/util.go
index fcb9c29..742ca31 100644
--- a/util/util.go
+++ b/util/util.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"math/rand"
 	"os"
+	"sync"
 	"time"
 )
 
@@ -12,7 +13,8 @@ const (
 )
 
 var (
-	random = rand.New(rand.NewSource(time.Now().UnixNano()))
+	random      = rand.New(rand.NewSource(time.Now().UnixNano()))
+	randomMutex = sync.Mutex{}
 )
 
 // FileExists checks if a file exists, and returns true if it does
@@ -23,6 +25,8 @@ func FileExists(filename string) bool {
 
 // RandomString returns a random string with a given length
 func RandomString(length int) string {
+	randomMutex.Lock() // Who would have thought that random.Intn() is not thread-safe?!
+	defer randomMutex.Unlock()
 	b := make([]byte, length)
 	for i := range b {
 		b[i] = randomStringCharset[random.Intn(len(randomStringCharset))]
-- 
GitLab