]> Cypherpunks repositories - gostls13.git/commitdiff
debug/elf: return FormatError when reading short files
authorMark F <fenderovlol@gmail.com>
Thu, 15 Jan 2026 12:19:10 +0000 (13:19 +0100)
committerGopher Robot <gobot@golang.org>
Thu, 22 Jan 2026 21:04:53 +0000 (13:04 -0800)
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>

src/debug/elf/file.go
src/debug/elf/file_test.go

index 80df13ef8babe6051702808e46df14a240e13ea5..cc40b22f393bb7de0b1b8f2b5a0e1736324041de 100644 (file)
@@ -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]}
index b796cdb95b65c6182b14c80b0c6589b33cbf340e..aef9967c78cde5de01200802667040814be55c0a 100644 (file)
@@ -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)
+                       }
+               })
+       }
+}