diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-02-26 01:00:39 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-02-26 01:00:39 +0000 |
commit | 99e20ba51d5b0785c7e98244d2901853d9fb3b41 (patch) | |
tree | d86fa5d601b8bc3629b3820df4d5e7042853453f /libgo/go/net | |
parent | e5e9b91bc61da0bdb58c6577c319e61a3ed04b17 (diff) | |
download | gcc-99e20ba51d5b0785c7e98244d2901853d9fb3b41.zip gcc-99e20ba51d5b0785c7e98244d2901853d9fb3b41.tar.gz gcc-99e20ba51d5b0785c7e98244d2901853d9fb3b41.tar.bz2 |
libgo: update to Go1.12rc1
Reviewed-on: https://go-review.googlesource.com/c/162881
From-SVN: r269202
Diffstat (limited to 'libgo/go/net')
-rw-r--r-- | libgo/go/net/http/client.go | 8 | ||||
-rw-r--r-- | libgo/go/net/http/fs_test.go | 15 | ||||
-rw-r--r-- | libgo/go/net/http/h2_bundle.go | 8 | ||||
-rw-r--r-- | libgo/go/net/http/http.go | 11 | ||||
-rw-r--r-- | libgo/go/net/http/request.go | 7 | ||||
-rw-r--r-- | libgo/go/net/http/requestwrite_test.go | 11 | ||||
-rw-r--r-- | libgo/go/net/lookup_test.go | 12 | ||||
-rw-r--r-- | libgo/go/net/net_test.go | 2 | ||||
-rw-r--r-- | libgo/go/net/url/url.go | 15 | ||||
-rw-r--r-- | libgo/go/net/url/url_test.go | 23 |
10 files changed, 92 insertions, 20 deletions
diff --git a/libgo/go/net/http/client.go b/libgo/go/net/http/client.go index ea6c0719..921f86b 100644 --- a/libgo/go/net/http/client.go +++ b/libgo/go/net/http/client.go @@ -478,10 +478,10 @@ func urlErrorOp(method string) string { // error. // // If the returned error is nil, the Response will contain a non-nil -// Body which the user is expected to close. If the Body is not -// closed, the Client's underlying RoundTripper (typically Transport) -// may not be able to re-use a persistent TCP connection to the server -// for a subsequent "keep-alive" request. +// Body which the user is expected to close. If the Body is not both +// read to EOF and closed, the Client's underlying RoundTripper +// (typically Transport) may not be able to re-use a persistent TCP +// connection to the server for a subsequent "keep-alive" request. // // The request Body, if non-nil, will be closed by the underlying // Transport, even on errors. diff --git a/libgo/go/net/http/fs_test.go b/libgo/go/net/http/fs_test.go index 1d6380d..82e13a4 100644 --- a/libgo/go/net/http/fs_test.go +++ b/libgo/go/net/http/fs_test.go @@ -583,16 +583,23 @@ func TestFileServerZeroByte(t *testing.T) { ts := httptest.NewServer(FileServer(Dir("."))) defer ts.Close() - res, err := Get(ts.URL + "/..\x00") + c, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatal(err) } - b, err := ioutil.ReadAll(res.Body) + defer c.Close() + _, err = fmt.Fprintf(c, "GET /..\x00 HTTP/1.0\r\n\r\n") + if err != nil { + t.Fatal(err) + } + var got bytes.Buffer + bufr := bufio.NewReader(io.TeeReader(c, &got)) + res, err := ReadResponse(bufr, nil) if err != nil { - t.Fatal("reading Body:", err) + t.Fatal("ReadResponse: ", err) } if res.StatusCode == 200 { - t.Errorf("got status 200; want an error. Body is:\n%s", string(b)) + t.Errorf("got status 200; want an error. Body is:\n%s", got.Bytes()) } } diff --git a/libgo/go/net/http/h2_bundle.go b/libgo/go/net/http/h2_bundle.go index 77c7eee..a848d68 100644 --- a/libgo/go/net/http/h2_bundle.go +++ b/libgo/go/net/http/h2_bundle.go @@ -4852,7 +4852,7 @@ func (sc *http2serverConn) resetStream(se http2StreamError) { // processFrameFromReader processes the serve loop's read from readFrameCh from the // frame-reading goroutine. -// processFrameFromReader reports whether the connection should be kept open. +// processFrameFromReader returns whether the connection should be kept open. func (sc *http2serverConn) processFrameFromReader(res http2readFrameResult) bool { sc.serveG.check() err := res.err @@ -5157,12 +5157,6 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error { // type PROTOCOL_ERROR." return http2ConnectionError(http2ErrCodeProtocol) } - // RFC 7540, sec 6.1: If a DATA frame is received whose stream is not in - // "open" or "half-closed (local)" state, the recipient MUST respond with a - // stream error (Section 5.4.2) of type STREAM_CLOSED. - if state == http2stateClosed { - return http2streamError(id, http2ErrCodeStreamClosed) - } if st == nil || state != http2stateOpen || st.gotTrailerHeader || st.resetQueued { // This includes sending a RST_STREAM if the stream is // in stateHalfClosedLocal (which currently means that diff --git a/libgo/go/net/http/http.go b/libgo/go/net/http/http.go index 624b2cf..e5d59e1 100644 --- a/libgo/go/net/http/http.go +++ b/libgo/go/net/http/http.go @@ -59,6 +59,17 @@ func isASCII(s string) bool { return true } +// stringContainsCTLByte reports whether s contains any ASCII control character. +func stringContainsCTLByte(s string) bool { + for i := 0; i < len(s); i++ { + b := s[i] + if b < ' ' || b == 0x7f { + return true + } + } + return false +} + func hexEscapeNonASCII(s string) string { newLen := 0 for i := 0; i < len(s); i++ { diff --git a/libgo/go/net/http/request.go b/libgo/go/net/http/request.go index fb058f9..dcad2b6 100644 --- a/libgo/go/net/http/request.go +++ b/libgo/go/net/http/request.go @@ -550,7 +550,12 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF ruri = r.URL.Opaque } } - // TODO(bradfitz): escape at least newlines in ruri? + if stringContainsCTLByte(ruri) { + return errors.New("net/http: can't write control character in Request.URL") + } + // TODO: validate r.Method too? At least it's less likely to + // come from an attacker (more likely to be a constant in + // code). // Wrap the writer in a bufio Writer if it's not already buffered. // Don't always call NewWriter, as that forces a bytes.Buffer diff --git a/libgo/go/net/http/requestwrite_test.go b/libgo/go/net/http/requestwrite_test.go index 7dbf0d4..b110b57 100644 --- a/libgo/go/net/http/requestwrite_test.go +++ b/libgo/go/net/http/requestwrite_test.go @@ -576,6 +576,17 @@ var reqWriteTests = []reqWriteTest{ "User-Agent: Go-http-client/1.1\r\n" + "X-Foo: X-Bar\r\n\r\n", }, + + 25: { + Req: Request{ + Method: "GET", + URL: &url.URL{ + Host: "www.example.com", + RawQuery: "new\nline", // or any CTL + }, + }, + WantError: errors.New("net/http: can't write control character in Request.URL"), + }, } func TestRequestWrite(t *testing.T) { diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go index 1da0e49..85bcb2b 100644 --- a/libgo/go/net/lookup_test.go +++ b/libgo/go/net/lookup_test.go @@ -207,6 +207,9 @@ var lookupGmailTXTTests = []struct { } func TestLookupGmailTXT(t *testing.T) { + if runtime.GOOS == "plan9" { + t.Skip("skipping on plan9; see https://golang.org/issue/29722") + } t.Parallel() mustHaveExternalNetwork(t) @@ -237,11 +240,16 @@ func TestLookupGmailTXT(t *testing.T) { if len(txts) == 0 { t.Error("got no record") } + found := false for _, txt := range txts { - if !strings.Contains(txt, tt.txt) || (!strings.HasSuffix(txt, tt.host) && !strings.HasSuffix(txt, tt.host+".")) { - t.Errorf("got %s; want a record containing %s, %s", txt, tt.txt, tt.host) + if strings.Contains(txt, tt.txt) && (strings.HasSuffix(txt, tt.host) || strings.HasSuffix(txt, tt.host+".")) { + found = true + break } } + if !found { + t.Errorf("got %v; want a record containing %s, %s", txts, tt.txt, tt.host) + } } } diff --git a/libgo/go/net/net_test.go b/libgo/go/net/net_test.go index 692f269..2b5845b 100644 --- a/libgo/go/net/net_test.go +++ b/libgo/go/net/net_test.go @@ -529,7 +529,7 @@ func TestNotTemporaryRead(t *testing.T) { server := func(cs *TCPConn) error { cs.SetLinger(0) // Give the client time to get stuck in a Read. - time.Sleep(20 * time.Millisecond) + time.Sleep(50 * time.Millisecond) cs.Close() return nil } diff --git a/libgo/go/net/url/url.go b/libgo/go/net/url/url.go index d84c95a..64274a0 100644 --- a/libgo/go/net/url/url.go +++ b/libgo/go/net/url/url.go @@ -513,6 +513,10 @@ func parse(rawurl string, viaRequest bool) (*URL, error) { var rest string var err error + if stringContainsCTLByte(rawurl) { + return nil, errors.New("net/url: invalid control character in URL") + } + if rawurl == "" && viaRequest { return nil, errors.New("empty url") } @@ -1134,3 +1138,14 @@ func validUserinfo(s string) bool { } return true } + +// stringContainsCTLByte reports whether s contains any ASCII control character. +func stringContainsCTLByte(s string) bool { + for i := 0; i < len(s); i++ { + b := s[i] + if b < ' ' || b == 0x7f { + return true + } + } + return false +} diff --git a/libgo/go/net/url/url_test.go b/libgo/go/net/url/url_test.go index 7c4ada2..c5fc90d 100644 --- a/libgo/go/net/url/url_test.go +++ b/libgo/go/net/url/url_test.go @@ -1738,12 +1738,33 @@ func TestNilUser(t *testing.T) { } func TestInvalidUserPassword(t *testing.T) { - _, err := Parse("http://us\ner:pass\nword@foo.com/") + _, err := Parse("http://user^:passwo^rd@foo.com/") if got, wantsub := fmt.Sprint(err), "net/url: invalid userinfo"; !strings.Contains(got, wantsub) { t.Errorf("error = %q; want substring %q", got, wantsub) } } +func TestRejectControlCharacters(t *testing.T) { + tests := []string{ + "http://foo.com/?foo\nbar", + "http\r://foo.com/", + "http://foo\x7f.com/", + } + for _, s := range tests { + _, err := Parse(s) + const wantSub = "net/url: invalid control character in URL" + if got := fmt.Sprint(err); !strings.Contains(got, wantSub) { + t.Errorf("Parse(%q) error = %q; want substring %q", s, got, wantSub) + } + } + + // But don't reject non-ASCII CTLs, at least for now: + if _, err := Parse("http://foo.com/ctl\x80"); err != nil { + t.Errorf("error parsing URL with non-ASCII control byte: %v", err) + } + +} + var escapeBenchmarks = []struct { unescaped string query string |