This patch to libgo updates it to the Go 1.3.3 release.  This is just
a few bug fixes.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r 03219f2d0191 libgo/MERGE
--- a/libgo/MERGE       Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/MERGE       Mon Oct 27 09:34:59 2014 -0700
@@ -1,4 +1,4 @@
-9895f9e36435
+f44017549ff9
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
diff -r 03219f2d0191 libgo/go/compress/gzip/gzip.go
--- a/libgo/go/compress/gzip/gzip.go    Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/compress/gzip/gzip.go    Mon Oct 27 09:34:59 2014 -0700
@@ -245,7 +245,8 @@
        return z.err
 }
 
-// Close closes the Writer. It does not close the underlying io.Writer.
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
 func (z *Writer) Close() error {
        if z.err != nil {
                return z.err
diff -r 03219f2d0191 libgo/go/compress/zlib/writer.go
--- a/libgo/go/compress/zlib/writer.go  Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/compress/zlib/writer.go  Mon Oct 27 09:34:59 2014 -0700
@@ -174,7 +174,8 @@
        return z.err
 }
 
-// Calling Close does not close the wrapped io.Writer originally passed to 
NewWriter.
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
 func (z *Writer) Close() error {
        if !z.wroteHeader {
                z.err = z.writeHeader()
diff -r 03219f2d0191 libgo/go/crypto/rsa/pkcs1v15.go
--- a/libgo/go/crypto/rsa/pkcs1v15.go   Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/rsa/pkcs1v15.go   Mon Oct 27 09:34:59 2014 -0700
@@ -53,11 +53,14 @@
        if err := checkPub(&priv.PublicKey); err != nil {
                return nil, err
        }
-       valid, out, err := decryptPKCS1v15(rand, priv, ciphertext)
-       if err == nil && valid == 0 {
-               err = ErrDecryption
+       valid, out, index, err := decryptPKCS1v15(rand, priv, ciphertext)
+       if err != nil {
+               return
        }
-
+       if valid == 0 {
+               return nil, ErrDecryption
+       }
+       out = out[index:]
        return
 }
 
@@ -80,21 +83,32 @@
        }
        k := (priv.N.BitLen() + 7) / 8
        if k-(len(key)+3+8) < 0 {
-               err = ErrDecryption
-               return
+               return ErrDecryption
        }
 
-       valid, msg, err := decryptPKCS1v15(rand, priv, ciphertext)
+       valid, em, index, err := decryptPKCS1v15(rand, priv, ciphertext)
        if err != nil {
                return
        }
 
-       valid &= subtle.ConstantTimeEq(int32(len(msg)), int32(len(key)))
-       subtle.ConstantTimeCopy(valid, key, msg)
+       if len(em) != k {
+               // This should be impossible because decryptPKCS1v15 always
+               // returns the full slice.
+               return ErrDecryption
+       }
+
+       valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
+       subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
        return
 }
 
-func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) 
(valid int, msg []byte, err error) {
+// decryptPKCS1v15 decrypts ciphertext using priv and blinds the operation if
+// rand is not nil. It returns one or zero in valid that indicates whether the
+// plaintext was correctly structured. In either case, the plaintext is
+// returned in em so that it may be read independently of whether it was valid
+// in order to maintain constant memory access patterns. If the plaintext was
+// valid then index contains the index of the original message in em.
+func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) 
(valid int, em []byte, index int, err error) {
        k := (priv.N.BitLen() + 7) / 8
        if k < 11 {
                err = ErrDecryption
@@ -107,7 +121,7 @@
                return
        }
 
-       em := leftPad(m.Bytes(), k)
+       em = leftPad(m.Bytes(), k)
        firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
        secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
 
@@ -115,8 +129,7 @@
        // octets, followed by a 0, followed by the message.
        //   lookingForIndex: 1 iff we are still looking for the zero.
        //   index: the offset of the first zero byte.
-       var lookingForIndex, index int
-       lookingForIndex = 1
+       lookingForIndex := 1
 
        for i := 2; i < len(em); i++ {
                equals0 := subtle.ConstantTimeByteEq(em[i], 0)
@@ -129,8 +142,8 @@
        validPS := subtle.ConstantTimeLessOrEq(2+8, index)
 
        valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & 
validPS
-       msg = em[index+1:]
-       return
+       index = subtle.ConstantTimeSelect(valid, index+1, 0)
+       return valid, em, index, nil
 }
 
 // nonZeroRandomBytes fills the given slice with non-zero random octets.
diff -r 03219f2d0191 libgo/go/crypto/rsa/pkcs1v15_test.go
--- a/libgo/go/crypto/rsa/pkcs1v15_test.go      Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/rsa/pkcs1v15_test.go      Mon Oct 27 09:34:59 2014 -0700
@@ -227,6 +227,26 @@
        }
 }
 
+func TestShortSessionKey(t *testing.T) {
+       // This tests that attempting to decrypt a session key where the
+       // ciphertext is too small doesn't run outside the array bounds.
+       ciphertext, err := EncryptPKCS1v15(rand.Reader, 
&rsaPrivateKey.PublicKey, []byte{1})
+       if err != nil {
+               t.Fatalf("Failed to encrypt short message: %s", err)
+       }
+
+       var key [32]byte
+       if err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, ciphertext, 
key[:]); err != nil {
+               t.Fatalf("Failed to decrypt short message: %s", err)
+       }
+
+       for _, v := range key {
+               if v != 0 {
+                       t.Fatal("key was modified when ciphertext was invalid")
+               }
+       }
+}
+
 // In order to generate new test vectors you'll need the PEM form of this key:
 // -----BEGIN RSA PRIVATE KEY-----
 // MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
diff -r 03219f2d0191 libgo/go/crypto/subtle/constant_time.go
--- a/libgo/go/crypto/subtle/constant_time.go   Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/subtle/constant_time.go   Mon Oct 27 09:34:59 2014 -0700
@@ -49,9 +49,14 @@
        return int(z & 1)
 }
 
-// ConstantTimeCopy copies the contents of y into x iff v == 1. If v == 0, x 
is left unchanged.
-// Its behavior is undefined if v takes any other value.
+// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
+// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
+// takes any other value.
 func ConstantTimeCopy(v int, x, y []byte) {
+       if len(x) != len(y) {
+               panic("subtle: slices have different lengths")
+       }
+
        xmask := byte(v - 1)
        ymask := byte(^(v - 1))
        for i := 0; i < len(x); i++ {
diff -r 03219f2d0191 libgo/go/crypto/tls/handshake_server.go
--- a/libgo/go/crypto/tls/handshake_server.go   Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/tls/handshake_server.go   Mon Oct 27 09:34:59 2014 -0700
@@ -214,6 +214,10 @@
 func (hs *serverHandshakeState) checkForResumption() bool {
        c := hs.c
 
+       if c.config.SessionTicketsDisabled {
+               return false
+       }
+
        var ok bool
        if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); 
!ok {
                return false
diff -r 03219f2d0191 libgo/go/crypto/tls/handshake_server_test.go
--- a/libgo/go/crypto/tls/handshake_server_test.go      Thu Oct 23 21:57:37 
2014 -0700
+++ b/libgo/go/crypto/tls/handshake_server_test.go      Mon Oct 27 09:34:59 
2014 -0700
@@ -557,6 +557,32 @@
        runServerTestTLS12(t, test)
 }
 
+func TestResumptionDisabled(t *testing.T) {
+       sessionFilePath := tempFile("")
+       defer os.Remove(sessionFilePath)
+
+       config := *testConfig
+
+       test := &serverTest{
+               name:    "IssueTicketPreDisable",
+               command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", 
"-sess_out", sessionFilePath},
+               config:  &config,
+       }
+       runServerTestTLS12(t, test)
+
+       config.SessionTicketsDisabled = true
+
+       test = &serverTest{
+               name:    "ResumeDisabled",
+               command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", 
"-sess_in", sessionFilePath},
+               config:  &config,
+       }
+       runServerTestTLS12(t, test)
+
+       // One needs to manually confirm that the handshake in the golden data
+       // file for ResumeDisabled does not include a resumption handshake.
+}
+
 // cert.pem and key.pem were generated with generate_cert.go
 // Thus, they have no ExtKeyUsage fields and trigger an error
 // when verification is turned on.
diff -r 03219f2d0191 libgo/go/crypto/tls/ticket.go
--- a/libgo/go/crypto/tls/ticket.go     Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/tls/ticket.go     Mon Oct 27 09:34:59 2014 -0700
@@ -153,7 +153,8 @@
 }
 
 func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
-       if len(encrypted) < aes.BlockSize+sha256.Size {
+       if c.config.SessionTicketsDisabled ||
+               len(encrypted) < aes.BlockSize+sha256.Size {
                return nil, false
        }
 
diff -r 03219f2d0191 libgo/go/net/dnsconfig_unix.go
--- a/libgo/go/net/dnsconfig_unix.go    Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/dnsconfig_unix.go    Mon Oct 27 09:34:59 2014 -0700
@@ -75,19 +75,19 @@
                        for i := 1; i < len(f); i++ {
                                s := f[i]
                                switch {
-                               case len(s) >= 6 && s[0:6] == "ndots:":
+                               case hasPrefix(s, "ndots:"):
                                        n, _, _ := dtoi(s, 6)
                                        if n < 1 {
                                                n = 1
                                        }
                                        conf.ndots = n
-                               case len(s) >= 8 && s[0:8] == "timeout:":
+                               case hasPrefix(s, "timeout:"):
                                        n, _, _ := dtoi(s, 8)
                                        if n < 1 {
                                                n = 1
                                        }
                                        conf.timeout = n
-                               case len(s) >= 8 && s[0:9] == "attempts:":
+                               case hasPrefix(s, "attempts:"):
                                        n, _, _ := dtoi(s, 9)
                                        if n < 1 {
                                                n = 1
@@ -103,3 +103,7 @@
 
        return conf, nil
 }
+
+func hasPrefix(s, prefix string) bool {
+       return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
diff -r 03219f2d0191 libgo/go/net/fd_unix.go
--- a/libgo/go/net/fd_unix.go   Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/fd_unix.go   Mon Oct 27 09:34:59 2014 -0700
@@ -68,16 +68,19 @@
        return fd.net + ":" + ls + "->" + rs
 }
 
-func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
+func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
        // Do not need to call fd.writeLock here,
        // because fd is not yet accessible to user,
        // so no concurrent operations are possible.
-       if err := fd.pd.PrepareWrite(); err != nil {
-               return err
-       }
        switch err := syscall.Connect(fd.sysfd, ra); err {
        case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
        case nil, syscall.EISCONN:
+               if !deadline.IsZero() && deadline.Before(time.Now()) {
+                       return errTimeout
+               }
+               if err := fd.init(); err != nil {
+                       return err
+               }
                return nil
        case syscall.EINVAL:
                // On Solaris we can see EINVAL if the socket has
@@ -92,6 +95,13 @@
        default:
                return err
        }
+       if err := fd.init(); err != nil {
+               return err
+       }
+       if !deadline.IsZero() {
+               fd.setWriteDeadline(deadline)
+               defer fd.setWriteDeadline(noDeadline)
+       }
        for {
                // Performing multiple connect system calls on a
                // non-blocking socket under Unix variants does not
diff -r 03219f2d0191 libgo/go/net/fd_windows.go
--- a/libgo/go/net/fd_windows.go        Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/fd_windows.go        Mon Oct 27 09:34:59 2014 -0700
@@ -313,10 +313,17 @@
        runtime.SetFinalizer(fd, (*netFD).Close)
 }
 
-func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
+func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
        // Do not need to call fd.writeLock here,
        // because fd is not yet accessible to user,
        // so no concurrent operations are possible.
+       if err := fd.init(); err != nil {
+               return err
+       }
+       if !deadline.IsZero() {
+               fd.setWriteDeadline(deadline)
+               defer fd.setWriteDeadline(noDeadline)
+       }
        if !canUseConnectEx(fd.net) {
                return syscall.Connect(fd.sysfd, ra)
        }
diff -r 03219f2d0191 libgo/go/net/http/httptest/server_test.go
--- a/libgo/go/net/http/httptest/server_test.go Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/http/httptest/server_test.go Mon Oct 27 09:34:59 2014 -0700
@@ -30,6 +30,7 @@
 }
 
 func TestIssue7264(t *testing.T) {
+       t.Skip("broken test - removed at tip")
        for i := 0; i < 1000; i++ {
                func() {
                        inHandler := make(chan bool, 1)
diff -r 03219f2d0191 libgo/go/net/sock_posix.go
--- a/libgo/go/net/sock_posix.go        Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/sock_posix.go        Mon Oct 27 09:34:59 2014 -0700
@@ -107,24 +107,18 @@
                        }
                }
        }
-       if err := fd.init(); err != nil {
-               return err
-       }
        var rsa syscall.Sockaddr
        if raddr != nil {
                if rsa, err = raddr.sockaddr(fd.family); err != nil {
                        return err
-               } else if rsa != nil {
-                       if !deadline.IsZero() {
-                               fd.setWriteDeadline(deadline)
-                       }
-                       if err := fd.connect(lsa, rsa); err != nil {
-                               return err
-                       }
-                       fd.isConnected = true
-                       if !deadline.IsZero() {
-                               fd.setWriteDeadline(noDeadline)
-                       }
+               }
+               if err := fd.connect(lsa, rsa, deadline); err != nil {
+                       return err
+               }
+               fd.isConnected = true
+       } else {
+               if err := fd.init(); err != nil {
+                       return err
                }
        }
        lsa, _ = syscall.Getsockname(fd.sysfd)
diff -r 03219f2d0191 libgo/go/net/testdata/resolv.conf
--- a/libgo/go/net/testdata/resolv.conf Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/testdata/resolv.conf Mon Oct 27 09:34:59 2014 -0700
@@ -3,3 +3,4 @@
 domain Home
 nameserver 192.168.1.1
 options ndots:5 timeout:10 attempts:3 rotate
+options attempts 3
diff -r 03219f2d0191 libgo/go/time/format_test.go
--- a/libgo/go/time/format_test.go      Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/time/format_test.go      Mon Oct 27 09:34:59 2014 -0700
@@ -183,39 +183,45 @@
        }
 }
 
-func TestParseInSydney(t *testing.T) {
-       loc, err := LoadLocation("Australia/Sydney")
+func TestParseInLocation(t *testing.T) {
+       // Check that Parse (and ParseInLocation) understand that
+       // Feb 01 AST (Arabia Standard Time) and Feb 01 AST (Atlantic Standard 
Time)
+       // are in different time zones even though both are called AST
+
+       baghdad, err := LoadLocation("Asia/Baghdad")
        if err != nil {
                t.Fatal(err)
        }
 
-       // Check that Parse (and ParseInLocation) understand
-       // that Feb EST and Aug EST are different time zones in Sydney
-       // even though both are called EST.
-       t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 EST", loc)
+       t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", 
baghdad)
        if err != nil {
                t.Fatal(err)
        }
-       t2 := Date(2013, February, 1, 00, 00, 00, 0, loc)
+       t2 := Date(2013, February, 1, 00, 00, 00, 0, baghdad)
        if t1 != t2 {
-               t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney) = %v, want 
%v", t1, t2)
+               t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad) = %v, want 
%v", t1, t2)
        }
        _, offset := t1.Zone()
-       if offset != 11*60*60 {
-               t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney).Zone = _, 
%d, want _, %d", offset, 11*60*60)
+       if offset != 3*60*60 {
+               t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad).Zone = _, 
%d, want _, %d", offset, 3*60*60)
        }
 
-       t1, err = ParseInLocation("Jan 02 2006 MST", "Aug 01 2013 EST", loc)
+       blancSablon, err := LoadLocation("America/Blanc-Sablon")
        if err != nil {
                t.Fatal(err)
        }
-       t2 = Date(2013, August, 1, 00, 00, 00, 0, loc)
+
+       t1, err = ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", 
blancSablon)
+       if err != nil {
+               t.Fatal(err)
+       }
+       t2 = Date(2013, February, 1, 00, 00, 00, 0, blancSablon)
        if t1 != t2 {
-               t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney) = %v, want 
%v", t1, t2)
+               t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon) = %v, 
want %v", t1, t2)
        }
        _, offset = t1.Zone()
-       if offset != 10*60*60 {
-               t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney).Zone = _, 
%d, want _, %d", offset, 10*60*60)
+       if offset != -4*60*60 {
+               t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon).Zone = 
_, %d, want _, %d", offset, -4*60*60)
        }
 }
 
diff -r 03219f2d0191 libgo/runtime/runtime.c
--- a/libgo/runtime/runtime.c   Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/runtime/runtime.c   Mon Oct 27 09:34:59 2014 -0700
@@ -112,8 +112,6 @@
        syscall_Envs.__values = (void*)s;
        syscall_Envs.__count = n;
        syscall_Envs.__capacity = n;
-
-       traceback_cache = ~(uint32)0;
 }
 
 int32
@@ -309,6 +307,16 @@
 {
        const byte *p;
        intgo i, n;
+       bool tmp;
+       
+       // gotraceback caches the GOTRACEBACK setting in traceback_cache.
+       // gotraceback can be called before the environment is available.
+       // traceback_cache must be reset after the environment is made
+       // available, in order for the environment variable to take effect.
+       // The code is fixed differently in Go 1.4.
+       // This is a limited fix for Go 1.3.3.
+       traceback_cache = ~(uint32)0;
+       runtime_gotraceback(&tmp);
 
        p = runtime_getenv("GODEBUG");
        if(p == nil)

Reply via email to