]> Cypherpunks repositories - gostls13.git/commitdiff
os: fix regression with handling of nil *File
authorJoe Tsai <joetsai@digital-static.net>
Wed, 8 Jul 2020 05:18:17 +0000 (22:18 -0700)
committerJoe Tsai <joetsai@google.com>
Wed, 8 Jul 2020 18:29:38 +0000 (18:29 +0000)
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>

src/os/readfrom_linux.go
src/os/readfrom_linux_test.go

index ed275e1ba6878a0ac5324ac749f9c8b7306def74..63ea45cf6516435265b2b71d81cca5a29ac5f971 100644 (file)
@@ -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 {
index b6f5cb703427a970e162dc1ac244e9510fb633ad..00faf39fe5a817a14b2d9a66fdab67e2be9dc2d6 100644 (file)
@@ -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) {