// Read in the full header first.
header, err := readData(x, addr, buildInfoHeaderSize)
- if err != nil {
+ if err == io.EOF {
+ return "", "", errNotGoExe
+ } else if err != nil {
return "", "", err
}
+ if len(header) < buildInfoHeaderSize {
+ return "", "", errNotGoExe
+ }
const (
ptrSizeOffset = 14
// addr. So we don't need to check that size doesn't overflow the
// section.
b, err := readData(x, addr, binary.MaxVarintLen64)
- if err != nil {
+ if err == io.EOF {
+ return "", 0, errNotGoExe
+ } else if err != nil {
return "", 0, err
}
addr += uint64(n)
b, err = readData(x, addr, length)
- if err != nil {
- if err == io.ErrUnexpectedEOF {
- // Length too large to allocate. Clearly bogus value.
- return "", 0, errNotGoExe
- }
+ if err == io.EOF {
+ return "", 0, errNotGoExe
+ } else if err == io.ErrUnexpectedEOF {
+ // Length too large to allocate. Clearly bogus value.
+ return "", 0, errNotGoExe
+ } else if err != nil {
return "", 0, err
}
if uint64(len(b)) < length {
}
n, err := readDataInto(x, start, buf)
- if err != nil {
+ if err == io.EOF {
+ // EOF before finding the magic; must not be a Go executable.
+ return 0, errNotGoExe
+ } else if err != nil {
return 0, err
}
}
b, err := saferio.ReadDataAt(r, size, 0)
- if err == io.EOF {
+ if len(b) > 0 && err == io.EOF {
err = nil
}
return b, err
}
n, err := r.ReadAt(b, 0)
- if err == io.EOF {
+ if n > 0 && err == io.EOF {
err = nil
}
return n, err
})
}
}
+
+func FuzzRead(f *testing.F) {
+ go117, err := os.ReadFile("testdata/go117")
+ if err != nil {
+ f.Errorf("Error reading go117: %v", err)
+ }
+ f.Add(go117)
+
+ notgo, err := os.ReadFile("testdata/notgo")
+ if err != nil {
+ f.Errorf("Error reading notgo: %v", err)
+ }
+ f.Add(notgo)
+
+ f.Fuzz(func(t *testing.T, in []byte) {
+ buildinfo.Read(bytes.NewReader(in))
+ })
+}