X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/4a340162c3654e8300f6ebfb71336c2df205beb5..469a638785e8562152dff4ba2e05e36b841c4d98:/hotline/file_path.go?ds=sidebyside diff --git a/hotline/file_path.go b/hotline/file_path.go index 46ef97c..97ce417 100644 --- a/hotline/file_path.go +++ b/hotline/file_path.go @@ -34,6 +34,9 @@ func fileItemScanner(data []byte, _ bool) (advance int, token []byte, err error) // Write implements the io.Writer interface for FilePathItem func (fpi *FilePathItem) Write(b []byte) (n int, err error) { + if len(b) < 3 { + return n, errors.New("buflen too small") + } fpi.Len = b[2] fpi.Name = b[fileItemMinLen : fpi.Len+fileItemMinLen] @@ -45,6 +48,7 @@ type FilePath struct { Items []FilePathItem } +// Write implements io.Writer interface for FilePath func (fp *FilePath) Write(b []byte) (n int, err error) { reader := bytes.NewReader(b) err = binary.Read(reader, binary.BigEndian, &fp.ItemCount) @@ -61,7 +65,13 @@ func (fp *FilePath) Write(b []byte) (n int, err error) { for i := 0; i < int(binary.BigEndian.Uint16(fp.ItemCount[:])); i++ { var fpi FilePathItem scanner.Scan() - if _, err := fpi.Write(scanner.Bytes()); err != nil { + + // Make a new []byte slice and copy the scanner bytes to it. This is critical to avoid a data race as the + // scanner re-uses the buffer for subsequent scans. + buf := make([]byte, len(scanner.Bytes())) + copy(buf, scanner.Bytes()) + + if _, err := fpi.Write(buf); err != nil { return n, err } fp.Items = append(fp.Items, fpi)