aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2020-07-07 22:18:17 -0700
committerJoe Tsai <joetsai@google.com>2020-07-08 18:29:38 +0000
commit0844ff8eef81e124c1fecba82dd5843745427fa4 (patch)
treea2a5a02e3265a4b846d61e7c80f711d6a0ca9682
parent4b09c8ad6fb9d30b9c3417b5364809ff0006749d (diff)
downloadgo-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.go5
-rw-r--r--src/os/readfrom_linux_test.go30
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) {