Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25e497e367 | ||
|
|
716e5b5d05 |
4
VERSION
4
VERSION
@@ -1,2 +1,2 @@
|
|||||||
go1.23.4
|
go1.23.6
|
||||||
time 2024-11-27T20:27:20Z
|
time 2025-01-31T18:38:03Z
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ func writebarrier(f *Func) {
|
|||||||
var start, end int
|
var start, end int
|
||||||
var nonPtrStores int
|
var nonPtrStores int
|
||||||
values := b.Values
|
values := b.Values
|
||||||
|
hasMove := false
|
||||||
FindSeq:
|
FindSeq:
|
||||||
for i := len(values) - 1; i >= 0; i-- {
|
for i := len(values) - 1; i >= 0; i-- {
|
||||||
w := values[i]
|
w := values[i]
|
||||||
@@ -263,6 +264,9 @@ func writebarrier(f *Func) {
|
|||||||
end = i + 1
|
end = i + 1
|
||||||
}
|
}
|
||||||
nonPtrStores = 0
|
nonPtrStores = 0
|
||||||
|
if w.Op == OpMoveWB {
|
||||||
|
hasMove = true
|
||||||
|
}
|
||||||
case OpVarDef, OpVarLive:
|
case OpVarDef, OpVarLive:
|
||||||
continue
|
continue
|
||||||
case OpStore:
|
case OpStore:
|
||||||
@@ -273,6 +277,17 @@ func writebarrier(f *Func) {
|
|||||||
if nonPtrStores > 2 {
|
if nonPtrStores > 2 {
|
||||||
break FindSeq
|
break FindSeq
|
||||||
}
|
}
|
||||||
|
if hasMove {
|
||||||
|
// We need to ensure that this store happens
|
||||||
|
// before we issue a wbMove, as the wbMove might
|
||||||
|
// use the result of this store as its source.
|
||||||
|
// Even though this store is not write-barrier
|
||||||
|
// eligible, it might nevertheless be the store
|
||||||
|
// of a pointer to the stack, which is then the
|
||||||
|
// source of the move.
|
||||||
|
// See issue 71228.
|
||||||
|
break FindSeq
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if last == nil {
|
if last == nil {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -662,7 +662,21 @@ func (r *gitRepo) statLocal(ctx context.Context, version, rev string) (*RevInfo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Strings(info.Tags)
|
|
||||||
|
// Git 2.47.1 does not send the tags during shallow clone anymore
|
||||||
|
// (perhaps the exact version that changed behavior is an earlier one),
|
||||||
|
// so we have to also add tags from the refs list we fetched with ls-remote.
|
||||||
|
if refs, err := r.loadRefs(ctx); err == nil {
|
||||||
|
for ref, h := range refs {
|
||||||
|
if h == hash {
|
||||||
|
if tag, found := strings.CutPrefix(ref, "refs/tags/"); found {
|
||||||
|
info.Tags = append(info.Tags, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slices.Sort(info.Tags)
|
||||||
|
info.Tags = slices.Compact(info.Tags)
|
||||||
|
|
||||||
// Used hash as info.Version above.
|
// Used hash as info.Version above.
|
||||||
// Use caller's suggested version if it appears in the tag list
|
// Use caller's suggested version if it appears in the tag list
|
||||||
|
|||||||
@@ -126,14 +126,23 @@ GLOBL p256mul<>(SB), 8, $160
|
|||||||
#define PH V31
|
#define PH V31
|
||||||
|
|
||||||
#define CAR1 V6
|
#define CAR1 V6
|
||||||
|
|
||||||
|
#define SEL V8
|
||||||
|
#define ZER V9
|
||||||
|
|
||||||
// func p256NegCond(val *p256Point, cond int)
|
// func p256NegCond(val *p256Point, cond int)
|
||||||
TEXT ·p256NegCond(SB), NOSPLIT, $0-16
|
TEXT ·p256NegCond(SB), NOSPLIT, $0-16
|
||||||
MOVD val+0(FP), P1ptr
|
MOVD val+0(FP), P1ptr
|
||||||
MOVD $16, R16
|
MOVD $16, R16
|
||||||
|
|
||||||
MOVD cond+8(FP), R6
|
// Copy cond into SEL (cond is R1 + 8 (cond offset) + 32)
|
||||||
CMP $0, R6
|
MOVD $40, R17
|
||||||
BC 12, 2, LR // just return if cond == 0
|
LXVDSX (R1)(R17), SEL
|
||||||
|
// Zeroize ZER
|
||||||
|
VSPLTISB $0, ZER
|
||||||
|
// SEL controls whether to return the original value (Y1H/Y1L)
|
||||||
|
// or the negated value (T1H/T1L).
|
||||||
|
VCMPEQUD SEL, ZER, SEL
|
||||||
|
|
||||||
MOVD $p256mul<>+0x00(SB), CPOOL
|
MOVD $p256mul<>+0x00(SB), CPOOL
|
||||||
|
|
||||||
@@ -150,6 +159,9 @@ TEXT ·p256NegCond(SB), NOSPLIT, $0-16
|
|||||||
VSUBUQM PL, Y1L, T1L // subtract part2 giving result
|
VSUBUQM PL, Y1L, T1L // subtract part2 giving result
|
||||||
VSUBEUQM PH, Y1H, CAR1, T1H // subtract part1 using carry from part2
|
VSUBEUQM PH, Y1H, CAR1, T1H // subtract part1 using carry from part2
|
||||||
|
|
||||||
|
VSEL T1H, Y1H, SEL, T1H
|
||||||
|
VSEL T1L, Y1L, SEL, T1L
|
||||||
|
|
||||||
XXPERMDI T1H, T1H, $2, T1H
|
XXPERMDI T1H, T1H, $2, T1H
|
||||||
XXPERMDI T1L, T1L, $2, T1L
|
XXPERMDI T1L, T1L, $2, T1L
|
||||||
|
|
||||||
@@ -166,6 +178,8 @@ TEXT ·p256NegCond(SB), NOSPLIT, $0-16
|
|||||||
#undef PL
|
#undef PL
|
||||||
#undef PH
|
#undef PH
|
||||||
#undef CAR1
|
#undef CAR1
|
||||||
|
#undef SEL
|
||||||
|
#undef ZER
|
||||||
|
|
||||||
#define P3ptr R3
|
#define P3ptr R3
|
||||||
#define P1ptr R4
|
#define P1ptr R4
|
||||||
|
|||||||
@@ -852,6 +852,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
MaxVersion: version,
|
MaxVersion: version,
|
||||||
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
||||||
Certificates: testConfig.Certificates,
|
Certificates: testConfig.Certificates,
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
|
issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
|
||||||
@@ -868,6 +869,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
ClientSessionCache: NewLRUClientSessionCache(32),
|
ClientSessionCache: NewLRUClientSessionCache(32),
|
||||||
RootCAs: rootCAs,
|
RootCAs: rootCAs,
|
||||||
ServerName: "example.golang",
|
ServerName: "example.golang",
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
testResumeState := func(test string, didResume bool) {
|
testResumeState := func(test string, didResume bool) {
|
||||||
@@ -914,7 +916,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
|
|
||||||
// An old session ticket is replaced with a ticket encrypted with a fresh key.
|
// An old session ticket is replaced with a ticket encrypted with a fresh key.
|
||||||
ticket = getTicket()
|
ticket = getTicket()
|
||||||
serverConfig.Time = func() time.Time { return time.Now().Add(24*time.Hour + time.Minute) }
|
serverConfig.Time = func() time.Time { return testTime().Add(24*time.Hour + time.Minute) }
|
||||||
testResumeState("ResumeWithOldTicket", true)
|
testResumeState("ResumeWithOldTicket", true)
|
||||||
if bytes.Equal(ticket, getTicket()) {
|
if bytes.Equal(ticket, getTicket()) {
|
||||||
t.Fatal("old first ticket matches the fresh one")
|
t.Fatal("old first ticket matches the fresh one")
|
||||||
@@ -922,13 +924,13 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
|
|
||||||
// Once the session master secret is expired, a full handshake should occur.
|
// Once the session master secret is expired, a full handshake should occur.
|
||||||
ticket = getTicket()
|
ticket = getTicket()
|
||||||
serverConfig.Time = func() time.Time { return time.Now().Add(24*8*time.Hour + time.Minute) }
|
serverConfig.Time = func() time.Time { return testTime().Add(24*8*time.Hour + time.Minute) }
|
||||||
testResumeState("ResumeWithExpiredTicket", false)
|
testResumeState("ResumeWithExpiredTicket", false)
|
||||||
if bytes.Equal(ticket, getTicket()) {
|
if bytes.Equal(ticket, getTicket()) {
|
||||||
t.Fatal("expired first ticket matches the fresh one")
|
t.Fatal("expired first ticket matches the fresh one")
|
||||||
}
|
}
|
||||||
|
|
||||||
serverConfig.Time = func() time.Time { return time.Now() } // reset the time back
|
serverConfig.Time = testTime // reset the time back
|
||||||
key1 := randomKey()
|
key1 := randomKey()
|
||||||
serverConfig.SetSessionTicketKeys([][32]byte{key1})
|
serverConfig.SetSessionTicketKeys([][32]byte{key1})
|
||||||
|
|
||||||
@@ -945,11 +947,11 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
testResumeState("KeyChangeFinish", true)
|
testResumeState("KeyChangeFinish", true)
|
||||||
|
|
||||||
// Age the session ticket a bit, but not yet expired.
|
// Age the session ticket a bit, but not yet expired.
|
||||||
serverConfig.Time = func() time.Time { return time.Now().Add(24*time.Hour + time.Minute) }
|
serverConfig.Time = func() time.Time { return testTime().Add(24*time.Hour + time.Minute) }
|
||||||
testResumeState("OldSessionTicket", true)
|
testResumeState("OldSessionTicket", true)
|
||||||
ticket = getTicket()
|
ticket = getTicket()
|
||||||
// Expire the session ticket, which would force a full handshake.
|
// Expire the session ticket, which would force a full handshake.
|
||||||
serverConfig.Time = func() time.Time { return time.Now().Add(24*8*time.Hour + time.Minute) }
|
serverConfig.Time = func() time.Time { return testTime().Add(24*8*time.Hour + 2*time.Minute) }
|
||||||
testResumeState("ExpiredSessionTicket", false)
|
testResumeState("ExpiredSessionTicket", false)
|
||||||
if bytes.Equal(ticket, getTicket()) {
|
if bytes.Equal(ticket, getTicket()) {
|
||||||
t.Fatal("new ticket wasn't provided after old ticket expired")
|
t.Fatal("new ticket wasn't provided after old ticket expired")
|
||||||
@@ -957,7 +959,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
|
|
||||||
// Age the session ticket a bit at a time, but don't expire it.
|
// Age the session ticket a bit at a time, but don't expire it.
|
||||||
d := 0 * time.Hour
|
d := 0 * time.Hour
|
||||||
serverConfig.Time = func() time.Time { return time.Now().Add(d) }
|
serverConfig.Time = func() time.Time { return testTime().Add(d) }
|
||||||
deleteTicket()
|
deleteTicket()
|
||||||
testResumeState("GetFreshSessionTicket", false)
|
testResumeState("GetFreshSessionTicket", false)
|
||||||
for i := 0; i < 13; i++ {
|
for i := 0; i < 13; i++ {
|
||||||
@@ -968,7 +970,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
// handshake occurs for TLS 1.2. Resumption should still occur for
|
// handshake occurs for TLS 1.2. Resumption should still occur for
|
||||||
// TLS 1.3 since the client should be using a fresh ticket sent over
|
// TLS 1.3 since the client should be using a fresh ticket sent over
|
||||||
// by the server.
|
// by the server.
|
||||||
d += 12 * time.Hour
|
d += 12*time.Hour + time.Minute
|
||||||
if version == VersionTLS13 {
|
if version == VersionTLS13 {
|
||||||
testResumeState("ExpiredSessionTicket", true)
|
testResumeState("ExpiredSessionTicket", true)
|
||||||
} else {
|
} else {
|
||||||
@@ -984,6 +986,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
MaxVersion: version,
|
MaxVersion: version,
|
||||||
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
||||||
Certificates: testConfig.Certificates,
|
Certificates: testConfig.Certificates,
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
serverConfig.SetSessionTicketKeys([][32]byte{key2})
|
serverConfig.SetSessionTicketKeys([][32]byte{key2})
|
||||||
|
|
||||||
@@ -1009,6 +1012,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
CurvePreferences: []CurveID{CurveP521, CurveP384, CurveP256},
|
CurvePreferences: []CurveID{CurveP521, CurveP384, CurveP256},
|
||||||
MaxVersion: version,
|
MaxVersion: version,
|
||||||
Certificates: testConfig.Certificates,
|
Certificates: testConfig.Certificates,
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
testResumeState("InitialHandshake", false)
|
testResumeState("InitialHandshake", false)
|
||||||
testResumeState("WithHelloRetryRequest", true)
|
testResumeState("WithHelloRetryRequest", true)
|
||||||
@@ -1018,6 +1022,7 @@ func testResumption(t *testing.T, version uint16) {
|
|||||||
MaxVersion: version,
|
MaxVersion: version,
|
||||||
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
|
||||||
Certificates: testConfig.Certificates,
|
Certificates: testConfig.Certificates,
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1736,6 +1741,7 @@ func testVerifyConnection(t *testing.T, version uint16) {
|
|||||||
serverConfig := &Config{
|
serverConfig := &Config{
|
||||||
MaxVersion: version,
|
MaxVersion: version,
|
||||||
Certificates: []Certificate{testConfig.Certificates[0]},
|
Certificates: []Certificate{testConfig.Certificates[0]},
|
||||||
|
Time: testTime,
|
||||||
ClientCAs: rootCAs,
|
ClientCAs: rootCAs,
|
||||||
NextProtos: []string{"protocol1"},
|
NextProtos: []string{"protocol1"},
|
||||||
}
|
}
|
||||||
@@ -1749,6 +1755,7 @@ func testVerifyConnection(t *testing.T, version uint16) {
|
|||||||
RootCAs: rootCAs,
|
RootCAs: rootCAs,
|
||||||
ServerName: "example.golang",
|
ServerName: "example.golang",
|
||||||
Certificates: []Certificate{testConfig.Certificates[0]},
|
Certificates: []Certificate{testConfig.Certificates[0]},
|
||||||
|
Time: testTime,
|
||||||
NextProtos: []string{"protocol1"},
|
NextProtos: []string{"protocol1"},
|
||||||
}
|
}
|
||||||
test.configureClient(clientConfig, &clientCalled)
|
test.configureClient(clientConfig, &clientCalled)
|
||||||
@@ -1791,8 +1798,6 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
|
|||||||
rootCAs := x509.NewCertPool()
|
rootCAs := x509.NewCertPool()
|
||||||
rootCAs.AddCert(issuer)
|
rootCAs.AddCert(issuer)
|
||||||
|
|
||||||
now := func() time.Time { return time.Unix(1476984729, 0) }
|
|
||||||
|
|
||||||
sentinelErr := errors.New("TestVerifyPeerCertificate")
|
sentinelErr := errors.New("TestVerifyPeerCertificate")
|
||||||
|
|
||||||
verifyPeerCertificateCallback := func(called *bool, rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
|
verifyPeerCertificateCallback := func(called *bool, rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
|
||||||
@@ -2038,7 +2043,7 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
|
|||||||
config.ServerName = "example.golang"
|
config.ServerName = "example.golang"
|
||||||
config.ClientAuth = RequireAndVerifyClientCert
|
config.ClientAuth = RequireAndVerifyClientCert
|
||||||
config.ClientCAs = rootCAs
|
config.ClientCAs = rootCAs
|
||||||
config.Time = now
|
config.Time = testTime
|
||||||
config.MaxVersion = version
|
config.MaxVersion = version
|
||||||
config.Certificates = make([]Certificate, 1)
|
config.Certificates = make([]Certificate, 1)
|
||||||
config.Certificates[0].Certificate = [][]byte{testRSACertificate}
|
config.Certificates[0].Certificate = [][]byte{testRSACertificate}
|
||||||
@@ -2055,7 +2060,7 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
|
|||||||
config := testConfig.Clone()
|
config := testConfig.Clone()
|
||||||
config.ServerName = "example.golang"
|
config.ServerName = "example.golang"
|
||||||
config.RootCAs = rootCAs
|
config.RootCAs = rootCAs
|
||||||
config.Time = now
|
config.Time = testTime
|
||||||
config.MaxVersion = version
|
config.MaxVersion = version
|
||||||
test.configureClient(config, &clientCalled)
|
test.configureClient(config, &clientCalled)
|
||||||
clientErr := Client(c, config).Handshake()
|
clientErr := Client(c, config).Handshake()
|
||||||
@@ -2368,7 +2373,7 @@ func testGetClientCertificate(t *testing.T, version uint16) {
|
|||||||
serverConfig.RootCAs = x509.NewCertPool()
|
serverConfig.RootCAs = x509.NewCertPool()
|
||||||
serverConfig.RootCAs.AddCert(issuer)
|
serverConfig.RootCAs.AddCert(issuer)
|
||||||
serverConfig.ClientCAs = serverConfig.RootCAs
|
serverConfig.ClientCAs = serverConfig.RootCAs
|
||||||
serverConfig.Time = func() time.Time { return time.Unix(1476984729, 0) }
|
serverConfig.Time = testTime
|
||||||
serverConfig.MaxVersion = version
|
serverConfig.MaxVersion = version
|
||||||
|
|
||||||
clientConfig := testConfig.Clone()
|
clientConfig := testConfig.Clone()
|
||||||
@@ -2539,6 +2544,7 @@ func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) {
|
|||||||
ClientSessionCache: NewLRUClientSessionCache(32),
|
ClientSessionCache: NewLRUClientSessionCache(32),
|
||||||
ServerName: "example.golang",
|
ServerName: "example.golang",
|
||||||
RootCAs: roots,
|
RootCAs: roots,
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
serverConfig := testConfig.Clone()
|
serverConfig := testConfig.Clone()
|
||||||
serverConfig.MaxVersion = ver
|
serverConfig.MaxVersion = ver
|
||||||
|
|||||||
@@ -501,6 +501,7 @@ func testCrossVersionResume(t *testing.T, version uint16) {
|
|||||||
serverConfig := &Config{
|
serverConfig := &Config{
|
||||||
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
|
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
|
||||||
Certificates: testConfig.Certificates,
|
Certificates: testConfig.Certificates,
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
clientConfig := &Config{
|
clientConfig := &Config{
|
||||||
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
|
CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
|
||||||
@@ -508,6 +509,7 @@ func testCrossVersionResume(t *testing.T, version uint16) {
|
|||||||
ClientSessionCache: NewLRUClientSessionCache(1),
|
ClientSessionCache: NewLRUClientSessionCache(1),
|
||||||
ServerName: "servername",
|
ServerName: "servername",
|
||||||
MinVersion: VersionTLS12,
|
MinVersion: VersionTLS12,
|
||||||
|
Time: testTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establish a session at TLS 1.3.
|
// Establish a session at TLS 1.3.
|
||||||
|
|||||||
@@ -519,6 +519,11 @@ func fromHex(s string) []byte {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testTime is 2016-10-20T17:32:09.000Z, which is within the validity period of
|
||||||
|
// [testRSACertificate], [testRSACertificateIssuer], [testRSA2048Certificate],
|
||||||
|
// [testRSA2048CertificateIssuer], and [testECDSACertificate].
|
||||||
|
var testTime = func() time.Time { return time.Unix(1476984729, 0) }
|
||||||
|
|
||||||
var testRSACertificate = fromHex("3082024b308201b4a003020102020900e8f09d3fe25beaa6300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301a310b3009060355040a1302476f310b300906035504031302476f30819f300d06092a864886f70d010101050003818d0030818902818100db467d932e12270648bc062821ab7ec4b6a25dfe1e5245887a3647a5080d92425bc281c0be97799840fb4f6d14fd2b138bc2a52e67d8d4099ed62238b74a0b74732bc234f1d193e596d9747bf3589f6c613cc0b041d4d92b2b2423775b1c3bbd755dce2054cfa163871d1e24c4f31d1a508baab61443ed97a77562f414c852d70203010001a38193308190300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff0402300030190603551d0e041204109f91161f43433e49a6de6db680d79f60301b0603551d230414301280104813494d137e1631bba301d5acab6e7b30190603551d1104123010820e6578616d706c652e676f6c616e67300d06092a864886f70d01010b0500038181009d30cc402b5b50a061cbbae55358e1ed8328a9581aa938a495a1ac315a1a84663d43d32dd90bf297dfd320643892243a00bccf9c7db74020015faad3166109a276fd13c3cce10c5ceeb18782f16c04ed73bbb343778d0c1cf10fa1d8408361c94c722b9daedb4606064df4c1b33ec0d1bd42d4dbfe3d1360845c21d33be9fae7")
|
var testRSACertificate = fromHex("3082024b308201b4a003020102020900e8f09d3fe25beaa6300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301a310b3009060355040a1302476f310b300906035504031302476f30819f300d06092a864886f70d010101050003818d0030818902818100db467d932e12270648bc062821ab7ec4b6a25dfe1e5245887a3647a5080d92425bc281c0be97799840fb4f6d14fd2b138bc2a52e67d8d4099ed62238b74a0b74732bc234f1d193e596d9747bf3589f6c613cc0b041d4d92b2b2423775b1c3bbd755dce2054cfa163871d1e24c4f31d1a508baab61443ed97a77562f414c852d70203010001a38193308190300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff0402300030190603551d0e041204109f91161f43433e49a6de6db680d79f60301b0603551d230414301280104813494d137e1631bba301d5acab6e7b30190603551d1104123010820e6578616d706c652e676f6c616e67300d06092a864886f70d01010b0500038181009d30cc402b5b50a061cbbae55358e1ed8328a9581aa938a495a1ac315a1a84663d43d32dd90bf297dfd320643892243a00bccf9c7db74020015faad3166109a276fd13c3cce10c5ceeb18782f16c04ed73bbb343778d0c1cf10fa1d8408361c94c722b9daedb4606064df4c1b33ec0d1bd42d4dbfe3d1360845c21d33be9fae7")
|
||||||
|
|
||||||
var testRSACertificateIssuer = fromHex("3082021930820182a003020102020900ca5e4e811a965964300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f7430819f300d06092a864886f70d010101050003818d0030818902818100d667b378bb22f34143b6cd2008236abefaf2852adf3ab05e01329e2c14834f5105df3f3073f99dab5442d45ee5f8f57b0111c8cb682fbb719a86944eebfffef3406206d898b8c1b1887797c9c5006547bb8f00e694b7a063f10839f269f2c34fff7a1f4b21fbcd6bfdfb13ac792d1d11f277b5c5b48600992203059f2a8f8cc50203010001a35d305b300e0603551d0f0101ff040403020204301d0603551d250416301406082b0601050507030106082b06010505070302300f0603551d130101ff040530030101ff30190603551d0e041204104813494d137e1631bba301d5acab6e7b300d06092a864886f70d01010b050003818100c1154b4bab5266221f293766ae4138899bd4c5e36b13cee670ceeaa4cbdf4f6679017e2fe649765af545749fe4249418a56bd38a04b81e261f5ce86b8d5c65413156a50d12449554748c59a30c515bc36a59d38bddf51173e899820b282e40aa78c806526fd184fb6b4cf186ec728edffa585440d2b3225325f7ab580e87dd76")
|
var testRSACertificateIssuer = fromHex("3082021930820182a003020102020900ca5e4e811a965964300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f7430819f300d06092a864886f70d010101050003818d0030818902818100d667b378bb22f34143b6cd2008236abefaf2852adf3ab05e01329e2c14834f5105df3f3073f99dab5442d45ee5f8f57b0111c8cb682fbb719a86944eebfffef3406206d898b8c1b1887797c9c5006547bb8f00e694b7a063f10839f269f2c34fff7a1f4b21fbcd6bfdfb13ac792d1d11f277b5c5b48600992203059f2a8f8cc50203010001a35d305b300e0603551d0f0101ff040403020204301d0603551d250416301406082b0601050507030106082b06010505070302300f0603551d130101ff040530030101ff30190603551d0e041204104813494d137e1631bba301d5acab6e7b300d06092a864886f70d01010b050003818100c1154b4bab5266221f293766ae4138899bd4c5e36b13cee670ceeaa4cbdf4f6679017e2fe649765af545749fe4249418a56bd38a04b81e261f5ce86b8d5c65413156a50d12449554748c59a30c515bc36a59d38bddf51173e899820b282e40aa78c806526fd184fb6b4cf186ec728edffa585440d2b3225325f7ab580e87dd76")
|
||||||
|
|||||||
@@ -1112,8 +1112,6 @@ func TestConnectionState(t *testing.T) {
|
|||||||
rootCAs := x509.NewCertPool()
|
rootCAs := x509.NewCertPool()
|
||||||
rootCAs.AddCert(issuer)
|
rootCAs.AddCert(issuer)
|
||||||
|
|
||||||
now := func() time.Time { return time.Unix(1476984729, 0) }
|
|
||||||
|
|
||||||
const alpnProtocol = "golang"
|
const alpnProtocol = "golang"
|
||||||
const serverName = "example.golang"
|
const serverName = "example.golang"
|
||||||
var scts = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")}
|
var scts = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")}
|
||||||
@@ -1129,7 +1127,7 @@ func TestConnectionState(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
config := &Config{
|
config := &Config{
|
||||||
Time: now,
|
Time: testTime,
|
||||||
Rand: zeroSource{},
|
Rand: zeroSource{},
|
||||||
Certificates: make([]Certificate, 1),
|
Certificates: make([]Certificate, 1),
|
||||||
MaxVersion: v,
|
MaxVersion: v,
|
||||||
@@ -1760,7 +1758,7 @@ func testVerifyCertificates(t *testing.T, version uint16) {
|
|||||||
var serverVerifyPeerCertificates, clientVerifyPeerCertificates bool
|
var serverVerifyPeerCertificates, clientVerifyPeerCertificates bool
|
||||||
|
|
||||||
clientConfig := testConfig.Clone()
|
clientConfig := testConfig.Clone()
|
||||||
clientConfig.Time = func() time.Time { return time.Unix(1476984729, 0) }
|
clientConfig.Time = testTime
|
||||||
clientConfig.MaxVersion = version
|
clientConfig.MaxVersion = version
|
||||||
clientConfig.MinVersion = version
|
clientConfig.MinVersion = version
|
||||||
clientConfig.RootCAs = rootCAs
|
clientConfig.RootCAs = rootCAs
|
||||||
|
|||||||
@@ -1607,6 +1607,23 @@ var nameConstraintsTests = []nameConstraintsTest{
|
|||||||
leaf: leafSpec{sans: []string{"dns:.example.com"}},
|
leaf: leafSpec{sans: []string{"dns:.example.com"}},
|
||||||
expectedError: "cannot parse dnsName \".example.com\"",
|
expectedError: "cannot parse dnsName \".example.com\"",
|
||||||
},
|
},
|
||||||
|
// #86: URIs with IPv6 addresses with zones and ports are rejected
|
||||||
|
{
|
||||||
|
roots: []constraintsSpec{
|
||||||
|
{
|
||||||
|
ok: []string{"uri:example.com"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
intermediates: [][]constraintsSpec{
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
leaf: leafSpec{
|
||||||
|
sans: []string{"uri:http://[2006:abcd::1%25.example.com]:16/"},
|
||||||
|
},
|
||||||
|
expectedError: "URI with IP",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
|
func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
@@ -434,8 +435,10 @@ func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") ||
|
// netip.ParseAddr will reject the URI IPv6 literal form "[...]", so we
|
||||||
net.ParseIP(host) != nil {
|
// check if _either_ the string parses as an IP, or if it is enclosed in
|
||||||
|
// square brackets.
|
||||||
|
if _, err := netip.ParseAddr(host); err == nil || (strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]")) {
|
||||||
return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
|
return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -613,8 +613,9 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
|
|||||||
reqBodyClosed = false // have we closed the current req.Body?
|
reqBodyClosed = false // have we closed the current req.Body?
|
||||||
|
|
||||||
// Redirect behavior:
|
// Redirect behavior:
|
||||||
redirectMethod string
|
redirectMethod string
|
||||||
includeBody bool
|
includeBody = true
|
||||||
|
stripSensitiveHeaders = false
|
||||||
)
|
)
|
||||||
uerr := func(err error) error {
|
uerr := func(err error) error {
|
||||||
// the body may have been closed already by c.send()
|
// the body may have been closed already by c.send()
|
||||||
@@ -681,7 +682,12 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
|
|||||||
// in case the user set Referer on their first request.
|
// in case the user set Referer on their first request.
|
||||||
// If they really want to override, they can do it in
|
// If they really want to override, they can do it in
|
||||||
// their CheckRedirect func.
|
// their CheckRedirect func.
|
||||||
copyHeaders(req)
|
if !stripSensitiveHeaders && reqs[0].URL.Host != req.URL.Host {
|
||||||
|
if !shouldCopyHeaderOnRedirect(reqs[0].URL, req.URL) {
|
||||||
|
stripSensitiveHeaders = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copyHeaders(req, stripSensitiveHeaders)
|
||||||
|
|
||||||
// Add the Referer header from the most recent
|
// Add the Referer header from the most recent
|
||||||
// request URL to the new one, if it's not https->http:
|
// request URL to the new one, if it's not https->http:
|
||||||
@@ -744,7 +750,7 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) {
|
|||||||
// makeHeadersCopier makes a function that copies headers from the
|
// makeHeadersCopier makes a function that copies headers from the
|
||||||
// initial Request, ireq. For every redirect, this function must be called
|
// initial Request, ireq. For every redirect, this function must be called
|
||||||
// so that it can copy headers into the upcoming Request.
|
// so that it can copy headers into the upcoming Request.
|
||||||
func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
|
func (c *Client) makeHeadersCopier(ireq *Request) func(req *Request, stripSensitiveHeaders bool) {
|
||||||
// The headers to copy are from the very initial request.
|
// The headers to copy are from the very initial request.
|
||||||
// We use a closured callback to keep a reference to these original headers.
|
// We use a closured callback to keep a reference to these original headers.
|
||||||
var (
|
var (
|
||||||
@@ -758,8 +764,7 @@ func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preq := ireq // The previous request
|
return func(req *Request, stripSensitiveHeaders bool) {
|
||||||
return func(req *Request) {
|
|
||||||
// If Jar is present and there was some initial cookies provided
|
// If Jar is present and there was some initial cookies provided
|
||||||
// via the request header, then we may need to alter the initial
|
// via the request header, then we may need to alter the initial
|
||||||
// cookies as we follow redirects since each redirect may end up
|
// cookies as we follow redirects since each redirect may end up
|
||||||
@@ -796,12 +801,15 @@ func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
|
|||||||
// Copy the initial request's Header values
|
// Copy the initial request's Header values
|
||||||
// (at least the safe ones).
|
// (at least the safe ones).
|
||||||
for k, vv := range ireqhdr {
|
for k, vv := range ireqhdr {
|
||||||
if shouldCopyHeaderOnRedirect(k, preq.URL, req.URL) {
|
sensitive := false
|
||||||
|
switch CanonicalHeaderKey(k) {
|
||||||
|
case "Authorization", "Www-Authenticate", "Cookie", "Cookie2":
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
if !(sensitive && stripSensitiveHeaders) {
|
||||||
req.Header[k] = vv
|
req.Header[k] = vv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preq = req // Update previous Request with the current request
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -977,28 +985,23 @@ func (b *cancelTimerBody) Close() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldCopyHeaderOnRedirect(headerKey string, initial, dest *url.URL) bool {
|
func shouldCopyHeaderOnRedirect(initial, dest *url.URL) bool {
|
||||||
switch CanonicalHeaderKey(headerKey) {
|
// Permit sending auth/cookie headers from "foo.com"
|
||||||
case "Authorization", "Www-Authenticate", "Cookie", "Cookie2":
|
// to "sub.foo.com".
|
||||||
// Permit sending auth/cookie headers from "foo.com"
|
|
||||||
// to "sub.foo.com".
|
|
||||||
|
|
||||||
// Note that we don't send all cookies to subdomains
|
// Note that we don't send all cookies to subdomains
|
||||||
// automatically. This function is only used for
|
// automatically. This function is only used for
|
||||||
// Cookies set explicitly on the initial outgoing
|
// Cookies set explicitly on the initial outgoing
|
||||||
// client request. Cookies automatically added via the
|
// client request. Cookies automatically added via the
|
||||||
// CookieJar mechanism continue to follow each
|
// CookieJar mechanism continue to follow each
|
||||||
// cookie's scope as set by Set-Cookie. But for
|
// cookie's scope as set by Set-Cookie. But for
|
||||||
// outgoing requests with the Cookie header set
|
// outgoing requests with the Cookie header set
|
||||||
// directly, we don't know their scope, so we assume
|
// directly, we don't know their scope, so we assume
|
||||||
// it's for *.domain.com.
|
// it's for *.domain.com.
|
||||||
|
|
||||||
ihost := idnaASCIIFromURL(initial)
|
ihost := idnaASCIIFromURL(initial)
|
||||||
dhost := idnaASCIIFromURL(dest)
|
dhost := idnaASCIIFromURL(dest)
|
||||||
return isDomainOrSubdomain(dhost, ihost)
|
return isDomainOrSubdomain(dhost, ihost)
|
||||||
}
|
|
||||||
// All other headers are copied:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// isDomainOrSubdomain reports whether sub is a subdomain (or exact
|
// isDomainOrSubdomain reports whether sub is a subdomain (or exact
|
||||||
|
|||||||
@@ -1536,6 +1536,55 @@ func testClientCopyHeadersOnRedirect(t *testing.T, mode testMode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #70530: Once we strip a header on a redirect to a different host,
|
||||||
|
// the header should stay stripped across any further redirects.
|
||||||
|
func TestClientStripHeadersOnRepeatedRedirect(t *testing.T) {
|
||||||
|
run(t, testClientStripHeadersOnRepeatedRedirect)
|
||||||
|
}
|
||||||
|
func testClientStripHeadersOnRepeatedRedirect(t *testing.T, mode testMode) {
|
||||||
|
var proto string
|
||||||
|
ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
|
||||||
|
if r.Host+r.URL.Path != "a.example.com/" {
|
||||||
|
if h := r.Header.Get("Authorization"); h != "" {
|
||||||
|
t.Errorf("on request to %v%v, Authorization=%q, want no header", r.Host, r.URL.Path, h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Follow a chain of redirects from a to b and back to a.
|
||||||
|
// The Authorization header is stripped on the first redirect to b,
|
||||||
|
// and stays stripped even if we're sent back to a.
|
||||||
|
switch r.Host + r.URL.Path {
|
||||||
|
case "a.example.com/":
|
||||||
|
Redirect(w, r, proto+"://b.example.com/", StatusFound)
|
||||||
|
case "b.example.com/":
|
||||||
|
Redirect(w, r, proto+"://b.example.com/redirect", StatusFound)
|
||||||
|
case "b.example.com/redirect":
|
||||||
|
Redirect(w, r, proto+"://a.example.com/redirect", StatusFound)
|
||||||
|
case "a.example.com/redirect":
|
||||||
|
w.Header().Set("X-Done", "true")
|
||||||
|
default:
|
||||||
|
t.Errorf("unexpected request to %v", r.URL)
|
||||||
|
}
|
||||||
|
})).ts
|
||||||
|
proto, _, _ = strings.Cut(ts.URL, ":")
|
||||||
|
|
||||||
|
c := ts.Client()
|
||||||
|
c.Transport.(*Transport).Dial = func(_ string, _ string) (net.Conn, error) {
|
||||||
|
return net.Dial("tcp", ts.Listener.Addr().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := NewRequest("GET", proto+"://a.example.com/", nil)
|
||||||
|
req.Header.Add("Cookie", "foo=bar")
|
||||||
|
req.Header.Add("Authorization", "secretpassword")
|
||||||
|
res, err := c.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
if res.Header.Get("X-Done") != "true" {
|
||||||
|
t.Fatalf("response missing expected header: X-Done=true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Issue 22233: copy host when Client follows a relative redirect.
|
// Issue 22233: copy host when Client follows a relative redirect.
|
||||||
func TestClientCopyHostOnRedirect(t *testing.T) { run(t, testClientCopyHostOnRedirect) }
|
func TestClientCopyHostOnRedirect(t *testing.T) { run(t, testClientCopyHostOnRedirect) }
|
||||||
func testClientCopyHostOnRedirect(t *testing.T, mode testMode) {
|
func testClientCopyHostOnRedirect(t *testing.T, mode testMode) {
|
||||||
@@ -1702,43 +1751,39 @@ func testClientAltersCookiesOnRedirect(t *testing.T, mode testMode) {
|
|||||||
// Part of Issue 4800
|
// Part of Issue 4800
|
||||||
func TestShouldCopyHeaderOnRedirect(t *testing.T) {
|
func TestShouldCopyHeaderOnRedirect(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
header string
|
|
||||||
initialURL string
|
initialURL string
|
||||||
destURL string
|
destURL string
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"User-Agent", "http://foo.com/", "http://bar.com/", true},
|
|
||||||
{"X-Foo", "http://foo.com/", "http://bar.com/", true},
|
|
||||||
|
|
||||||
// Sensitive headers:
|
// Sensitive headers:
|
||||||
{"cookie", "http://foo.com/", "http://bar.com/", false},
|
{"http://foo.com/", "http://bar.com/", false},
|
||||||
{"cookie2", "http://foo.com/", "http://bar.com/", false},
|
{"http://foo.com/", "http://bar.com/", false},
|
||||||
{"authorization", "http://foo.com/", "http://bar.com/", false},
|
{"http://foo.com/", "http://bar.com/", false},
|
||||||
{"authorization", "http://foo.com/", "https://foo.com/", true},
|
{"http://foo.com/", "https://foo.com/", true},
|
||||||
{"authorization", "http://foo.com:1234/", "http://foo.com:4321/", true},
|
{"http://foo.com:1234/", "http://foo.com:4321/", true},
|
||||||
{"www-authenticate", "http://foo.com/", "http://bar.com/", false},
|
{"http://foo.com/", "http://bar.com/", false},
|
||||||
{"authorization", "http://foo.com/", "http://[::1%25.foo.com]/", false},
|
{"http://foo.com/", "http://[::1%25.foo.com]/", false},
|
||||||
|
|
||||||
// But subdomains should work:
|
// But subdomains should work:
|
||||||
{"www-authenticate", "http://foo.com/", "http://foo.com/", true},
|
{"http://foo.com/", "http://foo.com/", true},
|
||||||
{"www-authenticate", "http://foo.com/", "http://sub.foo.com/", true},
|
{"http://foo.com/", "http://sub.foo.com/", true},
|
||||||
{"www-authenticate", "http://foo.com/", "http://notfoo.com/", false},
|
{"http://foo.com/", "http://notfoo.com/", false},
|
||||||
{"www-authenticate", "http://foo.com/", "https://foo.com/", true},
|
{"http://foo.com/", "https://foo.com/", true},
|
||||||
{"www-authenticate", "http://foo.com:80/", "http://foo.com/", true},
|
{"http://foo.com:80/", "http://foo.com/", true},
|
||||||
{"www-authenticate", "http://foo.com:80/", "http://sub.foo.com/", true},
|
{"http://foo.com:80/", "http://sub.foo.com/", true},
|
||||||
{"www-authenticate", "http://foo.com:443/", "https://foo.com/", true},
|
{"http://foo.com:443/", "https://foo.com/", true},
|
||||||
{"www-authenticate", "http://foo.com:443/", "https://sub.foo.com/", true},
|
{"http://foo.com:443/", "https://sub.foo.com/", true},
|
||||||
{"www-authenticate", "http://foo.com:1234/", "http://foo.com/", true},
|
{"http://foo.com:1234/", "http://foo.com/", true},
|
||||||
|
|
||||||
{"authorization", "http://foo.com/", "http://foo.com/", true},
|
{"http://foo.com/", "http://foo.com/", true},
|
||||||
{"authorization", "http://foo.com/", "http://sub.foo.com/", true},
|
{"http://foo.com/", "http://sub.foo.com/", true},
|
||||||
{"authorization", "http://foo.com/", "http://notfoo.com/", false},
|
{"http://foo.com/", "http://notfoo.com/", false},
|
||||||
{"authorization", "http://foo.com/", "https://foo.com/", true},
|
{"http://foo.com/", "https://foo.com/", true},
|
||||||
{"authorization", "http://foo.com:80/", "http://foo.com/", true},
|
{"http://foo.com:80/", "http://foo.com/", true},
|
||||||
{"authorization", "http://foo.com:80/", "http://sub.foo.com/", true},
|
{"http://foo.com:80/", "http://sub.foo.com/", true},
|
||||||
{"authorization", "http://foo.com:443/", "https://foo.com/", true},
|
{"http://foo.com:443/", "https://foo.com/", true},
|
||||||
{"authorization", "http://foo.com:443/", "https://sub.foo.com/", true},
|
{"http://foo.com:443/", "https://sub.foo.com/", true},
|
||||||
{"authorization", "http://foo.com:1234/", "http://foo.com/", true},
|
{"http://foo.com:1234/", "http://foo.com/", true},
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
u0, err := url.Parse(tt.initialURL)
|
u0, err := url.Parse(tt.initialURL)
|
||||||
@@ -1751,10 +1796,10 @@ func TestShouldCopyHeaderOnRedirect(t *testing.T) {
|
|||||||
t.Errorf("%d. dest URL %q parse error: %v", i, tt.destURL, err)
|
t.Errorf("%d. dest URL %q parse error: %v", i, tt.destURL, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
got := Export_shouldCopyHeaderOnRedirect(tt.header, u0, u1)
|
got := Export_shouldCopyHeaderOnRedirect(u0, u1)
|
||||||
if got != tt.want {
|
if got != tt.want {
|
||||||
t.Errorf("%d. shouldCopyHeaderOnRedirect(%q, %q => %q) = %v; want %v",
|
t.Errorf("%d. shouldCopyHeaderOnRedirect(%q => %q) = %v; want %v",
|
||||||
i, tt.header, tt.initialURL, tt.destURL, got, tt.want)
|
i, tt.initialURL, tt.destURL, got, tt.want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,56 +10,56 @@ import "strings"
|
|||||||
// LocalhostCert is a PEM-encoded TLS cert with SAN IPs
|
// LocalhostCert is a PEM-encoded TLS cert with SAN IPs
|
||||||
// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT.
|
// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT.
|
||||||
// generated from src/crypto/tls:
|
// generated from src/crypto/tls:
|
||||||
// go run generate_cert.go --rsa-bits 2048 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
|
// go run generate_cert.go --rsa-bits 2048 --host 127.0.0.1,::1,example.com,*.example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
|
||||||
var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
|
var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||||
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
|
||||||
WkBKOclmOV2xlTVuPw==
|
rF7r4gUnKeC7mYIH1zypY7laskopiLFAfe96Kg==
|
||||||
-----END CERTIFICATE-----`)
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
// LocalhostKey is the private key for LocalhostCert.
|
// LocalhostKey is the private key for LocalhostCert.
|
||||||
var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
|
var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
|
||||||
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
|
||||||
ZboOWVe3icTy64BT3OQhmg==
|
jel6uj2FOP9g54s+GzlSVg/T
|
||||||
-----END RSA TESTING KEY-----`))
|
-----END RSA TESTING KEY-----`))
|
||||||
|
|
||||||
func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
|
func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
|
||||||
|
|||||||
@@ -3873,23 +3873,23 @@ func injectglist(glist *gList) {
|
|||||||
if glist.empty() {
|
if glist.empty() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
trace := traceAcquire()
|
|
||||||
if trace.ok() {
|
|
||||||
for gp := glist.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
|
|
||||||
trace.GoUnpark(gp, 0)
|
|
||||||
}
|
|
||||||
traceRelease(trace)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark all the goroutines as runnable before we put them
|
// Mark all the goroutines as runnable before we put them
|
||||||
// on the run queues.
|
// on the run queues.
|
||||||
head := glist.head.ptr()
|
head := glist.head.ptr()
|
||||||
var tail *g
|
var tail *g
|
||||||
qsize := 0
|
qsize := 0
|
||||||
|
trace := traceAcquire()
|
||||||
for gp := head; gp != nil; gp = gp.schedlink.ptr() {
|
for gp := head; gp != nil; gp = gp.schedlink.ptr() {
|
||||||
tail = gp
|
tail = gp
|
||||||
qsize++
|
qsize++
|
||||||
casgstatus(gp, _Gwaiting, _Grunnable)
|
casgstatus(gp, _Gwaiting, _Grunnable)
|
||||||
|
if trace.ok() {
|
||||||
|
trace.GoUnpark(gp, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if trace.ok() {
|
||||||
|
traceRelease(trace)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn the gList into a gQueue.
|
// Turn the gList into a gQueue.
|
||||||
|
|||||||
@@ -53,3 +53,28 @@ func combine4slice(p *[4][]byte, a, b, c, d []byte) {
|
|||||||
// arm64:-`.*runtime[.]gcWriteBarrier`
|
// arm64:-`.*runtime[.]gcWriteBarrier`
|
||||||
p[3] = d
|
p[3] = d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type S struct {
|
||||||
|
a, b string
|
||||||
|
c *int
|
||||||
|
}
|
||||||
|
|
||||||
|
var g1, g2 *int
|
||||||
|
|
||||||
|
func issue71228(dst *S, ptr *int) {
|
||||||
|
// Make sure that the non-write-barrier write.
|
||||||
|
// "sp.c = ptr" happens before the large write
|
||||||
|
// barrier "*dst = *sp". We approximate testing
|
||||||
|
// that by ensuring that two global variable write
|
||||||
|
// barriers aren't combined.
|
||||||
|
_ = *dst
|
||||||
|
var s S
|
||||||
|
sp := &s
|
||||||
|
//amd64:`.*runtime[.]gcWriteBarrier1`
|
||||||
|
g1 = nil
|
||||||
|
sp.c = ptr // outside of any write barrier
|
||||||
|
//amd64:`.*runtime[.]gcWriteBarrier1`
|
||||||
|
g2 = nil
|
||||||
|
//amd64:`.*runtime[.]wbMove`
|
||||||
|
*dst = *sp
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user