mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
bufio: don't do empty Write at start of WriteTo
The empty Write will cause the wrong thing to happen when using io.Copy to copy to a package-based stream. Fixes #71424 Change-Id: I046a27539447182692ac76a8bdd422327345dd8d Reviewed-on: https://go-review.googlesource.com/c/go/+/644535 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com> Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
7c6b047ea1
commit
290ec2d92b
@ -519,10 +519,12 @@ func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
|
|||||||
b.lastByte = -1
|
b.lastByte = -1
|
||||||
b.lastRuneSize = -1
|
b.lastRuneSize = -1
|
||||||
|
|
||||||
|
if b.r < b.w {
|
||||||
n, err = b.writeBuf(w)
|
n, err = b.writeBuf(w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if r, ok := b.rd.(io.WriterTo); ok {
|
if r, ok := b.rd.(io.WriterTo); ok {
|
||||||
m, err := r.WriteTo(w)
|
m, err := r.WriteTo(w)
|
||||||
|
@ -1149,7 +1149,7 @@ func (w errorWriterToTest) Write(p []byte) (int, error) {
|
|||||||
var errorWriterToTests = []errorWriterToTest{
|
var errorWriterToTests = []errorWriterToTest{
|
||||||
{1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe},
|
{1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe},
|
||||||
{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
|
{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
|
||||||
{0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrClosedPipe},
|
{0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrUnexpectedEOF},
|
||||||
{0, 1, io.EOF, nil, nil},
|
{0, 1, io.EOF, nil, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
96
src/bufio/net_test.go
Normal file
96
src/bufio/net_test.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build unix
|
||||||
|
|
||||||
|
package bufio_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestCopyUnixpacket tests that we can use bufio when copying
|
||||||
|
// across a unixpacket socket. This used to fail due to an unnecessary
|
||||||
|
// empty Write call that was interpreted as an EOF.
|
||||||
|
func TestCopyUnixpacket(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
socket := filepath.Join(tmpDir, "unixsock")
|
||||||
|
|
||||||
|
// Start a unixpacket server.
|
||||||
|
addr := &net.UnixAddr{
|
||||||
|
Name: socket,
|
||||||
|
Net: "unixpacket",
|
||||||
|
}
|
||||||
|
server, err := net.ListenUnix("unixpacket", addr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a goroutine for the server to accept one connection
|
||||||
|
// and read all the data sent on the connection,
|
||||||
|
// reporting the number of bytes read on ch.
|
||||||
|
ch := make(chan int, 1)
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
tot := 0
|
||||||
|
defer func() {
|
||||||
|
ch <- tot
|
||||||
|
}()
|
||||||
|
|
||||||
|
serverConn, err := server.Accept()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
for {
|
||||||
|
n, err := serverConn.Read(buf)
|
||||||
|
tot += n
|
||||||
|
if err == io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
clientConn, err := net.DialUnix("unixpacket", nil, addr)
|
||||||
|
if err != nil {
|
||||||
|
// Leaves the server goroutine hanging. Oh well.
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer wg.Wait()
|
||||||
|
defer clientConn.Close()
|
||||||
|
|
||||||
|
const data = "data"
|
||||||
|
r := bufio.NewReader(strings.NewReader(data))
|
||||||
|
n, err := io.Copy(clientConn, r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n != int64(len(data)) {
|
||||||
|
t.Errorf("io.Copy returned %d, want %d", n, len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
clientConn.Close()
|
||||||
|
tot := <-ch
|
||||||
|
|
||||||
|
if tot != len(data) {
|
||||||
|
t.Errorf("server read %d, want %d", tot, len(data))
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user