// ErrShortBuffer means that a read required a longer buffer than was provided.
var ErrShortBuffer = errors.New("short buffer")
+// ErrBadWriteCount means that a write returned an impossible count.
+var ErrBadWriteCount = errors.New("Write returned impossible count")
+
// EOF is the error returned by Read when no more input is available.
// (Read must return EOF itself, not an error wrapping EOF,
// because callers will test for EOF using ==.)
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
- if nw > 0 {
- written += int64(nw)
+ if nw < 0 || nr < nw {
+ nw = 0
+ if ew == nil {
+ ew = ErrBadWriteCount
+ }
}
+ written += int64(nw)
if ew != nil {
err = ew
break
}
}
}
+
+// largeWriter returns an invalid count that is larger than the number
+// of bytes provided (issue 39978).
+type largeWriter struct {
+ err error
+}
+
+func (w largeWriter) Write(p []byte) (int, error) {
+ return len(p) + 1, w.err
+}
+
+func TestCopyLargeWriter(t *testing.T) {
+ want := ErrBadWriteCount
+ rb := new(Buffer)
+ wb := largeWriter{}
+ rb.WriteString("hello, world.")
+ if _, err := Copy(wb, rb); err != want {
+ t.Errorf("Copy error: got %v, want %v", err, want)
+ }
+
+ want = errors.New("largeWriterError")
+ rb = new(Buffer)
+ wb = largeWriter{err: want}
+ rb.WriteString("hello, world.")
+ if _, err := Copy(wb, rb); err != want {
+ t.Errorf("Copy error: got %v, want %v", err, want)
+ }
+}