diff options
| author | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2023-05-28 10:04:42 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-28 10:04:42 -0700 |
| commit | 469a638785e8562152dff4ba2e05e36b841c4d98 (patch) | |
| tree | 7be7cc1720115cdf7deceeeb7da133b94742b27f /hotline/file_path.go | |
| parent | 4a340162c3654e8300f6ebfb71336c2df205beb5 (diff) | |
Fix scanner buffer re-use for fileItemScanner (#104)
Diffstat (limited to 'hotline/file_path.go')
| -rw-r--r-- | hotline/file_path.go | 12 |
1 files changed, 11 insertions, 1 deletions
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) |