"bytes"
"encoding/binary"
"errors"
+ "fmt"
"io"
"path/filepath"
"strings"
// 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]
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)
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)
subPath,
filepath.Join("/", string(fileName)),
)
-
+ fullPath, err = txtDecoder.String(fullPath)
+ if err != nil {
+ return "", fmt.Errorf("invalid filepath encoding: %w", err)
+ }
return fullPath, nil
}