Skip to content

bufio: altered value when reading from tcpstream  #14055

@bench

Description

@bench
  • goversion "1.5"
  • arch "debian8-linux-amd64"
  • What did I do? "Read line from TCP stream"

I received altered data when reading from tcpstream.
Pointer receivedAAA is partially overwritten by pointer receivedBBB. (side effect of readSlice()?)
Only appears on unit testing.
Works fine with go1.4.2, go 1.4.3.

Here is a way to reproduce the issue:

package hello

import (
    "bufio"
    "fmt"
    "net"
    "os"
    "testing"
)

const (
    str1 = "AAAAAAAAAAAA"
    str2 = "BBBB"
)

func TestGetCommand(t *testing.T) {

    // Run TCP Server
    address, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("0.0.0.0:%d", 30299))
    if err != nil {
        panic(fmt.Sprintf("Error starting message server: %s", err))
    }
    l, err := net.ListenTCP("tcp", address)
    if err != nil {
        panic(fmt.Sprintf("Error starting message server: %s", err))
    }
    defer l.Close()

    go func() {
        for {
            // Listen for an incoming connection.
            conn, err := l.AcceptTCP()
            if err != nil {
                // Connection closed
                os.Exit(0)
            }
            _, err = fmt.Fprintf(conn, str1+"\n")
            if err != nil {
                panic(fmt.Sprintf("Error sending session ID: %v", err))
            }
            _, err = fmt.Fprintf(conn, str2+"\n")
            if err != nil {
                panic(fmt.Sprintf("Error sending session ID: %v", err))
            }
            conn.Close()
        }
    }()

    // TCP client
    addr, err := net.ResolveTCPAddr("tcp", "localhost:30299")
    if err != nil {
        t.Error("Error resolving address: %v", err)
    }
    connection, err := net.DialTCP("tcp", nil, addr)
    if err != nil {
        t.Error("Error during dial : %v", err)
    }
    defer connection.Close()

    reader := bufio.NewReader(connection)
    receivedStr1, _, err := reader.ReadLine()

    if err != nil {
        t.Error(err)
    }

    receivedStr2, _, err := reader.ReadLine()
    if err != nil {
        t.Error(err)
    }

    fmt.Printf("VALUE -- type %T: q=%p\n", receivedStr1, receivedStr1)
    fmt.Printf("VALUE -- type %T: q=%p\n", receivedStr2, receivedStr2)

    if string(receivedStr1) != str1 {
        t.Error("Bad Str1, should receive " + str1 + " but got " + string(receivedStr1))
    }
    if string(receivedStr2) != str2 {
        t.Error("Bad Str2, should receive " + str2 + " but got " + string(receivedStr2))
    }

}

Output

?       github.com/myapp    [no test files]
=== RUN   TestGetCommand
VALUE -- type []uint8: q=0xc8200a8000
VALUE -- type []uint8: q=0xc8200a8000
--- FAIL: TestGetCommand (0.00s)
    hello_test.go:76: Bad Str1, should receive AAAAAAAAAAAA but got BBBB
        AAAAAAA
FAIL
ok      github.com/myapp/hello  0.002s

Error seems to be due to client bufio, since tcp dump is correct

####
T 127.0.0.1:30299 -> 127.0.0.1:43386 [AP]
  AAAAAAAAAAAA.                                                                                                   
##
T 127.0.0.1:30299 -> 127.0.0.1:43386 [AP]
  BBBB.                                                                                                           
####

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions