diff options
author | Joe Tsai <joetsai@digital-static.net> | 2020-07-07 22:18:17 -0700 |
---|---|---|
committer | Joe Tsai <joetsai@google.com> | 2020-07-08 18:29:38 +0000 |
commit | 0844ff8eef81e124c1fecba82dd5843745427fa4 (patch) | |
tree | a2a5a02e3265a4b846d61e7c80f711d6a0ca9682 | |
parent | 4b09c8ad6fb9d30b9c3417b5364809ff0006749d (diff) | |
download | go-0844ff8eef81e124c1fecba82dd5843745427fa4.tar.gz go-0844ff8eef81e124c1fecba82dd5843745427fa4.zip |
os: fix regression with handling of nil *File
Use of a nil *File as an argument should not result in a panic,
but result in the ErrInvalid error being returned.
Fix the copy_file_range implementation to preserve this semantic.
Fixes #40115
Change-Id: Iad5ac39664a3efb7964cf55685be636940a8db13
Reviewed-on: https://go-review.googlesource.com/c/go/+/241417
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r-- | src/os/readfrom_linux.go | 5 | ||||
-rw-r--r-- | src/os/readfrom_linux_test.go | 30 |
2 files changed, 35 insertions, 0 deletions
diff --git a/src/os/readfrom_linux.go b/src/os/readfrom_linux.go index ed275e1ba6..63ea45cf65 100644 --- a/src/os/readfrom_linux.go +++ b/src/os/readfrom_linux.go @@ -32,6 +32,11 @@ func (f *File) readFrom(r io.Reader) (written int64, handled bool, err error) { if !ok { return 0, false, nil } + if src.checkValid("ReadFrom") != nil { + // Avoid returning the error as we report handled as false, + // leave further error handling as the responsibility of the caller. + return 0, false, nil + } written, handled, err = pollCopyFileRange(&f.pfd, &src.pfd, remain) if lr != nil { diff --git a/src/os/readfrom_linux_test.go b/src/os/readfrom_linux_test.go index b6f5cb7034..00faf39fe5 100644 --- a/src/os/readfrom_linux_test.go +++ b/src/os/readfrom_linux_test.go @@ -8,6 +8,7 @@ import ( "bytes" "internal/poll" "io" + "io/ioutil" "math/rand" . "os" "path/filepath" @@ -170,6 +171,35 @@ func TestCopyFileRange(t *testing.T) { mustContainData(t, dst, data) }) }) + t.Run("Nil", func(t *testing.T) { + var nilFile *File + anyFile, err := ioutil.TempFile("", "") + if err != nil { + t.Fatal(err) + } + defer Remove(anyFile.Name()) + defer anyFile.Close() + + if _, err := io.Copy(nilFile, nilFile); err != ErrInvalid { + t.Errorf("io.Copy(nilFile, nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := io.Copy(anyFile, nilFile); err != ErrInvalid { + t.Errorf("io.Copy(anyFile, nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := io.Copy(nilFile, anyFile); err != ErrInvalid { + t.Errorf("io.Copy(nilFile, anyFile) = %v, want %v", err, ErrInvalid) + } + + if _, err := nilFile.ReadFrom(nilFile); err != ErrInvalid { + t.Errorf("nilFile.ReadFrom(nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := anyFile.ReadFrom(nilFile); err != ErrInvalid { + t.Errorf("anyFile.ReadFrom(nilFile) = %v, want %v", err, ErrInvalid) + } + if _, err := nilFile.ReadFrom(anyFile); err != ErrInvalid { + t.Errorf("nilFile.ReadFrom(anyFile) = %v, want %v", err, ErrInvalid) + } + }) } func testCopyFileRange(t *testing.T, size int64, limit int64) { |