aboutsummaryrefslogtreecommitdiff
path: root/src/debug/elf
diff options
context:
space:
mode:
authorMark F <fenderovlol@gmail.com>2026-01-15 13:19:10 +0100
committerGopher Robot <gobot@golang.org>2026-01-22 13:04:53 -0800
commit858d4bf8511a7741cf5c21f1d51b23ed180fd450 (patch)
treebe1826d48d3d115447c6e8c9c2da3853ea7c06e8 /src/debug/elf
parent8e3104dc269b959083f7e7133841e3366a477ef1 (diff)
downloadgo-858d4bf8511a7741cf5c21f1d51b23ed180fd450.tar.xz
debug/elf: return FormatError when reading short files
NewFile returns the raw error from ReadAt when failing to read the ELF identifier, typically io.EOF for empty or short files. This breaks the API contract that all parsing failures should return *FormatError. Wrap the error in FormatError for consistency with other error paths. Fixes #76338 Change-Id: Ic4ed77316fcc459ce8cbe9e9506d7cf8e9286623 Reviewed-on: https://go-review.googlesource.com/c/go/+/736600 Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Auto-Submit: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/debug/elf')
-rw-r--r--src/debug/elf/file.go2
-rw-r--r--src/debug/elf/file_test.go44
2 files changed, 45 insertions, 1 deletions
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index 80df13ef8b..cc40b22f39 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -290,7 +290,7 @@ func NewFile(r io.ReaderAt) (*File, error) {
// Read and decode ELF identifier
var ident [16]uint8
if _, err := r.ReadAt(ident[0:], 0); err != nil {
- return nil, err
+ return nil, &FormatError{0, "cannot read ELF identifier", err}
}
if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
return nil, &FormatError{0, "bad magic number", ident[0:4]}
diff --git a/src/debug/elf/file_test.go b/src/debug/elf/file_test.go
index b796cdb95b..aef9967c78 100644
--- a/src/debug/elf/file_test.go
+++ b/src/debug/elf/file_test.go
@@ -17,6 +17,7 @@ import (
"net"
"os"
"path"
+ "path/filepath"
"reflect"
"runtime"
"slices"
@@ -1622,3 +1623,46 @@ func BenchmarkSymbols32(b *testing.B) {
}
}
}
+
+func TestOpenEmptyFile(t *testing.T) {
+ name := filepath.Join(t.TempDir(), "empty")
+ if err := os.WriteFile(name, nil, 0o644); err != nil {
+ t.Fatal(err)
+ }
+
+ _, err := Open(name)
+ if err == nil {
+ t.Fatal("Open on empty file: got nil error, want non-nil")
+ }
+
+ var formatErr *FormatError
+ if !errors.As(err, &formatErr) {
+ t.Errorf("Open on empty file: got %T (%v), want *FormatError", err, err)
+ }
+}
+
+func TestNewFileShortReader(t *testing.T) {
+ tests := []struct {
+ name string
+ data []byte
+ }{
+ {"empty", []byte{}},
+ {"one byte", []byte{0x7f}},
+ {"four bytes", []byte{0x7f, 'E', 'L', 'F'}},
+ {"fifteen bytes", make([]byte, 15)},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ _, err := NewFile(bytes.NewReader(tt.data))
+ if err == nil {
+ t.Fatal("NewFile with short data: got nil error, want non-nil")
+ }
+
+ var formatErr *FormatError
+ if !errors.As(err, &formatErr) {
+ t.Errorf("NewFile with short data: got %T (%v), want *FormatError", err, err)
+ }
+ })
+ }
+}