Compare commits

...

59 Commits

Author SHA1 Message Date
Gopher Robot
49860cf92a [release-branch.go1.24] go1.24.2
Change-Id: I8e6c68d7fff0519e2bdbc48f6dbf153bc40c02cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/661916
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
2025-04-01 09:11:46 -07:00
Austin Clements
f3a302358f [release-branch.go1.24] testing: detect a stopped timer in B.Loop
Currently, if the user stops the timer in a B.Loop benchmark loop, the
benchmark will run until it hits the timeout and fails.

Fix this by detecting that the timer is stopped and failing the
benchmark right away. We avoid making the fast path more expensive for
this check by "poisoning" the B.Loop iteration counter when the timer
is stopped so that it falls back to the slow path, which can check the
timer.

This causes b to escape from B.Loop, which is totally harmless because
it was already definitely heap-allocated. But it causes the
test/inline_testingbloop.go errorcheck test to fail. I don't think the
escape messages actually mattered to that test, they just had to be
matched. To fix this, we drop the debug level to -m=1, since -m=2
prints a lot of extra information for escaping parameters that we
don't want to deal with, and change one error check to allow b to
escape.

Fixes #72974.

Change-Id: I7d4abbb1ec1e096685514536f91ba0d581cca6b7
Reviewed-on: https://go-review.googlesource.com/c/go/+/659657
Auto-Submit: Austin Clements <austin@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/660558
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2025-03-26 09:44:03 -07:00
Austin Clements
1d755aa488 [release-branch.go1.24] testing: detect early return from B.Loop
Currently, if a benchmark function returns prior to B.Loop() returning
false, we'll report a bogus result. While there was no way to detect
this with b.N-style benchmarks, one way b.Loop()-style benchmarks are
more robust is that we *can* detect it.

This CL adds a flag to B that tracks if B.Loop() has finished and
checks it after the benchmark completes. If there was an early exit
(not caused by another error), it reports a B.Error.

For #72974.

Change-Id: I731c1350e6df938c0ffa08fcedc11dc147e78854
Reviewed-on: https://go-review.googlesource.com/c/go/+/659656
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Austin Clements <austin@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/660557
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2025-03-26 09:41:07 -07:00
Austin Clements
9204aca6c2 [release-branch.go1.24] testing: separate b.Loop counter from b.N
Currently, b.Loop uses b.N as the iteration count target. However,
since it updates the target as it goes, the behavior is quite
different from a b.N-style benchmark. To avoid user confusion, this CL
gives b.Loop a separate, unexported iteration count target. It ensures
b.N is 0 within the b.Loop loop to help catch misuses, and commits the
final iteration count to b.N only once the loop is done (as the
documentation states "After Loop returns false, b.N contains the total
number of iterations that ran, so the benchmark may use b.N to compute
other average metrics.")

Since there are now two variables used by b.Loop, we put them in an
unnamed struct. Also, we rename b.loopN to b.loop.i because this
variable tracks the current iteration index (conventionally "i"), not
the target (conventionally "n").

Unfortunately, a simple renaming causes B.Loop to be too large for the
inliner. Thus, we make one simplification to B.Loop to keep it under
the threshold. We're about to lean into that simplification anyway in
a follow-up CL, so this is just temporary.

For #72974.

Change-Id: Ide1c4f1b9ca37f300f3beb0e60ba6202331b183e
Reviewed-on: https://go-review.googlesource.com/c/go/+/659655
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Auto-Submit: Austin Clements <austin@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/660556
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2025-03-26 09:41:02 -07:00
Andy Pan
0ae3ca0a20 [release-branch.go1.24] runtime: explicitly disable async preempt for internal/runtime
Fixes #72115
For #71591
Relevant CL 560155

Change-Id: Iebc497d56b36d50c13a6dd88e7bca4578a03cf63
Reviewed-on: https://go-review.googlesource.com/c/go/+/654916
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
(cherry picked from commit 92a63bdfee9f8347df70293e5733661ae31ae285)
Reviewed-on: https://go-review.googlesource.com/c/go/+/660857
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2025-03-26 09:38:08 -07:00
Michael Pratt
dae59b594c [release-branch.go1.24] runtime: skip TestCgoCallbackPprof on platforms with broken profiling
CL 658035 added TestCgoCallbackPprof, which is consistently failing on
solaris. runtime/pprof maintains a list of platforms where CPU profiling
does not work properly. Since this test requires CPU profiling, skip the
this test on those platforms.

For #72870.
For #72876.
For #72872.

Change-Id: I6a6a636cbf6b16abcbba8771178fe1d001be9d9b
Reviewed-on: https://go-review.googlesource.com/c/go/+/658415
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/658416
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-03-25 11:51:27 -07:00
Michael Pratt
b7fd97ae3e [release-branch.go1.24] runtime: only set isExtraInC if there are no Go frames left
mp.isExtraInC is intended to indicate that this M has no Go frames at
all; it is entirely executing in C.

If there was a cgocallback to Go and then a cgocall to C, such that the
leaf frames are C, that is fine. e.g., traceback can handle this fine
with SetCgoTraceback (or by simply skipping the C frames).

However, we currently mismanage isExtraInC, unconditionally setting it
on return from cgocallback. This means that if there are two levels of
cgocallback, we end up running Go code with isExtraInC set.

1. C-created thread calls into Go function 1 (via cgocallback).
2. Go function 1 calls into C function 1 (via cgocall).
3. C function 1 calls into Go function 2 (via cgocallback).
4. Go function 2 returns back to C function 1 (returning via the remainder of cgocallback).
5. C function 1 returns back to Go function 1 (returning via the remainder of cgocall).
6. Go function 1 is now running with mp.isExtraInC == true.

The fix is simple; only set isExtraInC on return from cgocallback if
there are no more Go frames. There can't be more Go frames unless there
is an active cgocall out of the Go frames.

For #72870.
Fixes #72872.

Cq-Include-Trybots: luci.golang.try:go1.24-linux-amd64-longtest
Change-Id: I6a6a636c4e7ba75a29639d7036c5af3738033467
Reviewed-on: https://go-review.googlesource.com/c/go/+/658035
Reviewed-by: Cherry Mui <cherryyz@google.com>
Commit-Queue: Michael Pratt <mpratt@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit 577bb3d0ce576b2ca311e58dd942f189838b80fc)
Reviewed-on: https://go-review.googlesource.com/c/go/+/658056
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2025-03-25 11:51:24 -07:00
Rob Findley
311096a6a2 [release-branch.go1.24] go/types,types2: allocate the used* maps in initFiles
As described in the associated comment, we need to reallocate usedVars
and usedPkgNames in initFiles, as they are nilled out at the end of
Checker.Files, which may be called multiple times.

For #72122
For #72826

Change-Id: I9f6eb86e072d9d43a8720f6a5e86d827de6006a9
Reviewed-on: https://go-review.googlesource.com/c/go/+/655437
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
(cherry picked from commit fe9b292b11355af6b5f6e1d9247b88fa134657ed)
Reviewed-on: https://go-review.googlesource.com/c/go/+/657695
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@google.com>
2025-03-25 09:47:46 -07:00
Rob Findley
e9162e7e22 [release-branch.go1.24] go/types,types2: externalize used objects
The 'used' field on Var and PkgName is fundamentally an aspect of the
type checking pass: it records when objects are used, for the purposes
of reporting errors for unused variables or package names. While
expedient and performant, recording this information in the types.Object
instances themselves increases the memory footprint of type-checked
packages, and (as we saw in golang/go#71817) can lead to data races when
Objects are reused in follow-up type checking, such as is done with the
CheckExpr and Eval APIs.

Fix this by externalizing the 'used' information into two maps (one for
variables and one for packages) on the types.Checker, so that they are
garbage-collected after type checking, and cannot be a source of data
races.

Benchmarks showed essentially no change in performance.

For #72826

Change-Id: I40daeabe4ecaca3bcb494e2f1c62a04232098e49
Reviewed-on: https://go-review.googlesource.com/c/go/+/650796
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
(cherry picked from commit 9189921e4759055141b51fdbb8b7b69ee4fdd477)
Reviewed-on: https://go-review.googlesource.com/c/go/+/657675
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2025-03-25 09:45:16 -07:00
Junyang Shao
d107ee90df [release-branch.go1.24] testing: allow manual timer control in testing.B.Loop
Fixes #72934

Change-Id: I56610d2d11d151a8f95b6434bbedbfcd5c11c317
Reviewed-on: https://go-review.googlesource.com/c/go/+/658975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Commit-Queue: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/660555
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2025-03-25 08:50:14 -07:00
Jordan Liggitt
213f1566ee [release-branch.go1.24] internal/godebugs: fix changed version for winsymlink and winreadlinkvolume to 1.23
https://go.dev/doc/godebug#go-123 documents changes to winsymlink and
winreadlinkvolume in Go 1.23.

This fixes the registered "changed" minor version to Go 1.23,
so that defaults when building a Go 1.22 module are correct.

Fixes #72938

Change-Id: I5d5bf31ca04f9e95208fb0fdaad2232f9db653ff
Reviewed-on: https://go-review.googlesource.com/c/go/+/659035
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
(cherry picked from commit 2e749a645a6d03c7ac11bb172c4591564061b29e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/659036
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2025-03-24 15:37:49 -07:00
Damien Neil
ac1f5aa3d6 [release-branch.go1.24] net/http: reject newlines in chunk-size lines
Unlike request headers, where we are allowed to leniently accept
a bare LF in place of a CRLF, chunked bodies must always use CRLF
line terminators. We were already enforcing this for chunk-data lines;
do so for chunk-size lines as well. Also reject bare CRs anywhere
other than as part of the CRLF terminator.

Fixes CVE-2025-22871
Fixes #72011
For #71988

Change-Id: Ib0e21af5a8ba28c2a1ca52b72af8e2265ec79e4a
Reviewed-on: https://go-review.googlesource.com/c/go/+/652998
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit d31c805535f3fde95646ee4d87636aaaea66847b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/657056
2025-03-18 12:40:27 -07:00
Damien Neil
fd29397dca [release-branch.go1.24] net/http: don't modify caller's tls.Config.NextProtos
Clone the input slice before adjusting NextProtos
to add or remove "http/1.1" and "h2" entries,
so as not to modify a slice that the caller might be using.
(We clone the tls.Config that contains the slice, but
that's a shallow clone.)

For #72100
Fixes #72103

Change-Id: I9f228b8fb6f6f2ca5023179ec114929c002dbda9
Reviewed-on: https://go-review.googlesource.com/c/go/+/654875
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/657215
2025-03-17 14:37:18 -07:00
Alexandr Primak
4524009ba6 [release-branch.go1.24] runtime: Added usage example for the runtime.AddCleanup() function.
The existing description of the function lacks usage examples, which makes it difficult to understand, so I added one.

There is no open issue about this, since the implementation seems trivial.

For #72795
Fixes #72796

Change-Id: I96b29f0b21d1c7fda04128239633c8a2fc36fef2
Reviewed-on: https://go-review.googlesource.com/c/go/+/649995
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit 4c75671871af56fa68076ee3741780e52726ec82)
Reviewed-on: https://go-review.googlesource.com/c/go/+/656815
Reviewed-by: Cherry Mui <cherryyz@google.com>
2025-03-17 14:36:28 -07:00
Filippo Valsorda
bd1bc8a6e7 [release-branch.go1.24] crypto/tls: allow P-521 in FIPS 140-3 mode and Go+BoringCrypto
Partially reverts CL 587296, restoring the Go+BoringCrypto 1.23 behavior
in terms of supported curves.

Updates #71757
Fixes #72823

Change-Id: I6a6a465651a8407056fd0fae091d10a945b37997
Reviewed-on: https://go-review.googlesource.com/c/go/+/657135
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: David Chase <drchase@google.com>
2025-03-17 14:33:52 -07:00
David Chase
c2a34bedee [release-branch.go1.24] cmd/compile: use inline-Pos-based recursion test
Look at the inlining stack of positions for a call site,
if the line/col/file of the call site appears in that
stack, do not inline.  This subsumes all the other
recently-added recursive inlining checks, but they are
left in to make this easier+safer to backport.

Fixes #72822

Change-Id: I0f487bb0d4c514015907c649312672b7be464abd
Reviewed-on: https://go-review.googlesource.com/c/go/+/655155
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
(cherry picked from commit cad4dca518a3a984bfd6b19ee304a59f51937fd8)
Reviewed-on: https://go-review.googlesource.com/c/go/+/657075
2025-03-12 13:50:58 -07:00
Cuong Manh Le
0ace2d8aca [release-branch.go1.24] cmd/compile: fix out of memory when inlining closure
CL 629195 strongly favor closure inlining, allowing closures to be
inlined more aggressively.

However, if the closure body contains a call to a function, which itself
is one of the call arguments, it causes the infinite inlining.

Fixing this by prevent this kind of functions from being inlinable.

Fixes #72067

Change-Id: I5fb5723a819b1e2c5aadb57c1023ec84ca9fa53c
Reviewed-on: https://go-review.googlesource.com/c/go/+/654195
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/654517
Commit-Queue: Junyang Shao <shaojunyang@google.com>
Auto-Submit: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
2025-03-05 13:27:11 -08:00
Junyang Shao
e4119e9b74 [release-branch.go1.24] all: updates vendored x/net
This is to update module version to the fixed x/net.

For #71984

Change-Id: I7d50e302e8ba7d3ee28df2669fc16f19c12cf088
Reviewed-on: https://go-review.googlesource.com/c/go/+/654795
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
2025-03-04 12:31:16 -08:00
Gopher Robot
339c903a75 [release-branch.go1.24] go1.24.1
Change-Id: I774fcee39151f830ad58fd1677239bc0207c6679
Reviewed-on: https://go-review.googlesource.com/c/go/+/654319
Auto-Submit: Gopher Robot <gobot@golang.org>
Auto-Submit: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-03-04 11:27:08 -08:00
Damien Neil
334de7982f [release-branch.go1.24] all: updated vendored x/net with security fix
6ed00d0 [internal-branch.go1.24-vendor] proxy, http/httpproxy: do not mismatch IPv6 zone ids against hosts

Fixes CVE-2025-22870
For #71986

Change-Id: I7bda0825f1a9470b0708714d9cc32b5eae212f8b
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2121
Reviewed-by: Neal Patel <nealpatel@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/654715
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
2025-03-04 10:41:47 -08:00
Ian Lance Taylor
5d6920842b [release-branch.go1.24] runtime/cgo: avoid errors from -Wdeclaration-after-statement
CL 652181 accidentally missed this iPhone only code.

For #71961
For #71963

Change-Id: I567f8bb38958907442e69494da330d5199d11f54
Reviewed-on: https://go-review.googlesource.com/c/go/+/653137
Commit-Queue: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-02-26 14:41:34 -08:00
Keith Randall
949eae84df [release-branch.go1.24] cmd/compile: don't pull constant offsets out of pointer arithmetic
This could lead to manufacturing a pointer that points outside
its original allocation.

Bug was introduced in CL 629858.

Fixes #71938

Change-Id: Ia86ab0b65ce5f80a8e0f4f4c81babd07c5904f8d
Reviewed-on: https://go-review.googlesource.com/c/go/+/652078
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit 8b8bff7bb29210db868306cd07a03fb15e247b2f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/652855
2025-02-26 12:15:08 -08:00
Michael Anthony Knyszek
0bfde51e0d [release-branch.go1.24] runtime: document that cleanups can run concurrently with each other
For #71825.
Fixes #71955.

Change-Id: I25af19eb72d75f13cf661fc47ee5717782785326
Reviewed-on: https://go-review.googlesource.com/c/go/+/652637
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Keith Randall <khr@google.com>
2025-02-26 12:04:21 -08:00
Ian Lance Taylor
45a52718e3 [release-branch.go1.24] runtime/cgo: avoid errors from -Wdeclaration-after-statement
It's used by the SWIG CI build, at least, and it's an easy fix.

Fixes #71963
For #71961

Change-Id: Id21071a5aef216b35ecf0e9cd3e05d08972d92fe
Reviewed-on: https://go-review.googlesource.com/c/go/+/652181
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
(cherry picked from commit 76c70282538bf4cccd6f98b5b26df7f5a7f2cebd)
Reviewed-on: https://go-review.googlesource.com/c/go/+/652936
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2025-02-26 11:46:33 -08:00
qiulaidongfeng
7f375e2c22 [release-branch.go1.24] reflect: let Value.Seq return the iteration value correct type
Fixes #71916
For #71905

Change-Id: I50a418f8552e071c6e5011af5b9accc7d41548d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/651855
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
(cherry picked from commit 194696f1d1f6e5609f96d0fb0192595e7e0f5b90)
Reviewed-on: https://go-review.googlesource.com/c/go/+/652895
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
2025-02-26 11:11:37 -08:00
Zxilly
4070531920 [release-branch.go1.24] syscall: disable O_DIRECTORY on Windows for js/wasm
O_DIRECTORY is not available on all platforms, as described at

https://nodejs.org/docs/latest/api/fs.html#file-open-constants .

On Windows, only O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR,
O_TRUNC, O_WRONLY, and UV_FS_O_FILEMAP are available.

For #71758.
Fixes #71977.

Change-Id: Iacc890ba9a30dcd75eb746ec324fa0c3e368048e
GitHub-Last-Rev: a0160e8fc82583c4f903ae165fe9f204896cf56d
GitHub-Pull-Request: golang/go#71770
Reviewed-on: https://go-review.googlesource.com/c/go/+/650015
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@golang.org>
(cherry picked from commit ad8b33002bb5cb0c910694339e1cc6c75f781c5a)
Reviewed-on: https://go-review.googlesource.com/c/go/+/652835
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-02-26 10:08:02 -08:00
Michael Anthony Knyszek
5ffdb9c88b [release-branch.go1.24] reflect: correctly handle method values in Seq
Currently method values aren't correctly handled in Seq because we call
canRangeFunc on the reciever type, not the method value type, when we're
handling a method value. reflect.Value.Type has the logic to obtain the
method value type from the Value.

This change slightly refactors reflect.Value.Type into a separate
function so we can obtain the correct type as an abi.Type and pass it
off to canRangeFunc (and canRangeFunc2).

For #71874.
Fixes #71876.

Change-Id: Ie62dfca2a84b8f2f816bb87ff1ed1a58a7bb8122
Reviewed-on: https://go-review.googlesource.com/c/go/+/651416
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit d93f6df0cc4f33127ef76fa994edd54d7726d0a9)
Reviewed-on: https://go-review.googlesource.com/c/go/+/651515
2025-02-26 09:53:54 -08:00
Michael Pratt
becc17ebcd [release-branch.go1.24] runtime: use WCLONE when waiting on pidfd test child
As of CL 650835, the pidfd test child no longer sends SIGCHLD on exit.
Per clone(2), "If [the child termination] signal is specified as
anything other than SIGCHLD, then the parent process must specify the
__WALL or __WCLONE options when waiting for the child with wait(2)."

Align with this requirement.

For #71849.
For #71828.

Change-Id: I6a6a636c739e4a59abe1533fe429a433e8588939
Reviewed-on: https://go-review.googlesource.com/c/go/+/651415
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit e1e65ae3ee5f977c31f3651233cc7ff2a0b579ca)
Reviewed-on: https://go-review.googlesource.com/c/go/+/651476
2025-02-26 09:45:51 -08:00
Ian Lance Taylor
d418e224ae [release-branch.go1.24] syscall: don't send child signal when testing pidfd
Avoid a spurious SIGCHLD the first time we start a process.

For #71828
Fixes #71849

Change-Id: I744100d21bf6aaaaafc99bc5eec9f9f807a50682
Reviewed-on: https://go-review.googlesource.com/c/go/+/651035
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-02-26 09:45:47 -08:00
Jorropo
456eaf5c29 [release-branch.go1.24] cmd/compile: don't report newLimit discovered when unsat happens multiple times
Fixes #71855

Change-Id: I696fcb8fc8c0c2e5e5ae6ab50596f6bdb9b7d498
Reviewed-on: https://go-review.googlesource.com/c/go/+/650975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
(cherry picked from commit 00635de759b38610dd86f60074856367d6a1ceaa)
Reviewed-on: https://go-review.googlesource.com/c/go/+/652179
Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-02-26 09:44:53 -08:00
Michael Pratt
e4ef83383e [release-branch.go1.24] debug/buildinfo: base64-encode test binaries
Overzealous security scanners don't like the Go 1.17 binary because they
think it has every 1.17 security vulnerability. base64-encode the binary
to hide from them.

I've also extended the instructions to make the binary easier to
reproduce.

Since we do the Go binary, we might as well do the C binary too, as it
apparently makes some virus scanners unhappy.

Fixes #71858.
For #71753.
For #71734.
For #71821.

Change-Id: I6a6a636cccbf5312522f52f27f74eded64048fb7
Reviewed-on: https://go-review.googlesource.com/c/go/+/651175
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit af00524a6c1660e6a66fd975921df40ac1c3a415)
Reviewed-on: https://go-review.googlesource.com/c/go/+/651235
2025-02-26 09:44:08 -08:00
khr@golang.org
4e6d3468cc [release-branch.go1.24] cmd/compile: ensure we don't reuse temporary register
Before this CL, we could use the same register for both a temporary
register and for moving a value in the output register out of the way.

Fixes #71904

Change-Id: Iefbfd9d4139136174570d8aadf8a0fb391791ea9
Reviewed-on: https://go-review.googlesource.com/c/go/+/651221
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
(cherry picked from commit cc16fb52e6f1eafaee468f8563525ec391e016f5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/652178
2025-02-26 09:43:51 -08:00
Ian Lance Taylor
f5c388313f [release-branch.go1.24] internal/godebugs: add fips140 as an opaque godebug setting
This permits using "godebug fips140=on" in go.mod and
using "//go:debug fips140=on" in the main package.

Change code references to the godebug setting to remove the #
which is no longer required.

For #71666
Fixes #71745

Change-Id: I3a60ecc55b03848dadd6d431eb43137b6df6568b
Reviewed-on: https://go-review.googlesource.com/c/go/+/649495
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
(cherry picked from commit 2b43ce0a9d5825d66aa42a6fa9076f2fb9c181ea)
Reviewed-on: https://go-review.googlesource.com/c/go/+/650675
Commit-Queue: Ian Lance Taylor <iant@google.com>
2025-02-25 21:52:03 -08:00
David Chase
af236716b2 [release-branch.go1.24] cmd/compile, runtime: use deferreturn as target PC for recover from deferrangefunc
The existing code for recover from deferrangefunc was broken in
several ways.

1. the code following a deferrangefunc call did not check the return
value for an out-of-band value indicating "return now" (i.e., recover
was called)

2. the returned value was delivered using a bespoke ABI that happened
to match on register-ABI platforms, but not on older stack-based
ABI.

3. the returned value was the wrong width (1 word versus 2) and
type/value(integer 1, not a pointer to anything) for deferrangefunc's
any-typed return value (in practice, the OOB value check could catch
this, but still, it's sketchy).

This -- using the deferreturn lookup method already in place for
open-coded defers -- turned out to be a much-less-ugly way of
obtaining the desired transfer of control for recover().

TODO: we also could do this for regular defer, and delete some code.

Fixes #71840

Change-Id: If7d7ea789ad4320821aab3b443759a7d71647ff0
Reviewed-on: https://go-review.googlesource.com/c/go/+/650476
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/651497
2025-02-21 18:58:02 -08:00
Ian Lance Taylor
0f7b7600fb [release-branch.go1.24] doc/godebug: mention GODEBUG=fips140
For #71666
For #71745

Change-Id: Ice816cf2943c5b6660f05934b4c7ca38545714b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/648520
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Commit-Queue: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
(cherry picked from commit 5f65e5cb56f98381970de5485e704f3c7e20ca9a)
Reviewed-on: https://go-review.googlesource.com/c/go/+/650596
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2025-02-19 13:59:08 -08:00
Cuong Manh Le
eb58df7dbf [release-branch.go1.24] cmd/compile: avoid infinite recursion when inlining closures
CL 630696 changes budget for once-called closures, making them more
inlinable. However, when recursive inlining involve both the closure and
its parent, the inliner goes into an infinite loop:

	parent (a closure)  -> closure -> parent -> ...

The problem here dues to the closure name mangling, causing the inlined
checking condition failed, since the closure name affects how the
linker symbol generated.

To fix this, just prevent the closure from inlining its parent into
itself, avoid the infinite inlining loop.

Fixes #71829

Change-Id: Ib27626d70f95e5f1c24a3eb1c8e6c3443b7d90c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/649656
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/650555
2025-02-19 13:49:27 -08:00
qmuntal
30f4d9e117 [release-branch.go1.24] syscall: don't truncate newly created files on Windows
There is no need for syscall.OpenFile to truncate newly created files.
Some special Windows files, like the NUL device, can't be
truncated, so we should avoid truncating unless it is really necessary.

For #71752
Fixes #71836

Change-Id: I8238048594f706f6a5281053d55cfe3dc898828d
Reviewed-on: https://go-review.googlesource.com/c/go/+/650276
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 4267fd389e941cf197cc3890cc42e474866c0d30)
Reviewed-on: https://go-review.googlesource.com/c/go/+/650597
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
2025-02-19 10:46:24 -08:00
Paul Murphy
bb0e5c2045 [release-branch.go1.24] runtime: fix usleep on s390x/linux
The timespec argument takes the remainder in nanoseconds, not
microseconds. Convert the remaining time to nsec.

Fixes #71728

Change-Id: I36cbbe3a088830c5e3afcc9516ef42e96ee21268
Reviewed-on: https://go-review.googlesource.com/c/go/+/648915
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Axel Busch <axel.busch@ibm.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Vishwanatha HD <vishwanatha.hd@ibm.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/649375
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-02-19 09:14:47 -08:00
段仪
cd0e528d3d [release-branch.go1.24] runtime: add some linknames back for github.com/bytedance/sonic
Add some linknames back, therefore sonic (github.com/bytedance/sonic) can work correctly.

For #71672
Fixes #71705

Change-Id: Iae86c837d8a714855106a26766aa08b128e17e58
GitHub-Last-Rev: 4de0a4871766f9e7763394fdcdcaa9d683e97987
GitHub-Pull-Request: golang/go#71673
Reviewed-on: https://go-review.googlesource.com/c/go/+/650375
Auto-Submit: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-02-19 09:12:30 -08:00
Quan Tong
80e2e474b8 [release-branch.go1.24] cmd/go: initialize req.Header when loading git credential
Fixes #71687

Change-Id: I3d733a50b4451dfb571aba91a28387ba9e0614dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/647615
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
(cherry picked from commit 58834c3ee08ea85b764c7cc3318ce7a68ea92cbd)
Reviewed-on: https://go-review.googlesource.com/c/go/+/648936
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2025-02-12 11:16:33 -08:00
Gopher Robot
3901409b5d [release-branch.go1.24] go1.24.0
Change-Id: I98457f219e75fb99233804d15c8b9577ee3d4a24
Reviewed-on: https://go-review.googlesource.com/c/go/+/648555
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Bypass: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-02-11 09:55:39 -08:00
Cherry Mui
35c0ea22a9 [release-branch.go1.24] bytes: use "subslice" instead of "substring" in doc comments
The bytes package iterators return subslices, not substrings.

Updates #61901.

Change-Id: Ida91d3e33a0f178edfe9a267861adf4f13f9a965
Reviewed-on: https://go-review.googlesource.com/c/go/+/647875
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit ff27d270c9f95178f9749bc8e1f15957b1c1d5b3)
Reviewed-on: https://go-review.googlesource.com/c/go/+/648095
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Bypass: Cherry Mui <cherryyz@google.com>
2025-02-10 11:50:28 -08:00
Michael Anthony Knyszek
6d399e9da6 [release-branch.go1.24] os: hide SetFinalizer from users of Root
Currently Root embeds a root and calls SetFinalizer on &r.root. This
sets the finalizer on the outer root, which is visible to users of
os.Root, and thus they can mutate the finalizer attached to it.

This change modifies Root to not embed its inner root, but rather to
refer to it by pointer. This allows us to set the finalizer on this
independent inner object, preventing users of os.Root from changing the
finalizer. This follows the same pattern as os.File's finalizer.

Fixes #71617.

Change-Id: Ibd199bab1b3c877d5e12ef380fd4647b4e10221f
Reviewed-on: https://go-review.googlesource.com/c/go/+/647876
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit a704d39b29dfc21599f644909c0f98bbfa745cb4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/648135
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2025-02-10 10:48:31 -08:00
thepudds
b7b4c60585 [release-branch.go1.24] weak: prevent unsafe conversions using weak pointers
Prevent conversions between Pointer types,
like we do for sync/atomic.Pointer.

Fixes #71583

Change-Id: I20e83106d8a27996f221e6cd9d52637b0442cea4
Reviewed-on: https://go-review.googlesource.com/c/go/+/647195
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit 8163ea1458763aa38fa9197e479bd30cb0145429)
Reviewed-on: https://go-review.googlesource.com/c/go/+/647435
Reviewed-by: Carlos Amedee <carlos@golang.org>
TryBot-Bypass: Cherry Mui <cherryyz@google.com>
2025-02-06 13:53:01 -08:00
Gopher Robot
18068cb96a [release-branch.go1.24] go1.24rc3
Change-Id: Ib3e93a2ea07a0ef1ce0989143d03c765ede8cc99
Reviewed-on: https://go-review.googlesource.com/c/go/+/646936
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Bypass: Cherry Mui <cherryyz@google.com>
Auto-Submit: Gopher Robot <gobot@golang.org>
2025-02-05 12:35:01 -08:00
Roland Shoemaker
c43ac38b3b [release-branch.go1.24] Revert "cmd/go/internal/work: allow @ character in some -Wl, linker flags on darwin"
This reverts commit e3cd55e9d293d519e622e788e902f372dc30338a.

This change introduced a security issue as @ flags are first resolved as
files by the darwin linker, before their meaning as flags, allowing the
flag filtering logic to be entirely bypassed.

Thanks to Juho Forsén for reporting this issue.

Fixes #71476
Fixes CVE-2025-22867

Change-Id: I3a4b4a6fc534de105d930b8ed5b9900bc94b0c4e
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1900
Reviewed-by: Russ Cox <rsc@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit cc0d725a4168f234ef38859b2d951a50a8fd94b5)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1940
Reviewed-by: Neal Patel <nealpatel@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/646995
Reviewed-by: Carlos Amedee <carlos@golang.org>
TryBot-Bypass: Cherry Mui <cherryyz@google.com>
2025-02-05 11:57:13 -08:00
Carlos Amedee
4241f582fc [release-branch.go1.24] all: merge master (37f27fb) into release-branch.go1.24
Conflicts:

- src/cmd/go/testdata/script/goauth_netrc.txt

Merge List:

+ 2025-01-31 37f27fbecd cmd/go: enable fips test and fix caching bug
+ 2025-01-31 77d20838e9 cmd: update golang.org/x/tools to CL 645697, and revendor
+ 2025-01-30 ce7ea0a6a5 cmd/go: refine GOAUTH user parsing to be more strict
+ 2025-01-29 e81f715515 lib/fips140: freeze v1.0.0 FIPS 140 module zip file
+ 2025-01-29 4f48ad5c6b cmd/link/internal/loader: fix linknames from FIPS 140 frozen tree
+ 2025-01-29 1f58ad5d6d Revert "os: employ sendfile(2) for file-to-file copying on Linux when needed"
+ 2025-01-28 90ec9996cb crypto/pbkdf2: add keyLength limit
+ 2025-01-28 62cd7cb6cd crypto/hkdf: check error in TestFIPSServiceIndicator
+ 2025-01-28 7764c502e2 crypto/internal/sysrand: skip TestNoGetrandom without cgo
+ 2025-01-28 50455385b0 internal/coverage: fix bug in text-format coverage output with multiple packages
+ 2025-01-28 28d389ef30 internal/godebug: check error from os.ReadFile in test
+ 2025-01-28 8071f2a169 runtime: mapiter linkname compatibility layer
+ 2025-01-28 78e6f2a1c8 runtime: rename mapiterinit and mapiternext
+ 2025-01-28 4ebd5bf855 internal/goexperiment: update location of baseline experiment in comment
+ 2025-01-27 f8937cb625 archive/zip, archive/tar: writer appends slash to directory names
+ 2025-01-27 11e08d9d96 strconv: adjust comment so that gofmt doesn't mung it
+ 2025-01-27 b9872221cd crypto/internal/fips140/rsa: avoid CAST unsetting the service indicator
+ 2025-01-27 3f791c8dfb crypto/internal/fips140/aes: set FIPS 140 service indicator for CTR and CBC
+ 2025-01-27 e0aeee82f3 crypto/ecdsa: avoid needless ScalarBaseMult in s390x
+ 2025-01-27 f70aa3824b cmd/go: do not call base.fatal for an unset HOME for GOAUTH=netrc
+ 2025-01-27 475e08349d Revert "runtime: Check LSE support on ARM64 at runtime init"
+ 2025-01-27 e2e700f8b1 crypto/internal/boring: keep ECDH public key alive during cgo calls
+ 2025-01-22 608acff847 go/types: avoid importer.Default
+ 2025-01-22 9d21ef3bd4 runtime: fix the equality check in AddCleanup
+ 2025-01-22 5a46b17b5f os: force a goroutine to be scheduled on WASM
+ 2025-01-22 6fc23a3cff crypto/internal/fips140/nistec: make p256NegCond constant time on ppc64le
+ 2025-01-22 70b603f4d2 go/importer: document limitations of this API
+ 2025-01-21 f6d17c5400 net/http: update bundled golang.org/x/net/http2 [generated]
+ 2025-01-21 3aa7c5ef01 testing: fix reference to B.N in docstring
+ 2025-01-20 3f4164f508 runtime: delete out of date comment
+ 2025-01-17 40b3c0e58a internal/coverage: refactor EmitTextual in preparation for bugfix
+ 2025-01-17 87023bb27f go/types, types2: ensure deterministic output when reporting an init cycle
+ 2025-01-17 80bf7d83ed go/types, types2: remove superfluous assertion (fix build)
+ 2025-01-16 1a93e4a2cf lib/time: update to 2025a/2025a
+ 2025-01-16 0b632d26b9 cmd/internal/obj/wasm, runtime: detect wasmexport call before runtime initialization
+ 2025-01-16 6a4effa08b crypto/x509: avoid panic when parsing partial PKCS#1 private keys
+ 2025-01-16 139d6eedae cmd/go: restore netrc preferences for GOAUTH and fix domain lookup
+ 2025-01-16 2b2314e9f6 crypto/x509: properly check for IPv6 hosts in URIs
+ 2025-01-16 6783377295 net/http: persist header stripping across repeated redirects
+ 2025-01-14 368a9ec998 encoding/json: cleanup tests
+ 2025-01-14 bd80d8956f cmd/go/internal/modfetch: do not trust server to send all tags in shallow fetch
+ 2025-01-14 4fa61d6f9c cmd/api: report error in test instead of crashing
+ 2025-01-14 c5e205e928 internal/runtime/maps: re-enable some tests
+ 2025-01-14 befc43655b testing/fstest: fix function name and comment
+ 2025-01-14 c83f2ca4b3 cmd/dist: ignore packages with no Go files in BenchmarkAll
+ 2025-01-13 6da16013ba cmd/go: check go version when parsing go.mod fails
+ 2025-01-13 de9fdc7b71 syscall/js: adjust comments to that gofmt does not change them
+ 2025-01-13 17ed215958 go/types, types2: don't panic when instantiating generic alias with wrong number of type arguments
+ 2025-01-13 c53307c3fd spec: fix grammar issue
+ 2025-01-13 47a56b2b6d encoding/json: add cases to TestUnmarshal for fatal syntactic errors
+ 2025-01-13 7bb192a1c5 encoding/json: always check resulting Go value for unmarshaling
+ 2025-01-12 44a6f817ea cmd/compile: fix write barrier coalescing
+ 2025-01-10 19e923182e crypto/internal/fips140test: add hmac DRBG ACVP tests
+ 2025-01-10 7255b94920 crypto/internal/fips140test: add ML-KEM ACVP tests
+ 2025-01-09 932ec2be8d crypto/rsa: fix GenerateKey flakes for toy-sized keys
+ 2025-01-09 d0c9142ce3 runtime/pprof: hide map runtime frames from heap profiles
+ 2025-01-09 c7c4420ae4 cmd/go: clarify GODEBUG in go help environment
+ 2025-01-09 c6ab13fc43 cmd/go/internal/mmap: reslice to file size on Windows
+ 2025-01-09 f5a89dff67 crypto: fix fips140=only detection of SHA-3
+ 2025-01-08 4225c6cb37 encoding/json: improve fidelity of TestUnmarshal for Numbers
+ 2025-01-08 c87a6f932e crypto/mlkem: merge mlkem768.go and mlkem1024.go to improve godoc
+ 2025-01-08 f57a3a7c04 crypto/mlkem: add example and improve docs
+ 2025-01-08 c9afcbade7 go/types, types2: require iterator yield to return bool (work-around)
+ 2025-01-08 54693a81fd crypto/md5,crypto/sha1: apply fips140=only to Write and Sum, not New
+ 2025-01-08 0cdf8c7a8c crypto/ecdsa: apply fips140=only to deterministic ECDSA hash
+ 2025-01-08 4640e92af7 crypto/rsa: apply fips140=only to opts.Hash in SignPSS

Change-Id: I443d8d9433e7f504905b60652d3fcd975e5f674b
2025-01-31 12:45:08 -05:00
Gopher Robot
8a4c24f9bb [release-branch.go1.24] go1.24rc2
Change-Id: I37362fe37c47078c17f3f6f610d8ca7664985bd0
Reviewed-on: https://go-review.googlesource.com/c/go/+/643157
Auto-Submit: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2025-01-16 12:13:48 -08:00
Filippo Valsorda
3de5aca7d0 [release-branch.go1.24] crypto/x509: avoid panic when parsing partial PKCS#1 private keys
These keys are off-spec, but have historically been accepted by
ParsePKCS1PrivateKey.

Thanks to Philippe Antoine (Catena cyber) for reporting this issue.

Fixes #71216
Fixes CVE-2025-22865

Change-Id: I6a6a46564156fa32e29e8d6acbec3fbac47c7352
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1820
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
(cherry picked from commit 36c6c8b6957e155770461fd710aea9477ef3bc88)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1841
Reviewed-on: https://go-review.googlesource.com/c/go/+/643102
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-01-16 11:36:09 -08:00
Sam Thanawalla
8336dfde70 [release-branch.go1.24] cmd/go: restore netrc preferences for GOAUTH and fix domain lookup
Store netrc lines into the credential map backward so that earlier lines
take priority over later lines. This matches Go 1.23 netrc lookup which
stopped at the first match it found.
Additionally, this fixes a security issue related to domain parsing
which could have allowed servers to read credentials belonging to other
servers. The fix was to switch from using path.Dir(currentPrefix) to
strings.Cut(currentPrefix, "/")

Thanks to Juho Forsén of Mattermost for reporting this issue.

Fixes #71249
Fixes CVE-2024-45340

Change-Id: I175a00d6d7f4d31c9e4d79b7cf1c2a0ad35b2781
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1781
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 76833d221aa3ccc978b6f41bd24e26babf771375)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1840
Reviewed-on: https://go-review.googlesource.com/c/go/+/643101
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-01-16 11:36:07 -08:00
Damien Neil
6b60550504 [release-branch.go1.24] net/http: persist header stripping across repeated redirects
When an HTTP redirect changes the host of a request, we drop
sensitive headers such as Authorization from the redirected request.
Fix a bug where a chain of redirects could result in sensitive
headers being sent to the wrong host:

  1. request to a.tld with Authorization header
  2. a.tld redirects to b.tld
  3. request to b.tld with no Authorization header
  4. b.tld redirects to b.tld
  3. request to b.tld with Authorization header restored

Thanks to Kyle Seely for reporting this issue.

For #70530
Fixes #71212
Fixes CVE-2024-45336

Change-Id: Ia58a2e10d33d6b0cc7220935e771450e5c34de72
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1641
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Commit-Queue: Roland Shoemaker <bracewell@google.com>
(cherry picked from commit 2889169b87a61f1218a02994feb80fd3d8bfa87c)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1766
Reviewed-on: https://go-review.googlesource.com/c/go/+/643100
Auto-Submit: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-01-16 11:36:03 -08:00
Roland Shoemaker
468fad45a2 [release-branch.go1.24] crypto/x509: properly check for IPv6 hosts in URIs
When checking URI constraints, use netip.ParseAddr, which understands
zones, unlike net.ParseIP which chokes on them. This prevents zone IDs
from mistakenly satisfying URI constraints.

Thanks to Juho Forsén of Mattermost for reporting this issue.

For #71156
Fixes #71209
Fixes CVE-2024-45341

Change-Id: Iecac2529f3605382d257996e0fb6d6983547e400
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1700
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 22ca55d396ba801e6ae9b2bd67a059fcb30562fd)
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1800
Commit-Queue: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/643099
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
2025-01-16 11:08:59 -08:00
Michael Pratt
e06b6fc58d [release-branch.go1.24] all: merge master (e966a27) into release-branch.go1.24
Merge List:

+ 2025-01-08 e966a2773c crypto/internal/fips140/drbg: avoid global lock on rand state

Change-Id: I1ca8f6bf2ba14ff3d5c4183a26cbd51ac20dad0a
2025-01-08 14:01:58 -05:00
Michael Pratt
b3799ba634 [release-branch.go1.24] all: merge master (9a44df6) into release-branch.go1.24
Merge List:

+ 2025-01-08 9a44df6675 cmd/go/testdata/script: fix TestScript/env_gocacheprog on Windows
+ 2025-01-08 f025d19e7b runtime: hold traceAcquire across casgstatus in injectglist
+ 2025-01-08 1e9835f5b1 internal/sync: fix typo of panic message
+ 2025-01-07 39f2032c17 testing/synctest: add some examples
+ 2025-01-07 b50ccef67a cmd/go/internal/modindex: don't write index entry if file open
+ 2025-01-07 b2aa18b96c cmd/internal/hash: stop using md5, sha1
+ 2025-01-07 d93b549f05 cmd/go/internal/cache: handle cacheprog not responding to close
+ 2025-01-07 d62154db83 weak: don't panic when calling Value on a zero Pointer
+ 2025-01-07 9d0772b23e cmd/compile/internal/syntax: add test case for invalid label use
+ 2025-01-07 1d20bce981 go/types, types2: expand documentation for Info.Types map
+ 2025-01-07 a9bd6239a4 cmd/go/internal/env: add GOCACHEPROG to go env output
+ 2025-01-07 850b276a67 crypto/tls: send illegal_parameter on invalid ECHClientHello.type
+ 2025-01-06 27c5164374 crypto/internal/fips140: zeroise integrity test temporary values
+ 2025-01-06 d8ad4af78b cmd/internal/disasm: correct instruction length handling for riscv64
+ 2025-01-06 a76cc5a4ec crypto/rsa: use λ(N) instead of φ(N)
+ 2025-01-06 3f002abb60 internal/sync: add test from issue 70970
+ 2025-01-06 7a2e88e911 net/http: update NewRequestWithContext wrong link to NewRequest
+ 2025-01-06 c112c0af13 Revert "internal/sync: optimize CompareAndSwap and Swap"
+ 2025-01-03 705b5a569a crypto/ecdsa: drop SEC 1 reference from package doc
+ 2025-01-03 f966695cce context: use "canceled" in docs to refer to timed-out contexts
+ 2025-01-03 5da026354c cmd/go/internal/vcweb: close the .access file
+ 2025-01-03 31cabcf084 crypto/internal/fips140: mark OpenBSD unsupported
+ 2025-01-03 eb0c2b2f96 crypto/internal/fips140: add Supported
+ 2025-01-03 f0a9b6df45 internal/fuzz: remove the exp2 method
+ 2025-01-03 5d626c49ec spec: fix a dead link
+ 2025-01-03 81566aff3a internal/exportdata: add missing return
+ 2025-01-03 e7a8bd5d8b crypto/internal/fips140/check: remove Enabled
+ 2025-01-02 4b652e9f5f cmd/go: fix two typos in helpdoc.go
+ 2025-01-02 0afd7e85e5 cmd/go: document GOCACHEPROG in go help environment
+ 2025-01-02 3c8e5b13df cmd/go/internal/cacheprog: drop redundant Prog prefixes
+ 2025-01-02 20da34c6d2 cmd/go: move GOCACHEPROG protocol types to their own package
+ 2025-01-02 858a0e9dfd crypto/tls: properly return ECH retry configs
+ 2025-01-02 a63aee4955 cmd/go: improve GOCACHEPROG types documentation
+ 2025-01-02 847c357bbb cmd/go: remove references to gopath-get
+ 2025-01-01 d1d9312950 crypto/tls: fix Config.Time in tests using expired certificates
+ 2024-12-31 94f15810e6 cmd/go: document default GOARM value
+ 2024-12-30 856a7bc8e9 builtin: use list instead of indentation for comments in cap, len, and make
+ 2024-12-30 5efb4239c6 spec: document that string conversions don't guarantee result slice capacity
+ 2024-12-30 0d8aa8cce6 spec: describe representation of values
+ 2024-12-30 8857a5a33f crypto/tls: fix misspelling in comment
+ 2024-12-30 3c4102bfd4 encoding/binary: add documentation for endian methods
+ 2024-12-30 b702a26cf8 os: mention fsys modifications during CopyFS
+ 2024-12-30 15f232456a encoding/json: remove suggestion on Unmarshaler with JSON null
+ 2024-12-30 ba1deb1cee cmd/link: document that -s implies -w
+ 2024-12-30 fd5e0d26d9 go/doc: resolve imports before predeclared identifiers in examples
+ 2024-12-30 a785d11ac4 unique: fix typo
+ 2024-12-27 2b794ed86c encoding/json: expand and modernize TestInterfaceSet
+ 2024-12-27 e3cd55e9d2 cmd/go/internal/work: allow @ character in some -Wl, linker flags on darwin
+ 2024-12-27 39794819aa doc/initial: remove fixed-width spacing notice
+ 2024-12-27 7c03fe70b8 cmd/compile: improve compiler directive docs
+ 2024-12-27 d7c3e93c16 iter: improve documentation with iterator example
+ 2024-12-26 cce75da30b crypto/mlkem: swap order of return values of Encapsulate
+ 2024-12-23 772f024c61 weak: fix typo in warning about tiny allocator optimization
+ 2024-12-23 b9955f0ad9 cmd/link, runtime: apply a delta to RODATA->DATA relocations
+ 2024-12-23 eef35e3bd9 internal/goexperiment: run go generate for synctest
+ 2024-12-23 9f6c80a76a cmd/go/internal/work: allow single character values in -Wl, linker flags
+ 2024-12-22 05d8984781 net: document LookupTXT behavior with multiple strings per record
+ 2024-12-21 500675a7c8 cmd/compile: load map length with the right type
+ 2024-12-21 06b191e11f internal/syscall/unix: apply fstatat fix to linux/mips64le
+ 2024-12-21 110ab1aaf4 slices: document two oddities
+ 2024-12-19 669d87a935 runtime/pprof: continued attempt to deflake the VMInfo test.
+ 2024-12-19 45f49139f5 runtime: test trap panic parsing in TestTracebackSystem
+ 2024-12-19 e63eb98e98 net/http: fix nil panic in test
+ 2024-12-19 7b6c94dd03 cmd/go: drop fips140 build ID hacks
+ 2024-12-19 cb72406c36 cmd/go: fix two-step toolchain upgrade through go install, GOTOOLCHAIN
+ 2024-12-18 4f0561f9d3 cmd/dist: skip fips140test in exe mode on Android
+ 2024-12-18 87dbfb9fa7 weak: improve grammar in doc comments
+ 2024-12-18 f4e3ec3dbe crypto/ecdsa: fix condition for fips140=only check
+ 2024-12-18 6aa46eb750 crypto/tls: normalize spelling of "ClientHello" in comments
+ 2024-12-18 10ca5ba4ff crypto/pbkdf2: update RFC reference in package doc
+ 2024-12-18 8ff4cee564 cmd/go,crypto: reject using Go+BoringCrypto and fips140 together
+ 2024-12-18 971448ddf8 testing: support B.Context and F.Context
+ 2024-12-17 95b433eed4 debug/elf: adjust version API per issue discussion
+ 2024-12-17 b2c0168893 crypto/internal/fips140/aes/gcm: use aes.EncryptBlockInternal on ppc64x and s390x
+ 2024-12-17 b9e2ffdcd2 crypto/internal/fips140: add Name and Version
+ 2024-12-17 8790372a8d cmd, go: fix some typos
+ 2024-12-17 b057b8872d bytes, strings: add cross-references in docstrings
+ 2024-12-17 e977b83b32 cmd/go/internal/help: use secure link to swig.org
+ 2024-12-17 4ac8f552e9 syscall, internal/syscall/unix: fix fstatat on linux/mips64
+ 2024-12-17 236a0b4ffb spec: explain function invocation and passing of parameters more precisely
+ 2024-12-17 9f806bb76c go/build: streamline the crypto package graph in TestDependencies
+ 2024-12-17 0cd833d198 go/build: remove nonexistent package from TestDependencies
+ 2024-12-17 31e50af5f3 crypto/rsa: revert minimum GenerateKey size to 32 bits
+ 2024-12-17 b47ce8b0e9 crypto/cipher: block non-AES CTR and CBC in fips140=only mode
+ 2024-12-17 dd7a7ba38f crypto/internal/fips140/aes: mark AES-ECB as not approved
+ 2024-12-17 427a2401af cmd/go/testdata/script: update test_flags for new test output
+ 2024-12-17 75736cc169 fmt, strconv: document that exponent is always two digits
+ 2024-12-16 1218566fe5 cmd/link: update runtime dependency list
+ 2024-12-16 d92c34a387 cmd/go: don't create test actions for incomplete packages
+ 2024-12-16 3bd08b9792 runtime: usleep in TestWeakToStrongMarkTermination
+ 2024-12-15 18b5435fc8 testing: don't measure cleanup time after B.Loop
+ 2024-12-15 c1f2542c8b testing: improve B.Loop test
+ 2024-12-15 6bd56fcaeb testing: improve b.Loop example
+ 2024-12-15 090748d6c7 testing: improve B.Loop docs, use B.Loop in examples
+ 2024-12-13 e39e965e0e cmd/go: drop FailedBuild field if gotestjsonbuildtext=1
+ 2024-12-13 08770a5b94 cmd/link: make dwarf name slice index self-describing
+ 2024-12-13 c4f356dd86 crypto/ecdsa: fix s390x assembly with P-521
+ 2024-12-13 08725f9de2 crypto/internal/cryptotest: skip TestAllocations on s390x
+ 2024-12-13 1cbfe8c482 fmt: add more function and allocation tests
+ 2024-12-13 8391579ece runtime: migrate missing map linkname allowlists
+ 2024-12-12 80a2982a80 spec: align EBNF rules consistently (cosmetic change)
+ 2024-12-12 38e9a671d7 syscall: on freebsd-386 only update written for certain errors
+ 2024-12-12 6f7a4540b1 net: fix example function name for IP.To4
+ 2024-12-12 14e5093ee5 cmd/internal/obj: disallow linknamed access to builtin symbols
+ 2024-12-12 fb764cdad0 cmd/link: block new standard library linknames

Change-Id: Ie423f050db80034c3af6c12bd6007db273c5d281
2025-01-08 13:21:10 -05:00
Gopher Robot
16afa6a740 [release-branch.go1.24] go1.24rc1
Change-Id: Ia3b0a8ec25312b73879d2561a2b4d1cfc648c295
Reviewed-on: https://go-review.googlesource.com/c/go/+/636036
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Gopher Robot <gobot@golang.org>
TryBot-Bypass: Carlos Amedee <carlos@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2024-12-13 08:52:10 -08:00
Carlos Amedee
817d7bdc0a [release-branch.go1.24] all: merge master (9118060) into release-branch.go1.24
Merge List:

+ 2024-12-12 9118060040 builtin: document clear is a no-op if its argument's value is nil
+ 2024-12-11 077d51909d internal/poll: in SendFile treat ENOTSUP like EOPNOTSUPP
+ 2024-12-11 fafd4477f3 cmd/cgo: use full prototype for main in C code

Change-Id: I4c4941eff4a1e842920eb9be47d28351af0e4c36
2024-12-12 12:06:37 -05:00
Carlos Amedee
14bb1e11b9 [release-branch.go1.24] all: merge master (0ca521f) into release-branch.go1.24
Merge List:

+ 2024-12-11 0ca521f9c1 debug/elf: adjust version API per issue discussion

Change-Id: Ibd6f628528dd366837ad0bbacad624474eee0088
2024-12-11 18:55:28 -05:00
Carlos Amedee
2297c34cdf [release-branch.go1.24] all: merge master (c93477b) into release-branch.go1.24
Merge List:

+ 2024-12-11 c93477b5e5 crypto: use provided random Reader in FIPS mode
+ 2024-12-11 3104b6adbb log/slog: make DiscardHandler example package-level
+ 2024-12-11 5424f2e200 cmd/go: add more tests for GOAUTH's user provided authenticator
+ 2024-12-11 d5c1333eb4 net/http: document zero value of Protocols
+ 2024-12-11 a7c4cadce0 cmd/compile: update broken link
+ 2024-12-11 979c1cfbe8 net: avoid unnecessary interface lookup fetching all interface addresses
+ 2024-12-11 e424d78c3d internal/goos: fix bug in gengoos.go
+ 2024-12-11 6c25cf1c5f cmd/internal/objfile: break out dissassemblers to another package
+ 2024-12-11 e0c76d95ab syscall: remove a wrong comment in Clearenv
+ 2024-12-11 a9922d096f reflect: consistently document when value must be settable
+ 2024-12-10 4ce116a884 runtime: avoid panic in expired synctest timer chan read
+ 2024-12-10 e6de1b2deb html/template: escape script tags in JS errors case insensitively
+ 2024-12-10 fce17b0c77 crypto/internal/fips140/ecdsa: fix reseed_counter check for HMAC_DRBG_Generate_algorithm
+ 2024-12-09 d87878c62b runtime: make special offset a uintptr
+ 2024-12-09 6705ac6885 runtime: remove datadog-agent from prof labels hall of shame
+ 2024-12-09 07398d2e57 weak: align weak.Pointer documentation with runtime.AddCleanup
+ 2024-12-09 e3e1d73528 bufio: make the description of Peek's behavior better
+ 2024-12-09 e79b2e1e3a cmd/go: document the build cache as safe for concurrent use
+ 2024-12-08 c8fb6ae617 lib/wasm: provide fs.constants.O_DIRECTORY definition
+ 2024-12-07 8c3e391573 runtime: improve AddCleanup documentation
+ 2024-12-07 04cdaa9984 cmd/go: document c-shared buildmode for building WASI library/reactor
+ 2024-12-06 312f7c1bd3 runtime: add note that Callers never returns an entry PC

Change-Id: I52e035228121de3d8219ab13f195d4293daaaa34
2024-12-11 17:45:39 -05:00
Michael Anthony Knyszek
26682773ca [release-branch.go1.24] update codereview.cfg for release-branch.go1.24
Change-Id: I63ffca43a935bc5ff060f19c01152a20182cba03
Reviewed-on: https://go-review.googlesource.com/c/go/+/634317
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
2024-12-06 21:58:36 +00:00
103 changed files with 22305 additions and 358 deletions

2
VERSION Normal file
View File

@ -0,0 +1,2 @@
go1.24.2
time 2025-03-26T19:09:39Z

View File

@ -1 +1,2 @@
branch: master
branch: release-branch.go1.24
parent-branch: master

View File

@ -153,6 +153,17 @@ and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
### Go 1.24
Go 1.24 added a new `fips140` setting that controls whether the Go
Cryptographic Module operates in FIPS 140-3 mode.
The possible values are:
- "off": no special support for FIPS 140-3 mode. This is the default.
- "on": the Go Cryptographic Module operates in FIPS 140-3 mode.
- "only": like "on", but cryptographic algorithms not approved by
FIPS 140-3 return an error or panic.
For more information, see [FIPS 140-3 Compliance](/doc/security/fips140).
This setting is fixed at program startup time, and can't be modified
by changing the `GODEBUG` environment variable after the program starts.
Go 1.24 changed the global [`math/rand.Seed`](/pkg/math/rand/#Seed) to be a
no-op. This behavior is controlled by the `randseednop` setting.
For Go 1.24 it defaults to `randseednop=1`.

View File

@ -67,26 +67,26 @@ func splitSeq(s, sep []byte, sepSave int) iter.Seq[[]byte] {
}
}
// SplitSeq returns an iterator over all substrings of s separated by sep.
// The iterator yields the same strings that would be returned by [Split](s, sep),
// but without constructing the slice.
// SplitSeq returns an iterator over all subslices of s separated by sep.
// The iterator yields the same subslices that would be returned by [Split](s, sep),
// but without constructing a new slice containing the subslices.
// It returns a single-use iterator.
func SplitSeq(s, sep []byte) iter.Seq[[]byte] {
return splitSeq(s, sep, 0)
}
// SplitAfterSeq returns an iterator over substrings of s split after each instance of sep.
// The iterator yields the same strings that would be returned by [SplitAfter](s, sep),
// but without constructing the slice.
// SplitAfterSeq returns an iterator over subslices of s split after each instance of sep.
// The iterator yields the same subslices that would be returned by [SplitAfter](s, sep),
// but without constructing a new slice containing the subslices.
// It returns a single-use iterator.
func SplitAfterSeq(s, sep []byte) iter.Seq[[]byte] {
return splitSeq(s, sep, len(sep))
}
// FieldsSeq returns an iterator over substrings of s split around runs of
// FieldsSeq returns an iterator over subslices of s split around runs of
// whitespace characters, as defined by [unicode.IsSpace].
// The iterator yields the same strings that would be returned by [Fields](s),
// but without constructing the slice.
// The iterator yields the same subslices that would be returned by [Fields](s),
// but without constructing a new slice containing the subslices.
func FieldsSeq(s []byte) iter.Seq[[]byte] {
return func(yield func([]byte) bool) {
start := -1
@ -116,10 +116,10 @@ func FieldsSeq(s []byte) iter.Seq[[]byte] {
}
}
// FieldsFuncSeq returns an iterator over substrings of s split around runs of
// FieldsFuncSeq returns an iterator over subslices of s split around runs of
// Unicode code points satisfying f(c).
// The iterator yields the same strings that would be returned by [FieldsFunc](s),
// but without constructing the slice.
// The iterator yields the same subslices that would be returned by [FieldsFunc](s),
// but without constructing a new slice containing the subslices.
func FieldsFuncSeq(s []byte, f func(rune) bool) iter.Seq[[]byte] {
return func(yield func([]byte) bool) {
start := -1

View File

@ -42,6 +42,7 @@ import (
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/pgo"
"cmd/internal/src"
)
// Inlining budget parameters, gathered in one place
@ -974,6 +975,16 @@ func inlineCostOK(n *ir.CallExpr, caller, callee *ir.Func, bigCaller, closureCal
return true, 0, metric, hot
}
// parsePos returns all the inlining positions and the innermost position.
func parsePos(pos src.XPos, posTmp []src.Pos) ([]src.Pos, src.Pos) {
ctxt := base.Ctxt
ctxt.AllPos(pos, func(p src.Pos) {
posTmp = append(posTmp, p)
})
l := len(posTmp) - 1
return posTmp[:l], posTmp[l]
}
// canInlineCallExpr returns true if the call n from caller to callee
// can be inlined, plus the score computed for the call expr in question,
// and whether the callee is hot according to PGO.
@ -1001,6 +1012,17 @@ func canInlineCallExpr(callerfn *ir.Func, n *ir.CallExpr, callee *ir.Func, bigCa
return false, 0, false
}
callees, calleeInner := parsePos(n.Pos(), make([]src.Pos, 0, 10))
for _, p := range callees {
if p.Line() == calleeInner.Line() && p.Col() == calleeInner.Col() && p.AbsFilename() == calleeInner.AbsFilename() {
if log && logopt.Enabled() {
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(callerfn)))
}
return false, 0, false
}
}
if callee == callerfn {
// Can't recursively inline a function into itself.
if log && logopt.Enabled() {
@ -1009,6 +1031,60 @@ func canInlineCallExpr(callerfn *ir.Func, n *ir.CallExpr, callee *ir.Func, bigCa
return false, 0, false
}
isClosureParent := func(closure, parent *ir.Func) bool {
for p := closure.ClosureParent; p != nil; p = p.ClosureParent {
if p == parent {
return true
}
}
return false
}
if isClosureParent(callerfn, callee) {
// Can't recursively inline a parent of the closure into itself.
if log && logopt.Enabled() {
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to closure parent: %s, %s", ir.FuncName(callerfn), ir.FuncName(callee)))
}
return false, 0, false
}
if isClosureParent(callee, callerfn) {
// Can't recursively inline a closure if there's a call to the parent in closure body.
if ir.Any(callee, func(node ir.Node) bool {
if call, ok := node.(*ir.CallExpr); ok {
if name, ok := call.Fun.(*ir.Name); ok && isClosureParent(callerfn, name.Func) {
return true
}
}
return false
}) {
if log && logopt.Enabled() {
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to closure parent: %s, %s", ir.FuncName(callerfn), ir.FuncName(callee)))
}
return false, 0, false
}
}
do := func(fn *ir.Func) bool {
// Can't recursively inline a function if the function body contains
// a call to a function f, which the function f is one of the call arguments.
return ir.Any(fn, func(node ir.Node) bool {
if call, ok := node.(*ir.CallExpr); ok {
for _, arg := range call.Args {
if call.Fun == arg {
return true
}
}
}
return false
})
}
for _, fn := range []*ir.Func{callerfn, callee} {
if do(fn) {
if log && logopt.Enabled() {
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", fmt.Sprintf("recursive call to function: %s", ir.FuncName(fn)))
}
return false, 0, false
}
}
if base.Flag.Cfg.Instrumenting && types.IsNoInstrumentPkg(callee.Sym().Pkg) {
// Runtime package must not be instrumented.
// Instrument skips runtime package. However, some runtime code can be

View File

@ -253,7 +253,7 @@ func (s *inlClosureState) mark(n ir.Node) ir.Node {
if isTestingBLoop(n) {
// No inlining nor devirtualization performed on b.Loop body
if base.Flag.LowerM > 1 {
if base.Flag.LowerM > 0 {
fmt.Printf("%v: skip inlining within testing.B.loop for %v\n", ir.Line(n), n)
}
// We still want to explore inlining opportunities in other parts of ForStmt.

View File

@ -1148,10 +1148,12 @@
(SUB a l:(MNEGW x y)) && v.Type.Size() <= 4 && l.Uses==1 && clobber(l) => (MADDW a x y)
// madd/msub can't take constant arguments, so do a bit of reordering if a non-constant is available.
(ADD a p:(ADDconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 => (ADDconst [c] (ADD <v.Type> a m))
(ADD a p:(SUBconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 => (SUBconst [c] (ADD <v.Type> a m))
(SUB a p:(ADDconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 => (SUBconst [c] (SUB <v.Type> a m))
(SUB a p:(SUBconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 => (ADDconst [c] (SUB <v.Type> a m))
// Note: don't reorder arithmetic concerning pointers, as we must ensure that
// no intermediate computations are invalid pointers.
(ADD <t> a p:(ADDconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 && !t.IsPtrShaped() => (ADDconst [c] (ADD <v.Type> a m))
(ADD <t> a p:(SUBconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 && !t.IsPtrShaped() => (SUBconst [c] (ADD <v.Type> a m))
(SUB <t> a p:(ADDconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 && !t.IsPtrShaped() => (SUBconst [c] (SUB <v.Type> a m))
(SUB <t> a p:(SUBconst [c] m:((MUL|MULW|MNEG|MNEGW) _ _))) && p.Uses==1 && m.Uses==1 && !t.IsPtrShaped() => (ADDconst [c] (SUB <v.Type> a m))
// optimize ADCSflags, SBCSflags and friends
(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (ADCzerocarry <typ.UInt64> c)))) => (ADCSflags x y c)

View File

@ -41,11 +41,12 @@ type Func struct {
ABISelf *abi.ABIConfig // ABI for function being compiled
ABIDefault *abi.ABIConfig // ABI for rtcall and other no-parsed-signature/pragma functions.
scheduled bool // Values in Blocks are in final order
laidout bool // Blocks are ordered
NoSplit bool // true if function is marked as nosplit. Used by schedule check pass.
dumpFileSeq uint8 // the sequence numbers of dump file. (%s_%02d__%s.dump", funcname, dumpFileSeq, phaseName)
IsPgoHot bool
scheduled bool // Values in Blocks are in final order
laidout bool // Blocks are ordered
NoSplit bool // true if function is marked as nosplit. Used by schedule check pass.
dumpFileSeq uint8 // the sequence numbers of dump file. (%s_%02d__%s.dump", funcname, dumpFileSeq, phaseName)
IsPgoHot bool
HasDeferRangeFunc bool // if true, needs a deferreturn so deferrangefunc can use it for recover() return PC
// when register allocation is done, maps value ids to locations
RegAlloc []Location

View File

@ -552,8 +552,9 @@ func (ft *factsTable) newLimit(v *Value, newLim limit) bool {
}
if lim.unsat() {
r := !ft.unsat
ft.unsat = true
return true
return r
}
// Check for recursion. This normally happens because in unsatisfiable

View File

@ -1670,6 +1670,7 @@ func (s *regAllocState) regalloc(f *Func) {
}
tmpReg = s.allocReg(m, &tmpVal)
s.nospill |= regMask(1) << tmpReg
s.tmpused |= regMask(1) << tmpReg
}
// Now that all args are in regs, we're ready to issue the value itself.

View File

@ -1331,10 +1331,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(ADDconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(ADDconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1343,7 +1344,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64ADDconst)
@ -1355,10 +1356,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(ADDconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(ADDconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1367,7 +1369,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64ADDconst)
@ -1379,10 +1381,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(ADDconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(ADDconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1391,7 +1394,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64ADDconst)
@ -1403,10 +1406,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(ADDconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(ADDconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1415,7 +1419,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64ADDconst)
@ -1427,10 +1431,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(SUBconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(SUBconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1439,7 +1444,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64SUBconst)
@ -1451,10 +1456,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(SUBconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(SUBconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1463,7 +1469,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64SUBconst)
@ -1475,10 +1481,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(SUBconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(SUBconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1487,7 +1494,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64SUBconst)
@ -1499,10 +1506,11 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
break
}
// match: (ADD a p:(SUBconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (ADD <t> a p:(SUBconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (ADD <v.Type> a m))
for {
t := v.Type
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
a := v_0
p := v_1
@ -1511,7 +1519,7 @@ func rewriteValueARM64_OpARM64ADD(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
continue
}
v.reset(OpARM64SUBconst)
@ -16604,10 +16612,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg3(a, x, y)
return true
}
// match: (SUB a p:(ADDconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(ADDconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64ADDconst {
@ -16615,7 +16624,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64SUBconst)
@ -16625,10 +16634,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (SUB a p:(ADDconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(ADDconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64ADDconst {
@ -16636,7 +16646,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64SUBconst)
@ -16646,10 +16656,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (SUB a p:(ADDconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(ADDconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64ADDconst {
@ -16657,7 +16668,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64SUBconst)
@ -16667,10 +16678,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (SUB a p:(ADDconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(ADDconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (SUBconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64ADDconst {
@ -16678,7 +16690,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64SUBconst)
@ -16688,10 +16700,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (SUB a p:(SUBconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(SUBconst [c] m:(MUL _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64SUBconst {
@ -16699,7 +16712,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MUL || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64ADDconst)
@ -16709,10 +16722,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (SUB a p:(SUBconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(SUBconst [c] m:(MULW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64SUBconst {
@ -16720,7 +16734,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MULW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64ADDconst)
@ -16730,10 +16744,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (SUB a p:(SUBconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(SUBconst [c] m:(MNEG _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64SUBconst {
@ -16741,7 +16756,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEG || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64ADDconst)
@ -16751,10 +16766,11 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
v.AddArg(v0)
return true
}
// match: (SUB a p:(SUBconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1
// match: (SUB <t> a p:(SUBconst [c] m:(MNEGW _ _)))
// cond: p.Uses==1 && m.Uses==1 && !t.IsPtrShaped()
// result: (ADDconst [c] (SUB <v.Type> a m))
for {
t := v.Type
a := v_0
p := v_1
if p.Op != OpARM64SUBconst {
@ -16762,7 +16778,7 @@ func rewriteValueARM64_OpARM64SUB(v *Value) bool {
}
c := auxIntToInt64(p.AuxInt)
m := p.Args[0]
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1) {
if m.Op != OpARM64MNEGW || !(p.Uses == 1 && m.Uses == 1 && !t.IsPtrShaped()) {
break
}
v.reset(OpARM64ADDconst)

View File

@ -4433,6 +4433,9 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool, deferExt
callABI = s.f.ABI1
}
}
if fn := n.Fun.Sym().Name; n.Fun.Sym().Pkg == ir.Pkgs.Runtime && fn == "deferrangefunc" {
s.f.HasDeferRangeFunc = true
}
break
}
closure = s.expr(fn)
@ -6566,10 +6569,13 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
// nop (which will never execute) after the call.
Arch.Ginsnop(s.pp)
}
if openDeferInfo != nil {
if openDeferInfo != nil || f.HasDeferRangeFunc {
// When doing open-coded defers, generate a disconnected call to
// deferreturn and a return. This will be used to during panic
// recovery to unwind the stack and return back to the runtime.
//
// deferrangefunc needs to be sure that at least one of these exists;
// if all returns are dead-code eliminated, there might not be.
s.pp.NextLive = s.livenessMap.DeferReturn
p := s.pp.Prog(obj.ACALL)
p.To.Type = obj.TYPE_MEM

View File

@ -230,6 +230,9 @@ func TestIntendedInlining(t *testing.T) {
"(*Pointer[go.shape.int]).Store",
"(*Pointer[go.shape.int]).Swap",
},
"testing": {
"(*B).Loop",
},
}
if !goexperiment.SwissMap {

View File

@ -204,7 +204,7 @@ func (check *Checker) lhsVar(lhs syntax.Expr) Type {
// dot-imported variables.
if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
v = w
v_used = v.used
v_used = check.usedVars[v]
}
}
}
@ -213,7 +213,7 @@ func (check *Checker) lhsVar(lhs syntax.Expr) Type {
check.expr(nil, &x, lhs)
if v != nil {
v.used = v_used // restore v.used
check.usedVars[v] = v_used // restore v.used
}
if x.mode == invalid || !isValid(x.typ) {

View File

@ -687,7 +687,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *TypeName
if pname, _ := obj.(*PkgName); pname != nil {
assert(pname.pkg == check.pkg)
check.recordUse(ident, pname)
pname.used = true
check.usedPkgNames[pname] = true
pkg := pname.imported
var exp Object
@ -972,13 +972,13 @@ func (check *Checker) use1(e syntax.Expr, lhs bool) bool {
// dot-imported variables.
if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
v = w
v_used = v.used
v_used = check.usedVars[v]
}
}
}
check.exprOrType(&x, n, true)
if v != nil {
v.used = v_used // restore v.used
check.usedVars[v] = v_used // restore v.used
}
case *syntax.ListExpr:
return check.useN(n.ElemList, lhs)

View File

@ -162,6 +162,8 @@ type Checker struct {
dotImportMap map[dotImportKey]*PkgName // maps dot-imported objects to the package they were dot-imported through
brokenAliases map[*TypeName]bool // set of aliases with broken (not yet determined) types
unionTypeSets map[*Union]*_TypeSet // computed type sets for union types
usedVars map[*Var]bool // set of used variables
usedPkgNames map[*PkgName]bool // set of used package names
mono monoGraph // graph for detecting non-monomorphizable instantiation loops
firstErr error // first error encountered
@ -285,12 +287,14 @@ func NewChecker(conf *Config, pkg *Package, info *Info) *Checker {
// (previously, pkg.goVersion was mutated here: go.dev/issue/61212)
return &Checker{
conf: conf,
ctxt: conf.Context,
pkg: pkg,
Info: info,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
conf: conf,
ctxt: conf.Context,
pkg: pkg,
Info: info,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
usedVars: make(map[*Var]bool),
usedPkgNames: make(map[*PkgName]bool),
}
}
@ -298,6 +302,8 @@ func NewChecker(conf *Config, pkg *Package, info *Info) *Checker {
// The provided files must all belong to the same package.
func (check *Checker) initFiles(files []*syntax.File) {
// start with a clean slate (check.Files may be called multiple times)
// TODO(gri): what determines which fields are zeroed out here, vs at the end
// of checkFiles?
check.files = nil
check.imports = nil
check.dotImportMap = nil
@ -309,6 +315,13 @@ func (check *Checker) initFiles(files []*syntax.File) {
check.objPath = nil
check.cleaners = nil
// We must initialize usedVars and usedPkgNames both here and in NewChecker,
// because initFiles is not called in the CheckExpr or Eval codepaths, yet we
// want to free this memory at the end of Files ('used' predicates are
// only needed in the context of a given file).
check.usedVars = make(map[*Var]bool)
check.usedPkgNames = make(map[*PkgName]bool)
// determine package name and collect valid files
pkg := check.pkg
for _, file := range files {
@ -482,8 +495,11 @@ func (check *Checker) checkFiles(files []*syntax.File) {
check.seenPkgMap = nil
check.brokenAliases = nil
check.unionTypeSets = nil
check.usedVars = nil
check.usedPkgNames = nil
check.ctxt = nil
// TODO(gri): shouldn't the cleanup above occur after the bailout?
// TODO(gri) There's more memory we should release at this point.
}

View File

@ -242,13 +242,12 @@ func (a *object) cmp(b *object) int {
type PkgName struct {
object
imported *Package
used bool // set if the package was used
}
// NewPkgName returns a new PkgName object representing an imported package.
// The remaining arguments set the attributes found with all Objects.
func NewPkgName(pos syntax.Pos, pkg *Package, name string, imported *Package) *PkgName {
return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported}
}
// Imported returns the package that was imported.
@ -331,10 +330,10 @@ func (obj *TypeName) IsAlias() bool {
// A Variable represents a declared variable (including function parameters and results, and struct fields).
type Var struct {
object
origin *Var // if non-nil, the Var from which this one was instantiated
embedded bool // if set, the variable is an embedded struct field, and name is the type name
isField bool // var is struct field
used bool // set if the variable was used
origin *Var // if non-nil, the Var from which this one was instantiated
isParam bool // var is a param, for backport of 'used' check to go1.24 (go.dev/issue/72826)
}
// NewVar returns a new variable.
@ -345,7 +344,7 @@ func NewVar(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
// NewParam returns a new variable representing a function parameter.
func NewParam(pos syntax.Pos, pkg *Package, name string, typ Type) *Var {
return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true} // parameters are always 'used'
return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, isParam: true}
}
// NewField returns a new variable representing a struct field.

View File

@ -295,7 +295,7 @@ func (check *Checker) collectObjects() {
if imp.fake {
// match 1.17 cmd/compile (not prescribed by spec)
pkgName.used = true
check.usedPkgNames[pkgName] = true
}
// add import to file scope
@ -715,7 +715,7 @@ func (check *Checker) unusedImports() {
// (initialization), use the blank identifier as explicit package name."
for _, obj := range check.imports {
if !obj.used && obj.name != "_" {
if obj.name != "_" && !check.usedPkgNames[obj] {
check.errorUnusedPkg(obj)
}
}

View File

@ -36,7 +36,7 @@ func TestSizeof(t *testing.T) {
{term{}, 12, 24},
// Objects
{PkgName{}, 64, 104},
{PkgName{}, 60, 96},
{Const{}, 64, 104},
{TypeName{}, 56, 88},
{Var{}, 64, 104},

View File

@ -58,7 +58,7 @@ func (check *Checker) usage(scope *Scope) {
var unused []*Var
for name, elem := range scope.elems {
elem = resolve(name, elem)
if v, _ := elem.(*Var); v != nil && !v.used {
if v, _ := elem.(*Var); v != nil && !v.isParam && !check.usedVars[v] {
unused = append(unused, v)
}
}
@ -824,10 +824,10 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
if lhs != nil {
var used bool
for _, v := range lhsVars {
if v.used {
if check.usedVars[v] {
used = true
}
v.used = true // avoid usage error when checking entire function
check.usedVars[v] = true // avoid usage error when checking entire function
}
if !used {
check.softErrorf(lhs, UnusedVar, "%s declared and not used", lhs.Value)
@ -934,7 +934,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
if typ == nil || typ == Typ[Invalid] {
// typ == Typ[Invalid] can happen if allowVersion fails.
obj.typ = Typ[Invalid]
obj.used = true // don't complain about unused variable
check.usedVars[obj] = true // don't complain about unused variable
continue
}

View File

@ -55,7 +55,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType
// avoid "declared but not used" errors
// (don't use Checker.use - we don't want to evaluate too much)
if v, _ := obj.(*Var); v != nil && v.pkg == check.pkg /* see Checker.use1 */ {
v.used = true
check.usedVars[v] = true
}
return
}
@ -83,7 +83,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType
// (This code is only needed for dot-imports. Without them,
// we only have to mark variables, see *Var case below).
if pkgName := check.dotImportMap[dotImportKey{scope, obj.Name()}]; pkgName != nil {
pkgName.used = true
check.usedPkgNames[pkgName] = true
}
switch obj := obj.(type) {
@ -120,7 +120,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType
// from other packages to avoid potential race conditions with
// dot-imported variables.
if obj.pkg == check.pkg {
obj.used = true
check.usedVars[obj] = true
}
check.addDeclDep(obj)
if !isValid(typ) {

View File

@ -128,7 +128,8 @@ func runGoAuth(client *http.Client, res *http.Response, url string) {
// If no GOAUTH command provided a credential for the given url
// and an error occurred, log the error.
if cfg.BuildX && url != "" {
if ok := loadCredential(&http.Request{}, url); !ok && len(cmdErrs) > 0 {
req := &http.Request{Header: make(http.Header)}
if ok := loadCredential(req, url); !ok && len(cmdErrs) > 0 {
log.Printf("GOAUTH encountered errors for %s:", url)
for _, err := range cmdErrs {
log.Printf(" %v", err)

View File

@ -227,21 +227,6 @@ var validLinkerFlags = []*lazyregexp.Regexp{
re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`),
}
var validLinkerFlagsOnDarwin = []*lazyregexp.Regexp{
// The GNU linker interprets `@file` as "read command-line options from
// file". Thus, we forbid values starting with `@` on linker flags.
// However, this causes a problem when targeting Darwin.
// `@executable_path`, `@loader_path`, and `@rpath` are special values
// used in Mach-O to change the library search path and can be used in
// conjunction with the `-install_name` and `-rpath` linker flags.
// Since the GNU linker does not support Mach-O, targeting Darwin
// implies not using the GNU linker. Therefore, we allow @ in the linker
// flags if and only if cfg.Goos == "darwin" || cfg.Goos == "ios".
re(`-Wl,-dylib_install_name,@rpath(/[^,]*)?`),
re(`-Wl,-install_name,@rpath(/[^,]*)?`),
re(`-Wl,-rpath,@(executable_path|loader_path)(/[^,]*)?`),
}
var validLinkerFlagsWithNextArg = []string{
"-arch",
"-F",
@ -264,13 +249,8 @@ func checkCompilerFlags(name, source string, list []string) error {
}
func checkLinkerFlags(name, source string, list []string) error {
validLinkerFlagsForPlatform := validLinkerFlags
if cfg.Goos == "darwin" || cfg.Goos == "ios" {
validLinkerFlagsForPlatform = append(validLinkerFlags, validLinkerFlagsOnDarwin...)
}
checkOverrides := true
return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlagsForPlatform, validLinkerFlagsWithNextArg, checkOverrides)
return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
}
// checkCompilerFlagsForInternalLink returns an error if 'list'

View File

@ -8,8 +8,6 @@ import (
"os"
"strings"
"testing"
"cmd/go/internal/cfg"
)
var goodCompilerFlags = [][]string{
@ -247,8 +245,6 @@ var badLinkerFlags = [][]string{
{"-Wl,--hash-style=foo"},
{"-x", "--c"},
{"-x", "@obj"},
{"-Wl,-dylib_install_name,@foo"},
{"-Wl,-install_name,@foo"},
{"-Wl,-rpath,@foo"},
{"-Wl,-R,foo,bar"},
{"-Wl,-R,@foo"},
@ -265,21 +261,6 @@ var badLinkerFlags = [][]string{
{"./-Wl,--push-state,-R.c"},
}
var goodLinkerFlagsOnDarwin = [][]string{
{"-Wl,-dylib_install_name,@rpath"},
{"-Wl,-dylib_install_name,@rpath/"},
{"-Wl,-dylib_install_name,@rpath/foo"},
{"-Wl,-install_name,@rpath"},
{"-Wl,-install_name,@rpath/"},
{"-Wl,-install_name,@rpath/foo"},
{"-Wl,-rpath,@executable_path"},
{"-Wl,-rpath,@executable_path/"},
{"-Wl,-rpath,@executable_path/foo"},
{"-Wl,-rpath,@loader_path"},
{"-Wl,-rpath,@loader_path/"},
{"-Wl,-rpath,@loader_path/foo"},
}
func TestCheckLinkerFlags(t *testing.T) {
for _, f := range goodLinkerFlags {
if err := checkLinkerFlags("test", "test", f); err != nil {
@ -291,31 +272,6 @@ func TestCheckLinkerFlags(t *testing.T) {
t.Errorf("missing error for %q", f)
}
}
goos := cfg.Goos
cfg.Goos = "darwin"
for _, f := range goodLinkerFlagsOnDarwin {
if err := checkLinkerFlags("test", "test", f); err != nil {
t.Errorf("unexpected error for %q: %v", f, err)
}
}
cfg.Goos = "ios"
for _, f := range goodLinkerFlagsOnDarwin {
if err := checkLinkerFlags("test", "test", f); err != nil {
t.Errorf("unexpected error for %q: %v", f, err)
}
}
cfg.Goos = "linux"
for _, f := range goodLinkerFlagsOnDarwin {
if err := checkLinkerFlags("test", "test", f); err == nil {
t.Errorf("missing error for %q", f)
}
}
cfg.Goos = goos
}
func TestCheckFlagAllowDisallow(t *testing.T) {

View File

@ -49,6 +49,8 @@ go get vcs-test.golang.org/auth/or401
go mod tidy
go list all
stdout vcs-test.golang.org/auth/or404
# With cached credentials, re-downloading in debug mode should succeed.
go get -x vcs-test.golang.org/auth/or401
# Clearing GOAUTH credentials should result in failures.
env GOAUTH='off'

View File

@ -43,6 +43,9 @@ type PkgSpecial struct {
}
var runtimePkgs = []string{
// TODO(panjf2000): consider syncing the list inside the
// isAsyncSafePoint in preempt.go based on this list?
"runtime",
"internal/runtime/atomic",

View File

@ -10,7 +10,7 @@ import (
"internal/godebug"
)
var fips140GODEBUG = godebug.New("#fips140")
var fips140GODEBUG = godebug.New("fips140")
// Enabled reports whether the cryptography libraries are operating in FIPS
// 140-3 mode.

View File

@ -100,7 +100,7 @@ func init() {
clear(nbuf[:])
h.Reset()
if godebug.Value("#fips140") == "debug" {
if godebug.Value("fips140") == "debug" {
println("fips140: verified code+data")
}

View File

@ -16,7 +16,7 @@ import (
// Enabled reports whether FIPS 140-only mode is enabled, in which non-approved
// cryptography returns an error or panics.
var Enabled = godebug.New("#fips140").Value() == "only"
var Enabled = godebug.New("fips140").Value() == "only"
func ApprovedHash(h hash.Hash) bool {
switch h.(type) {

View File

@ -26,7 +26,7 @@ func TestFIPSCheckVerify(t *testing.T) {
return
}
if godebug.New("#fips140").Value() == "on" {
if godebug.New("fips140").Value() == "on" {
t.Fatalf("GODEBUG=fips140=on but verification did not run")
}

View File

@ -92,7 +92,8 @@ var defaultCipherSuitesTLS13NoAES = []uint16{
}
// The FIPS-only policies below match BoringSSL's
// ssl_compliance_policy_fips_202205, which is based on NIST SP 800-52r2.
// ssl_compliance_policy_fips_202205, which is based on NIST SP 800-52r2, with
// minor changes per https://go.dev/issue/71757.
// https://cs.opensource.google/boringssl/boringssl/+/master:ssl/ssl_lib.cc;l=3289;drc=ea7a88fa
var defaultSupportedVersionsFIPS = []uint16{
@ -102,7 +103,7 @@ var defaultSupportedVersionsFIPS = []uint16{
// defaultCurvePreferencesFIPS are the FIPS-allowed curves,
// in preference order (most preferable first).
var defaultCurvePreferencesFIPS = []CurveID{CurveP256, CurveP384}
var defaultCurvePreferencesFIPS = []CurveID{CurveP256, CurveP384, CurveP521}
// defaultSupportedSignatureAlgorithmsFIPS currently are a subset of
// defaultSupportedSignatureAlgorithms without Ed25519 and SHA-1.
@ -115,6 +116,7 @@ var defaultSupportedSignatureAlgorithmsFIPS = []SignatureScheme{
PKCS1WithSHA384,
ECDSAWithP384AndSHA384,
PKCS1WithSHA512,
ECDSAWithP521AndSHA512,
}
// defaultCipherSuitesFIPS are the FIPS-allowed cipher suites.

View File

@ -106,7 +106,7 @@ func isFIPSCipherSuite(id uint16) bool {
func isFIPSCurve(id CurveID) bool {
switch id {
case CurveP256, CurveP384:
case CurveP256, CurveP384, CurveP521:
return true
}
return false
@ -130,6 +130,7 @@ func isFIPSSignatureScheme(alg SignatureScheme) bool {
PKCS1WithSHA384,
ECDSAWithP384AndSHA384,
PKCS1WithSHA512,
ECDSAWithP521AndSHA512,
PSSWithSHA256,
PSSWithSHA384,
PSSWithSHA512:

View File

@ -11,6 +11,7 @@ import (
"encoding/binary"
"flag"
"fmt"
"internal/obscuretestdata"
"internal/testenv"
"os"
"os/exec"
@ -275,24 +276,16 @@ func TestReadFile(t *testing.T) {
// Test117 verifies that parsing of the old, pre-1.18 format works.
func Test117(t *testing.T) {
// go117 was generated for linux-amd64 with:
//
// main.go:
//
// package main
// func main() {}
//
// GOTOOLCHAIN=go1.17 go mod init example.com/go117
// GOTOOLCHAIN=go1.17 go build
//
// TODO(prattmic): Ideally this would be built on the fly to better
// cover all executable formats, but then we need a network connection
// to download an old Go toolchain.
info, err := buildinfo.ReadFile("testdata/go117")
b, err := obscuretestdata.ReadFile("testdata/go117/go117.base64")
if err != nil {
t.Fatalf("ReadFile got err %v, want nil", err)
}
info, err := buildinfo.Read(bytes.NewReader(b))
if err != nil {
t.Fatalf("Read got err %v, want nil", err)
}
if info.GoVersion != "go1.17" {
t.Errorf("GoVersion got %s want go1.17", info.GoVersion)
}
@ -306,20 +299,14 @@ func Test117(t *testing.T) {
// TestNotGo verifies that parsing of a non-Go binary returns the proper error.
func TestNotGo(t *testing.T) {
// notgo was generated for linux-amd64 with:
//
// main.c:
//
// int main(void) { return 0; }
//
// cc -o notgo main.c
//
// TODO(prattmic): Ideally this would be built on the fly to better
// cover all executable formats, but then we need to encode the
// intricacies of calling each platform's C compiler.
_, err := buildinfo.ReadFile("testdata/notgo")
b, err := obscuretestdata.ReadFile("testdata/notgo/notgo.base64")
if err != nil {
t.Fatalf("ReadFile got err %v, want nil", err)
}
_, err = buildinfo.Read(bytes.NewReader(b))
if err == nil {
t.Fatalf("ReadFile got nil err, want non-nil")
t.Fatalf("Read got nil err, want non-nil")
}
// The precise error text here isn't critical, but we want something
@ -410,13 +397,13 @@ func TestIssue54968(t *testing.T) {
}
func FuzzRead(f *testing.F) {
go117, err := os.ReadFile("testdata/go117")
go117, err := obscuretestdata.ReadFile("testdata/go117/go117.base64")
if err != nil {
f.Errorf("Error reading go117: %v", err)
}
f.Add(go117)
notgo, err := os.ReadFile("testdata/notgo")
notgo, err := obscuretestdata.ReadFile("testdata/notgo/notgo.base64")
if err != nil {
f.Errorf("Error reading notgo: %v", err)
}

Binary file not shown.

View File

@ -0,0 +1,15 @@
go117.base64 is a base64-encoded Go 1.17 hello world binary used to test
debug/buildinfo of pre-1.18 buildinfo encoding.
The binary is base64 encoded to hide it from security scanners that believe a
Go 1.17 is inherently insecure.
Generate go117.base64 with:
$ GOTOOLCHAIN=go1.17 GOOS=linux GOARCH=amd64 go build -trimpath
$ base64 go117 > go117.base64
$ rm go117
TODO(prattmic): Ideally this would be built on the fly to better cover all
executable formats, but then we need a network connection to download an old Go
toolchain.

View File

@ -0,0 +1,3 @@
module example.com/go117
go 1.17

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
// 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.
package main
func main() {}

Binary file not shown.

View File

@ -0,0 +1,17 @@
notgo.base64 is a base64-encoded C hello world binary used to test
debug/buildinfo errors on non-Go binaries.
The binary is base64 encoded to hide it from security scanners that might not
like it.
Generate notgo.base64 on linux-amd64 with:
$ cc -o notgo main.c
$ base64 notgo > notgo.base64
$ rm notgo
The current binary was built with "gcc version 14.2.0 (Debian 14.2.0-3+build4)".
TODO(prattmic): Ideally this would be built on the fly to better cover all
executable formats, but then we need to encode the intricacies of calling each
platform's C compiler.

View File

@ -0,0 +1,7 @@
// 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.
int main(void) {
return 0;
}

View File

@ -0,0 +1,278 @@
f0VMRgIBAQAAAAAAAAAAAAMAPgABAAAAQBAAAAAAAABAAAAAAAAAAGA2AAAAAAAAAAAAAEAAOAAN
AEAAHgAdAAYAAAAEAAAAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAA2AIAAAAAAADYAgAAAAAAAAgA
AAAAAAAAAwAAAAQAAAAYAwAAAAAAABgDAAAAAAAAGAMAAAAAAAAcAAAAAAAAABwAAAAAAAAAAQAA
AAAAAAABAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAFAAAAAAAA4AUAAAAAAAAAEAAA
AAAAAAEAAAAFAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAPQEAAAAAAAA9AQAAAAAAAAAQAAAA
AAAAAQAAAAQAAAAAIAAAAAAAAAAgAAAAAAAAACAAAAAAAADcAAAAAAAAANwAAAAAAAAAABAAAAAA
AAABAAAABgAAAAAuAAAAAAAAAD4AAAAAAAAAPgAAAAAAABACAAAAAAAAGAIAAAAAAAAAEAAAAAAA
AAIAAAAGAAAAEC4AAAAAAAAQPgAAAAAAABA+AAAAAAAAsAEAAAAAAACwAQAAAAAAAAgAAAAAAAAA
BAAAAAQAAAA4AwAAAAAAADgDAAAAAAAAOAMAAAAAAAAgAAAAAAAAACAAAAAAAAAACAAAAAAAAAAE
AAAABAAAAFgDAAAAAAAAWAMAAAAAAABYAwAAAAAAAEQAAAAAAAAARAAAAAAAAAAEAAAAAAAAAFPl
dGQEAAAAOAMAAAAAAAA4AwAAAAAAADgDAAAAAAAAIAAAAAAAAAAgAAAAAAAAAAgAAAAAAAAAUOV0
ZAQAAAAEIAAAAAAAAAQgAAAAAAAABCAAAAAAAAAsAAAAAAAAACwAAAAAAAAABAAAAAAAAABR5XRk
BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAFLldGQE
AAAAAC4AAAAAAAAAPgAAAAAAAAA+AAAAAAAAAAIAAAAAAAAAAgAAAAAAAAEAAAAAAAAAL2xpYjY0
L2xkLWxpbnV4LXg4Ni02NC5zby4yAAAAAAAEAAAAEAAAAAUAAABHTlUAAoAAwAQAAAABAAAAAAAA
AAQAAAAUAAAAAwAAAEdOVQB5fSf98eWTEBscIbS6nrsfguPLDgQAAAAQAAAAAQAAAEdOVQAAAAAA
AwAAAAIAAAAAAAAAAAAAAAIAAAAFAAAAAQAAAAYAAAAAAIEAAAAAAAUAAAAAAAAA0WXObQAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAEgAAAAAAAAAAAAAAAAAAAAAAAABDAAAAIAAAAAAA
AAAAAAAAAAAAAAAAAABfAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABuAAAAIAAAAAAAAAAAAAAAAAAA
AAAAAAATAAAAIgAAAAAAAAAAAAAAAAAAAAAAAAAAX19saWJjX3N0YXJ0X21haW4AX19jeGFfZmlu
YWxpemUAbGliYy5zby42AEdMSUJDXzIuMi41AEdMSUJDXzIuMzQAX0lUTV9kZXJlZ2lzdGVyVE1D
bG9uZVRhYmxlAF9fZ21vbl9zdGFydF9fAF9JVE1fcmVnaXN0ZXJUTUNsb25lVGFibGUAAAACAAEA
AQABAAMAAAAAAAEAAgAiAAAAEAAAAAAAAAB1GmkJAAADACwAAAAQAAAAtJGWBgAAAgA4AAAAAAAA
AAA+AAAAAAAACAAAAAAAAAAgEQAAAAAAAAg+AAAAAAAACAAAAAAAAADgEAAAAAAAAAhAAAAAAAAA
CAAAAAAAAAAIQAAAAAAAAMA/AAAAAAAABgAAAAEAAAAAAAAAAAAAAMg/AAAAAAAABgAAAAIAAAAA
AAAAAAAAANA/AAAAAAAABgAAAAMAAAAAAAAAAAAAANg/AAAAAAAABgAAAAQAAAAAAAAAAAAAAOA/
AAAAAAAABgAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEiD7AhIiwXF
LwAASIXAdAL/0EiDxAjDAAAAAAAAAAAA/zXKLwAA/yXMLwAADx9AAP8lqi8AAGaQAAAAAAAAAAAx
7UmJ0V5IieJIg+TwUFRFMcAxyUiNPc4AAAD/FV8vAAD0Zi4PH4QAAAAAAA8fQABIjT2ZLwAASI0F
ki8AAEg5+HQVSIsFPi8AAEiFwHQJ/+APH4AAAAAAww8fgAAAAABIjT1pLwAASI01Yi8AAEgp/kiJ
8EjB7j9IwfgDSAHGSNH+dBRIiwUNLwAASIXAdAj/4GYPH0QAAMMPH4AAAAAA8w8e+oA9JS8AAAB1
K1VIgz3qLgAAAEiJ5XQMSIs9Bi8AAOgp////6GT////GBf0uAAABXcMPHwDDDx+AAAAAAPMPHvrp
d////1VIieW4AAAAAF3DSIPsCEiDxAjDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIAARsDOygAAAAEAAAA
HPD//3QAAAAs8P//nAAAADzw//9EAAAAJfH//7QAAAAUAAAAAAAAAAF6UgABeBABGwwHCJABBxAU
AAAAHAAAAPDv//8iAAAAAAAAAAAAAAAUAAAAAAAAAAF6UgABeBABGwwHCJABAAAkAAAAHAAAAKDv
//8QAAAAAA4QRg4YSg8LdwiAAD8aOyozJCIAAAAAFAAAAEQAAACI7///CAAAAAAAAAAAAAAAHAAA
AFwAAABp8P//CwAAAABBDhCGAkMNBkYMBwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACARAAAAAAAA4BAAAAAAAAABAAAAAAAA
ACIAAAAAAAAADAAAAAAAAAAAEAAAAAAAAA0AAAAAAAAANBEAAAAAAAAZAAAAAAAAAAA+AAAAAAAA
GwAAAAAAAAAIAAAAAAAAABoAAAAAAAAACD4AAAAAAAAcAAAAAAAAAAgAAAAAAAAA9f7/bwAAAACg
AwAAAAAAAAUAAAAAAAAAWAQAAAAAAAAGAAAAAAAAAMgDAAAAAAAACgAAAAAAAACIAAAAAAAAAAsA
AAAAAAAAGAAAAAAAAAAVAAAAAAAAAAAAAAAAAAAAAwAAAAAAAADoPwAAAAAAAAcAAAAAAAAAIAUA
AAAAAAAIAAAAAAAAAMAAAAAAAAAACQAAAAAAAAAYAAAAAAAAAPv//28AAAAAAAAACAAAAAD+//9v
AAAAAPAEAAAAAAAA////bwAAAAABAAAAAAAAAPD//28AAAAA4AQAAAAAAAD5//9vAAAAAAMAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAED4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAAAEdDQzogKERl
YmlhbiAxNC4yLjAtMytidWlsZDQpIDE0LjIuMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB
AAAABADx/wAAAAAAAAAAAAAAAAAAAAAJAAAAAQAEAHwDAAAAAAAAIAAAAAAAAAATAAAABADx/wAA
AAAAAAAAAAAAAAAAAAAeAAAAAgAOAHAQAAAAAAAAAAAAAAAAAAAgAAAAAgAOAKAQAAAAAAAAAAAA
AAAAAAAzAAAAAgAOAOAQAAAAAAAAAAAAAAAAAABJAAAAAQAZABBAAAAAAAAAAQAAAAAAAABVAAAA
AQAUAAg+AAAAAAAAAAAAAAAAAAB8AAAAAgAOACARAAAAAAAAAAAAAAAAAACIAAAAAQATAAA+AAAA
AAAAAAAAAAAAAACnAAAABADx/wAAAAAAAAAAAAAAAAAAAAATAAAABADx/wAAAAAAAAAAAAAAAAAA
AACuAAAAAQASANggAAAAAAAAAAAAAAAAAAAAAAAABADx/wAAAAAAAAAAAAAAAAAAAAC8AAAAAQAV
ABA+AAAAAAAAAAAAAAAAAADFAAAAAAARAAQgAAAAAAAAAAAAAAAAAADYAAAAAQAXAOg/AAAAAAAA
AAAAAAAAAADuAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAALAQAAIAAAAAAAAAAAAAAAAAAAAAAAAAA2
AQAAIAAYAABAAAAAAAAAAAAAAAAAAAAnAQAAEAAYABBAAAAAAAAAAAAAAAAAAAAuAQAAEgIPADQR
AAAAAAAAAAAAAAAAAAA0AQAAEAAYAABAAAAAAAAAAAAAAAAAAABBAQAAIAAAAAAAAAAAAAAAAAAA
AAAAAABQAQAAEQIYAAhAAAAAAAAAAAAAAAAAAABdAQAAEQAQAAAgAAAAAAAABAAAAAAAAABsAQAA
EAAZABhAAAAAAAAAAAAAAAAAAAA6AQAAEgAOAEAQAAAAAAAAIgAAAAAAAABxAQAAEAAZABBAAAAA
AAAAAAAAAAAAAAB9AQAAEgAOACkRAAAAAAAACwAAAAAAAACCAQAAEQIYABBAAAAAAAAAAAAAAAAA
AACOAQAAIAAAAAAAAAAAAAAAAAAAAAAAAACoAQAAIgAAAAAAAAAAAAAAAAAAAAAAAADDAQAAEgIL
AAAQAAAAAAAAAAAAAAAAAAAAU2NydDEubwBfX2FiaV90YWcAY3J0c3R1ZmYuYwBkZXJlZ2lzdGVy
X3RtX2Nsb25lcwBfX2RvX2dsb2JhbF9kdG9yc19hdXgAY29tcGxldGVkLjAAX19kb19nbG9iYWxf
ZHRvcnNfYXV4X2ZpbmlfYXJyYXlfZW50cnkAZnJhbWVfZHVtbXkAX19mcmFtZV9kdW1teV9pbml0
X2FycmF5X2VudHJ5AG1haW4uYwBfX0ZSQU1FX0VORF9fAF9EWU5BTUlDAF9fR05VX0VIX0ZSQU1F
X0hEUgBfR0xPQkFMX09GRlNFVF9UQUJMRV8AX19saWJjX3N0YXJ0X21haW5AR0xJQkNfMi4zNABf
SVRNX2RlcmVnaXN0ZXJUTUNsb25lVGFibGUAX2VkYXRhAF9maW5pAF9fZGF0YV9zdGFydABfX2dt
b25fc3RhcnRfXwBfX2Rzb19oYW5kbGUAX0lPX3N0ZGluX3VzZWQAX2VuZABfX2Jzc19zdGFydABt
YWluAF9fVE1DX0VORF9fAF9JVE1fcmVnaXN0ZXJUTUNsb25lVGFibGUAX19jeGFfZmluYWxpemVA
R0xJQkNfMi4yLjUAX2luaXQAAC5zeW10YWIALnN0cnRhYgAuc2hzdHJ0YWIALmludGVycAAubm90
ZS5nbnUucHJvcGVydHkALm5vdGUuZ251LmJ1aWxkLWlkAC5ub3RlLkFCSS10YWcALmdudS5oYXNo
AC5keW5zeW0ALmR5bnN0cgAuZ251LnZlcnNpb24ALmdudS52ZXJzaW9uX3IALnJlbGEuZHluAC5p
bml0AC5wbHQuZ290AC50ZXh0AC5maW5pAC5yb2RhdGEALmVoX2ZyYW1lX2hkcgAuZWhfZnJhbWUA
LmluaXRfYXJyYXkALmZpbmlfYXJyYXkALmR5bmFtaWMALmdvdC5wbHQALmRhdGEALmJzcwAuY29t
bWVudAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAABsAAAABAAAAAgAAAAAAAAAYAwAAAAAAABgDAAAAAAAAHAAAAAAA
AAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAjAAAABwAAAAIAAAAAAAAAOAMAAAAAAAA4AwAAAAAA
ACAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAANgAAAAcAAAACAAAAAAAAAFgDAAAAAAAA
WAMAAAAAAAAkAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAEkAAAAHAAAAAgAAAAAAAAB8
AwAAAAAAAHwDAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAABXAAAA9v//bwIA
AAAAAAAAoAMAAAAAAACgAwAAAAAAACQAAAAAAAAABgAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAYQAA
AAsAAAACAAAAAAAAAMgDAAAAAAAAyAMAAAAAAACQAAAAAAAAAAcAAAABAAAACAAAAAAAAAAYAAAA
AAAAAGkAAAADAAAAAgAAAAAAAABYBAAAAAAAAFgEAAAAAAAAiAAAAAAAAAAAAAAAAAAAAAEAAAAA
AAAAAAAAAAAAAABxAAAA////bwIAAAAAAAAA4AQAAAAAAADgBAAAAAAAAAwAAAAAAAAABgAAAAAA
AAACAAAAAAAAAAIAAAAAAAAAfgAAAP7//28CAAAAAAAAAPAEAAAAAAAA8AQAAAAAAAAwAAAAAAAA
AAcAAAABAAAACAAAAAAAAAAAAAAAAAAAAI0AAAAEAAAAAgAAAAAAAAAgBQAAAAAAACAFAAAAAAAA
wAAAAAAAAAAGAAAAAAAAAAgAAAAAAAAAGAAAAAAAAACXAAAAAQAAAAYAAAAAAAAAABAAAAAAAAAA
EAAAAAAAABcAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAA9wAAAAEAAAAGAAAAAAAAACAQ
AAAAAAAAIBAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAJ0AAAABAAAABgAA
AAAAAAAwEAAAAAAAADAQAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAACmAAAA
AQAAAAYAAAAAAAAAQBAAAAAAAABAEAAAAAAAAPQAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAA
AAAArAAAAAEAAAAGAAAAAAAAADQRAAAAAAAANBEAAAAAAAAJAAAAAAAAAAAAAAAAAAAABAAAAAAA
AAAAAAAAAAAAALIAAAABAAAAEgAAAAAAAAAAIAAAAAAAAAAgAAAAAAAABAAAAAAAAAAAAAAAAAAA
AAQAAAAAAAAABAAAAAAAAAC6AAAAAQAAAAIAAAAAAAAABCAAAAAAAAAEIAAAAAAAACwAAAAAAAAA
AAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAyAAAAAEAAAACAAAAAAAAADAgAAAAAAAAMCAAAAAAAACs
AAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAANIAAAAOAAAAAwAAAAAAAAAAPgAAAAAAAAAu
AAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAAAADeAAAADwAAAAMAAAAAAAAACD4A
AAAAAAAILgAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAA6gAAAAYAAAADAAAA
AAAAABA+AAAAAAAAEC4AAAAAAACwAQAAAAAAAAcAAAAAAAAACAAAAAAAAAAQAAAAAAAAAKEAAAAB
AAAAAwAAAAAAAADAPwAAAAAAAMAvAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAAAAA
AADzAAAAAQAAAAMAAAAAAAAA6D8AAAAAAADoLwAAAAAAABgAAAAAAAAAAAAAAAAAAAAIAAAAAAAA
AAgAAAAAAAAA/AAAAAEAAAADAAAAAAAAAABAAAAAAAAAADAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA
CAAAAAAAAAAAAAAAAAAAAAIBAAAIAAAAAwAAAAAAAAAQQAAAAAAAABAwAAAAAAAACAAAAAAAAAAA
AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAHAQAAAQAAADAAAAAAAAAAAAAAAAAAAAAQMAAAAAAAACUA
AAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAODAA
AAAAAABIAwAAAAAAABwAAAASAAAACAAAAAAAAAAYAAAAAAAAAAkAAAADAAAAAAAAAAAAAAAAAAAA
AAAAAIAzAAAAAAAAyQEAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAARAAAAAwAAAAAAAAAA
AAAAAAAAAAAAAABJNQAAAAAAABABAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA

View File

@ -4,7 +4,7 @@ go 1.24
require (
golang.org/x/crypto v0.30.0
golang.org/x/net v0.32.1-0.20250121202134-9a960c88dd98
golang.org/x/net v0.32.1-0.20250304185419-76f9bf3279ef
)
require (

View File

@ -1,7 +1,7 @@
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/net v0.32.1-0.20250121202134-9a960c88dd98 h1:36bTiCRO7f/J3t+LumnLTJDXqxsp1x6Q7754SsRD9u4=
golang.org/x/net v0.32.1-0.20250121202134-9a960c88dd98/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/net v0.32.1-0.20250304185419-76f9bf3279ef h1:oQtTn7aH5kyi7dPmG2Eot3aG1XBwnkrX+zIq+lNeZeM=
golang.org/x/net v0.32.1-0.20250304185419-76f9bf3279ef/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=

View File

@ -207,7 +207,7 @@ func (check *Checker) lhsVar(lhs ast.Expr) Type {
// dot-imported variables.
if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
v = w
v_used = v.used
v_used = check.usedVars[v]
}
}
}
@ -216,7 +216,7 @@ func (check *Checker) lhsVar(lhs ast.Expr) Type {
check.expr(nil, &x, lhs)
if v != nil {
v.used = v_used // restore v.used
check.usedVars[v] = v_used // restore v.used
}
if x.mode == invalid || !isValid(x.typ) {

View File

@ -689,7 +689,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *TypeName, w
if pname, _ := obj.(*PkgName); pname != nil {
assert(pname.pkg == check.pkg)
check.recordUse(ident, pname)
pname.used = true
check.usedPkgNames[pname] = true
pkg := pname.imported
var exp Object
@ -1020,13 +1020,13 @@ func (check *Checker) use1(e ast.Expr, lhs bool) bool {
// dot-imported variables.
if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
v = w
v_used = v.used
v_used = check.usedVars[v]
}
}
}
check.exprOrType(&x, n, true)
if v != nil {
v.used = v_used // restore v.used
check.usedVars[v] = v_used // restore v.used
}
default:
check.rawExpr(nil, &x, e, nil, true)

View File

@ -182,6 +182,8 @@ type Checker struct {
dotImportMap map[dotImportKey]*PkgName // maps dot-imported objects to the package they were dot-imported through
brokenAliases map[*TypeName]bool // set of aliases with broken (not yet determined) types
unionTypeSets map[*Union]*_TypeSet // computed type sets for union types
usedVars map[*Var]bool // set of used variables
usedPkgNames map[*PkgName]bool // set of used package names
mono monoGraph // graph for detecting non-monomorphizable instantiation loops
firstErr error // first error encountered
@ -308,13 +310,15 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch
conf._EnableAlias = gotypesalias.Value() != "0"
return &Checker{
conf: conf,
ctxt: conf.Context,
fset: fset,
pkg: pkg,
Info: info,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
conf: conf,
ctxt: conf.Context,
fset: fset,
pkg: pkg,
Info: info,
objMap: make(map[Object]*declInfo),
impMap: make(map[importKey]*Package),
usedVars: make(map[*Var]bool),
usedPkgNames: make(map[*PkgName]bool),
}
}
@ -322,6 +326,8 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch
// The provided files must all belong to the same package.
func (check *Checker) initFiles(files []*ast.File) {
// start with a clean slate (check.Files may be called multiple times)
// TODO(gri): what determines which fields are zeroed out here, vs at the end
// of checkFiles?
check.files = nil
check.imports = nil
check.dotImportMap = nil
@ -333,6 +339,13 @@ func (check *Checker) initFiles(files []*ast.File) {
check.objPath = nil
check.cleaners = nil
// We must initialize usedVars and usedPkgNames both here and in NewChecker,
// because initFiles is not called in the CheckExpr or Eval codepaths, yet we
// want to free this memory at the end of Files ('used' predicates are
// only needed in the context of a given file).
check.usedVars = make(map[*Var]bool)
check.usedPkgNames = make(map[*PkgName]bool)
// determine package name and collect valid files
pkg := check.pkg
for _, file := range files {
@ -507,9 +520,12 @@ func (check *Checker) checkFiles(files []*ast.File) {
check.seenPkgMap = nil
check.brokenAliases = nil
check.unionTypeSets = nil
check.usedVars = nil
check.usedPkgNames = nil
check.ctxt = nil
// TODO(rFindley) There's more memory we should release at this point.
// TODO(gri): shouldn't the cleanup above occur after the bailout?
// TODO(gri) There's more memory we should release at this point.
}
// processDelayed processes all delayed actions pushed after top.

View File

@ -245,13 +245,12 @@ func (a *object) cmp(b *object) int {
type PkgName struct {
object
imported *Package
used bool // set if the package was used
}
// NewPkgName returns a new PkgName object representing an imported package.
// The remaining arguments set the attributes found with all Objects.
func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported}
}
// Imported returns the package that was imported.
@ -334,10 +333,10 @@ func (obj *TypeName) IsAlias() bool {
// A Variable represents a declared variable (including function parameters and results, and struct fields).
type Var struct {
object
origin *Var // if non-nil, the Var from which this one was instantiated
embedded bool // if set, the variable is an embedded struct field, and name is the type name
isField bool // var is struct field
used bool // set if the variable was used
origin *Var // if non-nil, the Var from which this one was instantiated
isParam bool // var is a param, for backport of 'used' check to go1.24 (go.dev/issue/72826)
}
// NewVar returns a new variable.
@ -348,7 +347,7 @@ func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
// NewParam returns a new variable representing a function parameter.
func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true} // parameters are always 'used'
return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, isParam: true}
}
// NewField returns a new variable representing a struct field.

View File

@ -310,7 +310,7 @@ func (check *Checker) collectObjects() {
if imp.fake {
// match 1.17 cmd/compile (not prescribed by spec)
pkgName.used = true
check.usedPkgNames[pkgName] = true
}
// add import to file scope
@ -710,7 +710,7 @@ func (check *Checker) unusedImports() {
// (initialization), use the blank identifier as explicit package name."
for _, obj := range check.imports {
if !obj.used && obj.name != "_" {
if obj.name != "_" && !check.usedPkgNames[obj] {
check.errorUnusedPkg(obj)
}
}

View File

@ -35,7 +35,7 @@ func TestSizeof(t *testing.T) {
{term{}, 12, 24},
// Objects
{PkgName{}, 48, 88},
{PkgName{}, 44, 80},
{Const{}, 48, 88},
{TypeName{}, 40, 72},
{Var{}, 48, 88},

View File

@ -59,7 +59,7 @@ func (check *Checker) usage(scope *Scope) {
var unused []*Var
for name, elem := range scope.elems {
elem = resolve(name, elem)
if v, _ := elem.(*Var); v != nil && !v.used {
if v, _ := elem.(*Var); v != nil && !v.isParam && !check.usedVars[v] {
unused = append(unused, v)
}
}
@ -777,13 +777,16 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
}
// If lhs exists, we must have at least one lhs variable that was used.
// (We can't use check.usage because that only looks at one scope; and
// we don't want to use the same variable for all scopes and change the
// variable type underfoot.)
if lhs != nil {
var used bool
for _, v := range lhsVars {
if v.used {
if check.usedVars[v] {
used = true
}
v.used = true // avoid usage error when checking entire function
check.usedVars[v] = true // avoid usage error when checking entire function
}
if !used {
check.softErrorf(lhs, UnusedVar, "%s declared and not used", lhs.Name)
@ -952,7 +955,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *ast.RangeStmt) {
if typ == nil || typ == Typ[Invalid] {
// typ == Typ[Invalid] can happen if allowVersion fails.
obj.typ = Typ[Invalid]
obj.used = true // don't complain about unused variable
check.usedVars[obj] = true // don't complain about unused variable
continue
}

View File

@ -54,7 +54,7 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bo
// avoid "declared but not used" errors
// (don't use Checker.use - we don't want to evaluate too much)
if v, _ := obj.(*Var); v != nil && v.pkg == check.pkg /* see Checker.use1 */ {
v.used = true
check.usedVars[v] = true
}
return
}
@ -82,7 +82,7 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bo
// (This code is only needed for dot-imports. Without them,
// we only have to mark variables, see *Var case below).
if pkgName := check.dotImportMap[dotImportKey{scope, obj.Name()}]; pkgName != nil {
pkgName.used = true
check.usedPkgNames[pkgName] = true
}
switch obj := obj.(type) {
@ -119,7 +119,7 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bo
// from other packages to avoid potential race conditions with
// dot-imported variables.
if obj.pkg == check.pkg {
obj.used = true
check.usedVars[obj] = true
}
check.addDeclDep(obj)
if !isValid(typ) {

View File

@ -28,6 +28,7 @@ var All = []Info{
{Name: "asynctimerchan", Package: "time", Changed: 23, Old: "1"},
{Name: "dataindependenttiming", Package: "crypto/subtle", Opaque: true},
{Name: "execerrdot", Package: "os/exec"},
{Name: "fips140", Package: "crypto/fips140", Opaque: true},
{Name: "gocachehash", Package: "cmd/go"},
{Name: "gocachetest", Package: "cmd/go"},
{Name: "gocacheverify", Package: "cmd/go"},
@ -58,8 +59,8 @@ var All = []Info{
{Name: "tlsmlkem", Package: "crypto/tls", Changed: 24, Old: "0", Opaque: true},
{Name: "tlsrsakex", Package: "crypto/tls", Changed: 22, Old: "1"},
{Name: "tlsunsafeekm", Package: "crypto/tls", Changed: 22, Old: "1"},
{Name: "winreadlinkvolume", Package: "os", Changed: 22, Old: "0"},
{Name: "winsymlink", Package: "os", Changed: 22, Old: "0"},
{Name: "winreadlinkvolume", Package: "os", Changed: 23, Old: "0"},
{Name: "winsymlink", Package: "os", Changed: 23, Old: "0"},
{Name: "x509keypairleaf", Package: "crypto/tls", Changed: 23, Old: "0"},
{Name: "x509negativeserial", Package: "crypto/x509", Changed: 23, Old: "1"},
{Name: "x509rsacrt", Package: "crypto/x509", Changed: 24, Old: "0"},

View File

@ -504,3 +504,26 @@ func ParallelOn64Bit(t *testing.T) {
}
t.Parallel()
}
// CPUProfilingBroken returns true if CPU profiling has known issues on this
// platform.
func CPUProfilingBroken() bool {
switch runtime.GOOS {
case "plan9":
// Profiling unimplemented.
return true
case "aix":
// See https://golang.org/issue/45170.
return true
case "ios", "dragonfly", "netbsd", "illumos", "solaris":
// See https://golang.org/issue/13841.
return true
case "openbsd":
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
// See https://golang.org/issue/13841.
return true
}
}
return false
}

View File

@ -164,6 +164,19 @@ func readChunkLine(b *bufio.Reader) ([]byte, error) {
}
return nil, err
}
// RFC 9112 permits parsers to accept a bare \n as a line ending in headers,
// but not in chunked encoding lines. See https://www.rfc-editor.org/errata/eid7633,
// which explicitly rejects a clarification permitting \n as a chunk terminator.
//
// Verify that the line ends in a CRLF, and that no CRs appear before the end.
if idx := bytes.IndexByte(p, '\r'); idx == -1 {
return nil, errors.New("chunked line ends with bare LF")
} else if idx != len(p)-2 {
return nil, errors.New("invalid CR in chunked line")
}
p = p[:len(p)-2] // trim CRLF
if len(p) >= maxLineLength {
return nil, ErrLineTooLong
}
@ -171,14 +184,14 @@ func readChunkLine(b *bufio.Reader) ([]byte, error) {
}
func trimTrailingWhitespace(b []byte) []byte {
for len(b) > 0 && isASCIISpace(b[len(b)-1]) {
for len(b) > 0 && isOWS(b[len(b)-1]) {
b = b[:len(b)-1]
}
return b
}
func isASCIISpace(b byte) bool {
return b == ' ' || b == '\t' || b == '\n' || b == '\r'
func isOWS(b byte) bool {
return b == ' ' || b == '\t'
}
var semi = []byte(";")

View File

@ -280,6 +280,33 @@ func TestChunkReaderByteAtATime(t *testing.T) {
}
}
func TestChunkInvalidInputs(t *testing.T) {
for _, test := range []struct {
name string
b string
}{{
name: "bare LF in chunk size",
b: "1\na\r\n0\r\n",
}, {
name: "extra LF in chunk size",
b: "1\r\r\na\r\n0\r\n",
}, {
name: "bare LF in chunk data",
b: "1\r\na\n0\r\n",
}, {
name: "bare LF in chunk extension",
b: "1;\na\r\n0\r\n",
}} {
t.Run(test.name, func(t *testing.T) {
r := NewChunkedReader(strings.NewReader(test.b))
got, err := io.ReadAll(r)
if err == nil {
t.Fatalf("unexpectedly parsed invalid chunked data:\n%q", got)
}
})
}
}
type funcReader struct {
f func(iteration int) ([]byte, error)
i int

View File

@ -13,6 +13,7 @@ import (
"compress/zlib"
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
@ -7303,3 +7304,120 @@ func testServerReadAfterHandlerAbort100Continue(t *testing.T, mode testMode) {
readyc <- struct{}{} // server starts reading from the request body
readyc <- struct{}{} // server finishes reading from the request body
}
// Issue #72100: Verify that we don't modify the caller's TLS.Config.NextProtos slice.
func TestServerTLSNextProtos(t *testing.T) {
run(t, testServerTLSNextProtos, []testMode{https1Mode, http2Mode})
}
func testServerTLSNextProtos(t *testing.T, mode testMode) {
CondSkipHTTP2(t)
cert, err := tls.X509KeyPair(testcert.LocalhostCert, testcert.LocalhostKey)
if err != nil {
t.Fatal(err)
}
leafCert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
t.Fatal(err)
}
certpool := x509.NewCertPool()
certpool.AddCert(leafCert)
protos := new(Protocols)
switch mode {
case https1Mode:
protos.SetHTTP1(true)
case http2Mode:
protos.SetHTTP2(true)
}
wantNextProtos := []string{"http/1.1", "h2", "other"}
nextProtos := slices.Clone(wantNextProtos)
// We don't use httptest here because it overrides the tls.Config.
srv := &Server{
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{cert},
NextProtos: nextProtos,
},
Handler: HandlerFunc(func(w ResponseWriter, req *Request) {}),
Protocols: protos,
}
tr := &Transport{
TLSClientConfig: &tls.Config{
RootCAs: certpool,
NextProtos: nextProtos,
},
Protocols: protos,
}
listener := newLocalListener(t)
srvc := make(chan error, 1)
go func() {
srvc <- srv.ServeTLS(listener, "", "")
}()
t.Cleanup(func() {
srv.Close()
<-srvc
})
client := &Client{Transport: tr}
resp, err := client.Get("https://" + listener.Addr().String())
if err != nil {
t.Fatal(err)
}
resp.Body.Close()
if !slices.Equal(nextProtos, wantNextProtos) {
t.Fatalf("after running test: original NextProtos slice = %v, want %v", nextProtos, wantNextProtos)
}
}
func TestInvalidChunkedBodies(t *testing.T) {
for _, test := range []struct {
name string
b string
}{{
name: "bare LF in chunk size",
b: "1\na\r\n0\r\n\r\n",
}, {
name: "bare LF at body end",
b: "1\r\na\r\n0\r\n\n",
}} {
t.Run(test.name, func(t *testing.T) {
reqc := make(chan error)
ts := newClientServerTest(t, http1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
got, err := io.ReadAll(r.Body)
if err == nil {
t.Logf("read body: %q", got)
}
reqc <- err
})).ts
serverURL, err := url.Parse(ts.URL)
if err != nil {
t.Fatal(err)
}
conn, err := net.Dial("tcp", serverURL.Host)
if err != nil {
t.Fatal(err)
}
if _, err := conn.Write([]byte(
"POST / HTTP/1.1\r\n" +
"Host: localhost\r\n" +
"Transfer-Encoding: chunked\r\n" +
"Connection: close\r\n" +
"\r\n" +
test.b)); err != nil {
t.Fatal(err)
}
conn.(*net.TCPConn).CloseWrite()
if err := <-reqc; err == nil {
t.Errorf("server handler: io.ReadAll(r.Body) succeeded, want error")
}
})
}
}

View File

@ -3521,6 +3521,12 @@ func (s *Server) protocols() Protocols {
// adjustNextProtos adds or removes "http/1.1" and "h2" entries from
// a tls.Config.NextProtos list, according to the set of protocols in protos.
func adjustNextProtos(nextProtos []string, protos Protocols) []string {
// Make a copy of NextProtos since it might be shared with some other tls.Config.
// (tls.Config.Clone doesn't do a deep copy.)
//
// We could avoid an allocation in the common case by checking to see if the slice
// is already in order, but this is just one small allocation per connection.
nextProtos = slices.Clone(nextProtos)
var have Protocols
nextProtos = slices.DeleteFunc(nextProtos, func(s string) bool {
switch s {

View File

@ -11,12 +11,15 @@ import (
"internal/testenv"
"io"
"os"
"os/exec"
"os/signal"
"os/user"
"path/filepath"
"runtime"
"slices"
"strconv"
"strings"
"sync"
"syscall"
"testing"
"time"
@ -24,6 +27,7 @@ import (
func init() {
registerHelperCommand("pwd", cmdPwd)
registerHelperCommand("signaltest", cmdSignalTest)
}
func cmdPwd(...string) {
@ -274,3 +278,55 @@ func TestExplicitPWD(t *testing.T) {
})
}
}
// Issue 71828.
func TestSIGCHLD(t *testing.T) {
cmd := helperCommand(t, "signaltest")
out, err := cmd.CombinedOutput()
t.Logf("%s", out)
if err != nil {
t.Error(err)
}
}
// cmdSignaltest is for TestSIGCHLD.
// This runs in a separate process because the bug only happened
// the first time that a child process was started.
func cmdSignalTest(...string) {
chSig := make(chan os.Signal, 1)
signal.Notify(chSig, syscall.SIGCHLD)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
c := 0
for range chSig {
c++
fmt.Printf("SIGCHLD %d\n", c)
if c > 1 {
fmt.Println("too many SIGCHLD signals")
os.Exit(1)
}
}
}()
defer func() {
signal.Reset(syscall.SIGCHLD)
close(chSig)
wg.Wait()
}()
exe, err := os.Executable()
if err != nil {
fmt.Printf("os.Executable failed: %v\n", err)
os.Exit(1)
}
cmd := exec.Command(exe, "hang", "200ms")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Printf("failed to run child process: %v\n", err)
os.Exit(1)
}
}

View File

@ -3848,3 +3848,14 @@ func TestRemoveReadOnlyFile(t *testing.T) {
}
})
}
func TestOpenFileDevNull(t *testing.T) {
// See https://go.dev/issue/71752.
t.Parallel()
f, err := OpenFile(DevNull, O_WRONLY|O_CREATE|O_TRUNC, 0o644)
if err != nil {
t.Fatalf("OpenFile(DevNull): %v", err)
}
f.Close()
}

View File

@ -60,7 +60,7 @@ func OpenInRoot(dir, name string) (*File, error) {
// - When GOOS=plan9 or GOOS=js, Root does not track directories across renames.
// On these platforms, a Root references a directory name, not a file descriptor.
type Root struct {
root root
root *root
}
const (

View File

@ -49,7 +49,7 @@ func newRoot(name string) (*Root, error) {
if !fi.IsDir() {
return nil, errors.New("not a directory")
}
return &Root{root{name: name}}, nil
return &Root{&root{name: name}}, nil
}
func (r *root) Close() error {

View File

@ -48,11 +48,11 @@ func newRoot(fd int, name string) (*Root, error) {
syscall.CloseOnExec(fd)
}
r := &Root{root{
r := &Root{&root{
fd: fd,
name: name,
}}
runtime.SetFinalizer(&r.root, (*root).Close)
runtime.SetFinalizer(r.root, (*root).Close)
return r, nil
}

View File

@ -105,11 +105,11 @@ func newRoot(fd syscall.Handle, name string) (*Root, error) {
return nil, &PathError{Op: "open", Path: name, Err: errors.New("not a directory")}
}
r := &Root{root{
r := &Root{&root{
fd: fd,
name: name,
}}
runtime.SetFinalizer(&r.root, (*root).Close)
runtime.SetFinalizer(r.root, (*root).Close)
return r, nil
}

View File

@ -4,15 +4,24 @@
package reflect
import "iter"
import (
"iter"
)
func rangeNum[T int8 | int16 | int32 | int64 | int |
uint8 | uint16 | uint32 | uint64 | uint |
uintptr, N int64 | uint64](v N) iter.Seq[Value] {
uintptr, N int64 | uint64](num N, t Type) iter.Seq[Value] {
return func(yield func(v Value) bool) {
convert := t.PkgPath() != ""
// cannot use range T(v) because no core type.
for i := T(0); i < T(v); i++ {
if !yield(ValueOf(i)) {
for i := T(0); i < T(num); i++ {
tmp := ValueOf(i)
// if the iteration value type is define by
// type T built-in type.
if convert {
tmp = tmp.Convert(t)
}
if !yield(tmp) {
return
}
}
@ -27,7 +36,7 @@ func rangeNum[T int8 | int16 | int32 | int64 | int |
// Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
// Array, Chan, Map, Slice, or String.
func (v Value) Seq() iter.Seq[Value] {
if canRangeFunc(v.typ()) {
if canRangeFunc(v.abiType()) {
return func(yield func(Value) bool) {
rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
return []Value{ValueOf(yield(in[0]))}
@ -35,29 +44,29 @@ func (v Value) Seq() iter.Seq[Value] {
v.Call([]Value{rf})
}
}
switch v.Kind() {
switch v.kind() {
case Int:
return rangeNum[int](v.Int())
return rangeNum[int](v.Int(), v.Type())
case Int8:
return rangeNum[int8](v.Int())
return rangeNum[int8](v.Int(), v.Type())
case Int16:
return rangeNum[int16](v.Int())
return rangeNum[int16](v.Int(), v.Type())
case Int32:
return rangeNum[int32](v.Int())
return rangeNum[int32](v.Int(), v.Type())
case Int64:
return rangeNum[int64](v.Int())
return rangeNum[int64](v.Int(), v.Type())
case Uint:
return rangeNum[uint](v.Uint())
return rangeNum[uint](v.Uint(), v.Type())
case Uint8:
return rangeNum[uint8](v.Uint())
return rangeNum[uint8](v.Uint(), v.Type())
case Uint16:
return rangeNum[uint16](v.Uint())
return rangeNum[uint16](v.Uint(), v.Type())
case Uint32:
return rangeNum[uint32](v.Uint())
return rangeNum[uint32](v.Uint(), v.Type())
case Uint64:
return rangeNum[uint64](v.Uint())
return rangeNum[uint64](v.Uint(), v.Type())
case Uintptr:
return rangeNum[uintptr](v.Uint())
return rangeNum[uintptr](v.Uint(), v.Type())
case Pointer:
if v.Elem().kind() != Array {
break
@ -113,7 +122,7 @@ func (v Value) Seq() iter.Seq[Value] {
// If v's kind is Pointer, the pointer element type must have kind Array.
// Otherwise v's kind must be Array, Map, Slice, or String.
func (v Value) Seq2() iter.Seq2[Value, Value] {
if canRangeFunc2(v.typ()) {
if canRangeFunc2(v.abiType()) {
return func(yield func(Value, Value) bool) {
rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
return []Value{ValueOf(yield(in[0], in[1]))}

View File

@ -7,10 +7,13 @@ package reflect_test
import (
"iter"
"maps"
"reflect"
. "reflect"
"testing"
)
type N int8
func TestValueSeq(t *testing.T) {
m := map[string]int{
"1": 1,
@ -173,6 +176,33 @@ func TestValueSeq(t *testing.T) {
t.Fatalf("should loop four times")
}
}},
{"method", ValueOf(methodIter{}).Method(0), func(t *testing.T, s iter.Seq[Value]) {
i := int64(0)
for v := range s {
if v.Int() != i {
t.Fatalf("got %d, want %d", v.Int(), i)
}
i++
}
if i != 4 {
t.Fatalf("should loop four times")
}
}},
{"type N int8", ValueOf(N(4)), func(t *testing.T, s iter.Seq[Value]) {
i := N(0)
for v := range s {
if v.Int() != int64(i) {
t.Fatalf("got %d, want %d", v.Int(), i)
}
i++
if v.Type() != reflect.TypeOf(i) {
t.Fatalf("got %s, want %s", v.Type(), reflect.TypeOf(i))
}
}
if i != 4 {
t.Fatalf("should loop four times")
}
}},
}
for _, tc := range tests {
seq := tc.val.Seq()
@ -293,9 +323,84 @@ func TestValueSeq2(t *testing.T) {
t.Fatalf("should loop four times")
}
}},
{"method", ValueOf(methodIter2{}).Method(0), func(t *testing.T, s iter.Seq2[Value, Value]) {
i := int64(0)
for v1, v2 := range s {
if v1.Int() != i {
t.Fatalf("got %d, want %d", v1.Int(), i)
}
i++
if v2.Int() != i {
t.Fatalf("got %d, want %d", v2.Int(), i)
}
}
if i != 4 {
t.Fatalf("should loop four times")
}
}},
{"[4]N", ValueOf([4]N{0, 1, 2, 3}), func(t *testing.T, s iter.Seq2[Value, Value]) {
i := N(0)
for v1, v2 := range s {
if v1.Int() != int64(i) {
t.Fatalf("got %d, want %d", v1.Int(), i)
}
if v2.Int() != int64(i) {
t.Fatalf("got %d, want %d", v2.Int(), i)
}
i++
if v2.Type() != reflect.TypeOf(i) {
t.Fatalf("got %s, want %s", v2.Type(), reflect.TypeOf(i))
}
}
if i != 4 {
t.Fatalf("should loop four times")
}
}},
{"[]N", ValueOf([]N{1, 2, 3, 4}), func(t *testing.T, s iter.Seq2[Value, Value]) {
i := N(0)
for v1, v2 := range s {
if v1.Int() != int64(i) {
t.Fatalf("got %d, want %d", v1.Int(), i)
}
i++
if v2.Int() != int64(i) {
t.Fatalf("got %d, want %d", v2.Int(), i)
}
if v2.Type() != reflect.TypeOf(i) {
t.Fatalf("got %s, want %s", v2.Type(), reflect.TypeOf(i))
}
}
if i != 4 {
t.Fatalf("should loop four times")
}
}},
}
for _, tc := range tests {
seq := tc.val.Seq2()
tc.check(t, seq)
}
}
// methodIter is a type from which we can derive a method
// value that is an iter.Seq.
type methodIter struct{}
func (methodIter) Seq(yield func(int) bool) {
for i := range 4 {
if !yield(i) {
return
}
}
}
// methodIter2 is a type from which we can derive a method
// value that is an iter.Seq2.
type methodIter2 struct{}
func (methodIter2) Seq2(yield func(int, int) bool) {
for i := range 4 {
if !yield(i, i+1) {
return
}
}
}

View File

@ -93,6 +93,9 @@ func (f flag) ro() flag {
return 0
}
// typ returns the *abi.Type stored in the Value. This method is fast,
// but it doesn't always return the correct type for the Value.
// See abiType and Type, which do return the correct type.
func (v Value) typ() *abi.Type {
// Types are either static (for compiler-created types) or
// heap-allocated but always reachable (for reflection-created
@ -2380,14 +2383,26 @@ func (v Value) Type() Type {
return v.typeSlow()
}
//go:noinline
func (v Value) typeSlow() Type {
return toRType(v.abiTypeSlow())
}
func (v Value) abiType() *abi.Type {
if v.flag != 0 && v.flag&flagMethod == 0 {
return v.typ()
}
return v.abiTypeSlow()
}
func (v Value) abiTypeSlow() *abi.Type {
if v.flag == 0 {
panic(&ValueError{"reflect.Value.Type", Invalid})
}
typ := v.typ()
if v.flag&flagMethod == 0 {
return toRType(v.typ())
return v.typ()
}
// Method value.
@ -2400,7 +2415,7 @@ func (v Value) typeSlow() Type {
panic("reflect: internal error: invalid method index")
}
m := &tt.Methods[i]
return toRType(typeOffFor(typ, m.Typ))
return typeOffFor(typ, m.Typ)
}
// Method on concrete type.
ms := typ.ExportedMethods()
@ -2408,7 +2423,7 @@ func (v Value) typeSlow() Type {
panic("reflect: internal error: invalid method index")
}
m := ms[i]
return toRType(typeOffFor(typ, m.Mtyp))
return typeOffFor(typ, m.Mtyp)
}
// CanUint reports whether [Value.Uint] can be used without panicking.

View File

@ -25,7 +25,8 @@ package cgo
// Use -fno-stack-protector to avoid problems locating the
// proper support functions. See issues #52919, #54313, #58385.
#cgo CFLAGS: -Wall -Werror -fno-stack-protector
// Use -Wdeclaration-after-statement because some CI builds use it.
#cgo CFLAGS: -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement
#cgo solaris CPPFLAGS: -D_POSIX_PTHREAD_SEMANTICS

View File

@ -76,19 +76,27 @@ threadentry(void *v)
static void
init_working_dir()
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFBundleRef bundle;
CFURLRef url_ref;
CFStringRef url_str_ref;
char buf[MAXPATHLEN];
Boolean res;
int url_len;
char *dir;
CFStringRef wd_ref;
bundle = CFBundleGetMainBundle();
if (bundle == NULL) {
fprintf(stderr, "runtime/cgo: no main bundle\n");
return;
}
CFURLRef url_ref = CFBundleCopyResourceURL(bundle, CFSTR("Info"), CFSTR("plist"), NULL);
url_ref = CFBundleCopyResourceURL(bundle, CFSTR("Info"), CFSTR("plist"), NULL);
if (url_ref == NULL) {
// No Info.plist found. It can happen on Corellium virtual devices.
return;
}
CFStringRef url_str_ref = CFURLGetString(url_ref);
char buf[MAXPATHLEN];
Boolean res = CFStringGetCString(url_str_ref, buf, sizeof(buf), kCFStringEncodingUTF8);
url_str_ref = CFURLGetString(url_ref);
res = CFStringGetCString(url_str_ref, buf, sizeof(buf), kCFStringEncodingUTF8);
CFRelease(url_ref);
if (!res) {
fprintf(stderr, "runtime/cgo: cannot get URL string\n");
@ -97,13 +105,13 @@ init_working_dir()
// url is of the form "file:///path/to/Info.plist".
// strip it down to the working directory "/path/to".
int url_len = strlen(buf);
url_len = strlen(buf);
if (url_len < sizeof("file://")+sizeof("/Info.plist")) {
fprintf(stderr, "runtime/cgo: bad URL: %s\n", buf);
return;
}
buf[url_len-sizeof("/Info.plist")+1] = 0;
char *dir = &buf[0] + sizeof("file://")-1;
dir = &buf[0] + sizeof("file://")-1;
if (chdir(dir) != 0) {
fprintf(stderr, "runtime/cgo: chdir(%s) failed\n", dir);
@ -111,7 +119,7 @@ init_working_dir()
// The test harness in go_ios_exec passes the relative working directory
// in the GoExecWrapperWorkingDirectory property of the app bundle.
CFStringRef wd_ref = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("GoExecWrapperWorkingDirectory"));
wd_ref = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("GoExecWrapperWorkingDirectory"));
if (wd_ref != NULL) {
if (!CFStringGetCString(wd_ref, buf, sizeof(buf), kCFStringEncodingUTF8)) {
fprintf(stderr, "runtime/cgo: cannot get GoExecWrapperWorkingDirectory string\n");

View File

@ -39,10 +39,11 @@ void
x_cgo_sys_thread_create(void* (*func)(void*), void* arg) {
pthread_attr_t attr;
pthread_t p;
int err;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int err = _cgo_try_pthread_create(&p, &attr, func, arg);
err = _cgo_try_pthread_create(&p, &attr, func, arg);
if (err != 0) {
fprintf(stderr, "pthread_create failed: %s", strerror(err));
abort();
@ -52,9 +53,11 @@ x_cgo_sys_thread_create(void* (*func)(void*), void* arg) {
uintptr_t
_cgo_wait_runtime_init_done(void) {
void (*pfn)(struct context_arg*);
int done;
pfn = __atomic_load_n(&cgo_context_function, __ATOMIC_CONSUME);
int done = 2;
done = 2;
if (__atomic_load_n(&runtime_init_done, __ATOMIC_CONSUME) != done) {
pthread_mutex_lock(&runtime_init_mu);
while (__atomic_load_n(&runtime_init_done, __ATOMIC_CONSUME) == 0) {

View File

@ -75,8 +75,10 @@ x_cgo_sys_thread_create(void (*func)(void*), void* arg) {
int
_cgo_is_runtime_initialized() {
int status;
EnterCriticalSection(&runtime_init_cs);
int status = runtime_init_done;
status = runtime_init_done;
LeaveCriticalSection(&runtime_init_cs);
return status;
}

View File

@ -355,7 +355,9 @@ func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
gp.m.incgo = true
unlockOSThread()
if gp.m.isextra {
if gp.m.isextra && gp.m.ncgo == 0 {
// There are no active cgocalls above this frame (ncgo == 0),
// thus there can't be more Go frames above this frame.
gp.m.isExtraInC = true
}

View File

@ -72,6 +72,22 @@ func TestCgoCallbackGC(t *testing.T) {
}
}
func TestCgoCallbackPprof(t *testing.T) {
t.Parallel()
switch runtime.GOOS {
case "plan9", "windows":
t.Skipf("no pthreads on %s", runtime.GOOS)
}
if testenv.CPUProfilingBroken() {
t.Skip("skipping on platform with broken profiling")
}
got := runTestProg(t, "testprogcgo", "CgoCallbackPprof")
if want := "OK\n"; got != want {
t.Fatalf("expected %q, but got:\n%s", want, got)
}
}
func TestCgoExternalThreadPanic(t *testing.T) {
t.Parallel()
if runtime.GOOS == "plan9" {

View File

@ -6,6 +6,7 @@ package runtime_test
import (
"fmt"
"os"
"runtime"
"strings"
)
@ -59,3 +60,36 @@ func ExampleFrames() {
// - more:true | runtime_test.ExampleFrames.func3
// - more:true | runtime_test.ExampleFrames
}
func ExampleAddCleanup() {
tempFile, err := os.CreateTemp(os.TempDir(), "file.*")
if err != nil {
fmt.Println("failed to create temp file:", err)
return
}
ch := make(chan struct{})
// Attach a cleanup function to the file object.
runtime.AddCleanup(&tempFile, func(fileName string) {
if err := os.Remove(fileName); err == nil {
fmt.Println("temp file has been removed")
}
ch <- struct{}{}
}, tempFile.Name())
if err := tempFile.Close(); err != nil {
fmt.Println("failed to close temp file:", err)
return
}
// Run the garbage collector to reclaim unreachable objects
// and enqueue their cleanup functions.
runtime.GC()
// Wait until cleanup function is done.
<-ch
// Output:
// temp file has been removed
}

View File

@ -30,8 +30,10 @@ import (
// unreachable at the same time, their cleanups all become eligible to run
// and can run in any order. This is true even if the objects form a cycle.
//
// A single goroutine runs all cleanup calls for a program, sequentially. If a
// cleanup function must run for a long time, it should create a new goroutine.
// Cleanups run concurrently with any user-created goroutines.
// Cleanups may also run concurrently with one another (unlike finalizers).
// If a cleanup function must run for a long time, it should create a new goroutine
// to avoid blocking the execution of other cleanups.
//
// If ptr has both a cleanup and a finalizer, the cleanup will only run once
// it has been finalized and becomes unreachable without an associated finalizer.

View File

@ -391,10 +391,15 @@ func deferrangefunc() any {
throw("defer on system stack")
}
fn := findfunc(sys.GetCallerPC())
if fn.deferreturn == 0 {
throw("no deferreturn")
}
d := newdefer()
d.link = gp._defer
gp._defer = d
d.pc = sys.GetCallerPC()
d.pc = fn.entry() + uintptr(fn.deferreturn)
// We must not be preempted between calling GetCallerSP and
// storing it to d.sp because GetCallerSP's result is a
// uintptr stack pointer.
@ -1246,6 +1251,8 @@ func recovery(gp *g) {
// only gets us to the caller's fp.
gp.sched.bp = sp - goarch.PtrSize
}
// The value in ret is delivered IN A REGISTER, even if there is a
// stack ABI.
gp.sched.ret = 1
gogo(&gp.sched)
}

View File

@ -416,27 +416,6 @@ func parseProfile(t *testing.T, valBytes []byte, f func(uintptr, []*profile.Loca
return p
}
func cpuProfilingBroken() bool {
switch runtime.GOOS {
case "plan9":
// Profiling unimplemented.
return true
case "aix":
// See https://golang.org/issue/45170.
return true
case "ios", "dragonfly", "netbsd", "illumos", "solaris":
// See https://golang.org/issue/13841.
return true
case "openbsd":
if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" {
// See https://golang.org/issue/13841.
return true
}
}
return false
}
// testCPUProfile runs f under the CPU profiler, checking for some conditions specified by need,
// as interpreted by matches, and returns the parsed profile.
func testCPUProfile(t *testing.T, matches profileMatchFunc, f func(dur time.Duration)) *profile.Profile {
@ -454,7 +433,7 @@ func testCPUProfile(t *testing.T, matches profileMatchFunc, f func(dur time.Dura
t.Skip("skipping on wasip1")
}
broken := cpuProfilingBroken()
broken := testenv.CPUProfilingBroken()
deadline, ok := t.Deadline()
if broken || !ok {

View File

@ -419,14 +419,21 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
name := u.srcFunc(uf).name()
if stringslite.HasPrefix(name, "runtime.") ||
stringslite.HasPrefix(name, "runtime/internal/") ||
stringslite.HasPrefix(name, "internal/runtime/") ||
stringslite.HasPrefix(name, "reflect.") {
// For now we never async preempt the runtime or
// anything closely tied to the runtime. Known issues
// include: various points in the scheduler ("don't
// preempt between here and here"), much of the defer
// implementation (untyped info on stack), bulk write
// barriers (write barrier check),
// reflect.{makeFuncStub,methodValueCall}.
// barriers (write barrier check), atomic functions in
// internal/runtime/atomic, reflect.{makeFuncStub,methodValueCall}.
//
// Note that this is a subset of the runtimePkgs in pkgspecial.go
// and these checks are theoretically redundant because the compiler
// marks "all points" in runtime functions as unsafe for async preemption.
// But for some reason, we can't eliminate these checks until https://go.dev/issue/72031
// is resolved.
//
// TODO(austin): We should improve this, or opt things
// in incrementally.

View File

@ -556,7 +556,7 @@ type m struct {
printlock int8
incgo bool // m is executing a cgo call
isextra bool // m is an extra m
isExtraInC bool // m is an extra m that is not executing Go code
isExtraInC bool // m is an extra m that does not have any Go frames
isExtraInSig bool // m is an extra m in a signal handler
freeWait atomic.Uint32 // Whether it is safe to free g0 and delete m (one of freeMRef, freeMStack, freeMWait)
needextram bool

View File

@ -312,6 +312,16 @@ func asmcgocall(fn, arg unsafe.Pointer) int32
func morestack()
// morestack_noctxt should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
//
// Do not remove or change the type signature.
// See go.dev/issues/67401.
// See go.dev/issues/71672.
//
//go:linkname morestack_noctxt
func morestack_noctxt()
func rt0_go()

View File

@ -480,7 +480,18 @@ var pinnedTypemaps []map[typeOff]*_type
// the relocated one.
var aixStaticDataBase uintptr // linker symbol
var firstmoduledata moduledata // linker symbol
var firstmoduledata moduledata // linker symbol
// lastmoduledatap should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
//
// Do not remove or change the type signature.
// See go.dev/issues/67401.
// See go.dev/issues/71672.
//
//go:linkname lastmoduledatap
var lastmoduledatap *moduledata // linker symbol
var modulesSlice *[]*moduledata // see activeModules
@ -591,6 +602,16 @@ func moduledataverify() {
const debugPcln = false
// moduledataverify1 should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
// - github.com/bytedance/sonic
//
// Do not remove or change the type signature.
// See go.dev/issues/67401.
// See go.dev/issues/71672.
//
//go:linkname moduledataverify1
func moduledataverify1(datap *moduledata) {
// Check that the pclntab's format is valid.
hdr := datap.pcHeader

View File

@ -112,9 +112,10 @@ TEXT runtime·usleep(SB),NOSPLIT,$16-4
MOVW $1000000, R3
DIVD R3, R2
MOVD R2, 8(R15)
MOVW $1000, R3
MULLD R2, R3
MULLD R2, R3 // Convert sec to usec and subtract
SUB R3, R4
MOVW $1000, R3
MULLD R3, R4 // Convert remaining usec into nsec.
MOVD R4, 16(R15)
// nanosleep(&ts, 0)

View File

@ -0,0 +1,138 @@
// 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 !plan9 && !windows
package main
// Regression test for https://go.dev/issue/72870. Go code called from C should
// never be reported as external code.
/*
#include <pthread.h>
void go_callback1();
void go_callback2();
static void *callback_pprof_thread(void *arg) {
go_callback1();
return 0;
}
static void c_callback(void) {
go_callback2();
}
static void start_callback_pprof_thread() {
pthread_t th;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&th, &attr, callback_pprof_thread, 0);
// Don't join, caller will watch pprof.
}
*/
import "C"
import (
"bytes"
"fmt"
"internal/profile"
"os"
"runtime/pprof"
"time"
)
func init() {
register("CgoCallbackPprof", CgoCallbackPprof)
}
func CgoCallbackPprof() {
C.start_callback_pprof_thread()
var buf bytes.Buffer
if err := pprof.StartCPUProfile(&buf); err != nil {
fmt.Printf("Error starting CPU profile: %v\n", err)
os.Exit(1)
}
time.Sleep(1 * time.Second)
pprof.StopCPUProfile()
p, err := profile.Parse(&buf)
if err != nil {
fmt.Printf("Error parsing profile: %v\n", err)
os.Exit(1)
}
foundCallee := false
for _, s := range p.Sample {
funcs := flattenFrames(s)
if len(funcs) == 0 {
continue
}
leaf := funcs[0]
if leaf.Name != "main.go_callback1_callee" {
continue
}
foundCallee = true
if len(funcs) < 2 {
fmt.Printf("Profile: %s\n", p)
frames := make([]string, len(funcs))
for i := range funcs {
frames[i] = funcs[i].Name
}
fmt.Printf("FAIL: main.go_callback1_callee sample missing caller in frames %v\n", frames)
os.Exit(1)
}
if funcs[1].Name != "main.go_callback1" {
// In https://go.dev/issue/72870, this will be runtime._ExternalCode.
fmt.Printf("Profile: %s\n", p)
frames := make([]string, len(funcs))
for i := range funcs {
frames[i] = funcs[i].Name
}
fmt.Printf("FAIL: main.go_callback1_callee sample caller got %s want main.go_callback1 in frames %v\n", funcs[1].Name, frames)
os.Exit(1)
}
}
if !foundCallee {
fmt.Printf("Missing main.go_callback1_callee sample in profile %s\n", p)
os.Exit(1)
}
fmt.Printf("OK\n")
}
// Return the frame functions in s, regardless of inlining.
func flattenFrames(s *profile.Sample) []*profile.Function {
ret := make([]*profile.Function, 0, len(s.Location))
for _, loc := range s.Location {
for _, line := range loc.Line {
ret = append(ret, line.Function)
}
}
return ret
}
//export go_callback1
func go_callback1() {
// This is a separate function just to ensure we have another Go
// function as the caller in the profile.
go_callback1_callee()
}
func go_callback1_callee() {
C.c_callback()
// Spin for CPU samples.
for {
}
}
//export go_callback2
func go_callback2() {
}

View File

@ -779,7 +779,12 @@ func os_checkClonePidfd() error {
var err error
for {
var status WaitStatus
_, err = Wait4(int(pid), &status, 0, nil)
// WCLONE is an untyped constant that sets bit 31, so
// it cannot convert directly to int on 32-bit
// GOARCHes. We must convert through another type
// first.
flags := uint(WCLONE)
_, err = Wait4(int(pid), &status, int(flags), nil)
if err != EINTR {
break
}
@ -797,7 +802,7 @@ func os_checkClonePidfd() error {
for {
const _P_PIDFD = 3
_, _, errno = Syscall6(SYS_WAITID, _P_PIDFD, uintptr(pidfd), 0, WEXITED, 0, 0)
_, _, errno = Syscall6(SYS_WAITID, _P_PIDFD, uintptr(pidfd), 0, WEXITED | WCLONE, 0, 0)
if errno != EINTR {
break
}
@ -818,7 +823,7 @@ func os_checkClonePidfd() error {
//
//go:noinline
func doCheckClonePidfd(pidfd *int32) (pid uintptr, errno Errno) {
flags := uintptr(CLONE_VFORK | CLONE_VM | CLONE_PIDFD | SIGCHLD)
flags := uintptr(CLONE_VFORK | CLONE_VM | CLONE_PIDFD)
if runtime.GOARCH == "s390x" {
// On Linux/s390, the first two arguments of clone(2) are swapped.
pid, errno = rawVforkSyscall(SYS_CLONE, 0, flags, uintptr(unsafe.Pointer(pidfd)))

View File

@ -23,15 +23,26 @@ var constants = jsFS.Get("constants")
var uint8Array = js.Global().Get("Uint8Array")
var (
nodeWRONLY = constants.Get("O_WRONLY").Int()
nodeRDWR = constants.Get("O_RDWR").Int()
nodeCREATE = constants.Get("O_CREAT").Int()
nodeTRUNC = constants.Get("O_TRUNC").Int()
nodeAPPEND = constants.Get("O_APPEND").Int()
nodeEXCL = constants.Get("O_EXCL").Int()
nodeDIRECTORY = constants.Get("O_DIRECTORY").Int()
nodeWRONLY = constants.Get("O_WRONLY").Int()
nodeRDWR = constants.Get("O_RDWR").Int()
nodeCREATE = constants.Get("O_CREAT").Int()
nodeTRUNC = constants.Get("O_TRUNC").Int()
nodeAPPEND = constants.Get("O_APPEND").Int()
nodeEXCL = constants.Get("O_EXCL").Int()
// NodeJS on Windows does not support O_DIRECTORY, so we default
// to -1 and assign it in init if available.
// See https://nodejs.org/docs/latest/api/fs.html#file-open-constants.
nodeDIRECTORY = -1
)
func init() {
oDir := constants.Get("O_DIRECTORY")
if !oDir.IsUndefined() {
nodeDIRECTORY = oDir.Int()
}
}
type jsFile struct {
path string
entries []string
@ -85,7 +96,11 @@ func Open(path string, openmode int, perm uint32) (int, error) {
return 0, errors.New("syscall.Open: O_SYNC is not supported by js/wasm")
}
if openmode&O_DIRECTORY != 0 {
flags |= nodeDIRECTORY
if nodeDIRECTORY != -1 {
flags |= nodeDIRECTORY
} else {
return 0, errors.New("syscall.Open: O_DIRECTORY is not supported on Windows")
}
}
jsFD, err := fsCall("open", path, flags, perm)

View File

@ -235,7 +235,7 @@ func NewCallbackCDecl(fn any) uintptr {
//sys GetVersion() (ver uint32, err error)
//sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
//sys ExitProcess(exitcode uint32)
//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
//sys createFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval == InvalidHandle || e1 == ERROR_ALREADY_EXISTS ] = CreateFileW
//sys readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = ReadFile
//sys writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = WriteFile
//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
@ -404,8 +404,8 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
const _FILE_FLAG_WRITE_THROUGH = 0x80000000
attrs |= _FILE_FLAG_WRITE_THROUGH
}
h, err := CreateFile(namep, access, sharemode, sa, createmode, attrs, 0)
if err != nil {
h, err := createFile(namep, access, sharemode, sa, createmode, attrs, 0)
if h == InvalidHandle {
if err == ERROR_ACCESS_DENIED && (flag&O_WRONLY != 0 || flag&O_RDWR != 0) {
// We should return EISDIR when we are trying to open a directory with write access.
fa, e1 := GetFileAttributes(namep)
@ -413,9 +413,11 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
err = EISDIR
}
}
return InvalidHandle, err
return h, err
}
if flag&O_TRUNC == O_TRUNC {
// Ignore O_TRUNC if the file has just been created.
if flag&O_TRUNC == O_TRUNC &&
(createmode == OPEN_EXISTING || (createmode == OPEN_ALWAYS && err == ERROR_ALREADY_EXISTS)) {
err = Ftruncate(h, 0)
if err != nil {
CloseHandle(h)
@ -1454,3 +1456,13 @@ func GetStartupInfo(startupInfo *StartupInfo) error {
getStartupInfo(startupInfo)
return nil
}
func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
handle, err = createFile(name, access, mode, sa, createmode, attrs, templatefile)
if handle != InvalidHandle {
// CreateFileW can return ERROR_ALREADY_EXISTS with a valid handle.
// We only want to return an error if the handle is invalid.
err = nil
}
return handle, err
}

View File

@ -502,10 +502,10 @@ func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxS
return
}
func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
func createFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
r0, _, e1 := Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
handle = Handle(r0)
if handle == InvalidHandle {
if handle == InvalidHandle || e1 == ERROR_ALREADY_EXISTS {
err = errnoErr(e1)
}
return

View File

@ -114,10 +114,22 @@ type B struct {
netBytes uint64
// Extra metrics collected by ReportMetric.
extra map[string]float64
// For Loop() to be executed in benchFunc.
// Loop() has its own control logic that skips the loop scaling.
// See issue #61515.
loopN int
// loop tracks the state of B.Loop
loop struct {
// n is the target number of iterations. It gets bumped up as we go.
// When the benchmark loop is done, we commit this to b.N so users can
// do reporting based on it, but we avoid exposing it until then.
n uint64
// i is the current Loop iteration. It's strictly monotonically
// increasing toward n.
//
// The high bit is used to poison the Loop fast path and fall back to
// the slow path.
i uint64
done bool // set when B.Loop return false
}
}
// StartTimer starts timing a test. This function is called automatically
@ -130,6 +142,7 @@ func (b *B) StartTimer() {
b.startBytes = memStats.TotalAlloc
b.start = highPrecisionTimeNow()
b.timerOn = true
b.loop.i &^= loopPoisonTimer
}
}
@ -142,6 +155,8 @@ func (b *B) StopTimer() {
b.netAllocs += memStats.Mallocs - b.startAllocs
b.netBytes += memStats.TotalAlloc - b.startBytes
b.timerOn = false
// If we hit B.Loop with the timer stopped, fail.
b.loop.i |= loopPoisonTimer
}
}
@ -192,7 +207,9 @@ func (b *B) runN(n int) {
runtime.GC()
b.resetRaces()
b.N = n
b.loopN = 0
b.loop.n = 0
b.loop.i = 0
b.loop.done = false
b.ctx = ctx
b.cancelCtx = cancelCtx
@ -203,6 +220,10 @@ func (b *B) runN(n int) {
b.StopTimer()
b.previousN = n
b.previousDuration = b.duration
if b.loop.n > 0 && !b.loop.done && !b.failed {
b.Error("benchmark function returned without B.Loop() == false (break or return in loop?)")
}
}
// run1 runs the first iteration of benchFunc. It reports whether more
@ -312,8 +333,8 @@ func (b *B) launch() {
}()
// b.Loop does its own ramp-up logic so we just need to run it once.
// If b.loopN is non zero, it means b.Loop has already run.
if b.loopN == 0 {
// If b.loop.n is non zero, it means b.Loop has already run.
if b.loop.n == 0 {
// Run the benchmark for at least the specified amount of time.
if b.benchTime.n > 0 {
// We already ran a single iteration in run1.
@ -368,38 +389,59 @@ func (b *B) ReportMetric(n float64, unit string) {
}
func (b *B) stopOrScaleBLoop() bool {
timeElapsed := highPrecisionTimeSince(b.start)
if timeElapsed >= b.benchTime.d {
t := b.Elapsed()
if t >= b.benchTime.d {
// Stop the timer so we don't count cleanup time
b.StopTimer()
// Commit iteration count
b.N = int(b.loop.n)
b.loop.done = true
return false
}
// Loop scaling
goalns := b.benchTime.d.Nanoseconds()
prevIters := int64(b.N)
b.N = predictN(goalns, prevIters, timeElapsed.Nanoseconds(), prevIters)
b.loopN++
prevIters := int64(b.loop.n)
b.loop.n = uint64(predictN(goalns, prevIters, t.Nanoseconds(), prevIters))
if b.loop.n&loopPoisonMask != 0 {
// The iteration count should never get this high, but if it did we'd be
// in big trouble.
panic("loop iteration target overflow")
}
b.loop.i++
return true
}
func (b *B) loopSlowPath() bool {
if b.loopN == 0 {
// Consistency checks
if !b.timerOn {
b.Fatal("B.Loop called with timer stopped")
}
if b.loop.i&loopPoisonMask != 0 {
panic(fmt.Sprintf("unknown loop stop condition: %#x", b.loop.i))
}
if b.loop.n == 0 {
// If it's the first call to b.Loop() in the benchmark function.
// Allows more precise measurement of benchmark loop cost counts.
// Also initialize b.N to 1 to kick start loop scaling.
b.N = 1
b.loopN = 1
// Also initialize target to 1 to kick start loop scaling.
b.loop.n = 1
// Within a b.Loop loop, we don't use b.N (to avoid confusion).
b.N = 0
b.loop.i++
b.ResetTimer()
return true
}
// Handles fixed iterations case
if b.benchTime.n > 0 {
if b.N < b.benchTime.n {
b.N = b.benchTime.n
b.loopN++
if b.loop.n < uint64(b.benchTime.n) {
b.loop.n = uint64(b.benchTime.n)
b.loop.i++
return true
}
b.StopTimer()
// Commit iteration count
b.N = int(b.loop.n)
b.loop.done = true
return false
}
// Handles fixed time case
@ -440,13 +482,38 @@ func (b *B) loopSlowPath() bool {
// whereas b.N-based benchmarks must run the benchmark function (and any
// associated setup and cleanup) several times.
func (b *B) Loop() bool {
if b.loopN != 0 && b.loopN < b.N {
b.loopN++
// This is written such that the fast path is as fast as possible and can be
// inlined.
//
// There are three cases where we'll fall out of the fast path:
//
// - On the first call, both i and n are 0.
//
// - If the loop reaches the n'th iteration, then i == n and we need
// to figure out the new target iteration count or if we're done.
//
// - If the timer is stopped, it poisons the top bit of i so the slow
// path can do consistency checks and fail.
if b.loop.i < b.loop.n {
b.loop.i++
return true
}
return b.loopSlowPath()
}
// The loopPoison constants can be OR'd into B.loop.i to cause it to fall back
// to the slow path.
const (
loopPoisonTimer = uint64(1 << (63 - iota))
// If necessary, add more poison bits here.
// loopPoisonMask is the set of all loop poison bits. (iota-1) is the index
// of the bit we just set, from which we recreate that bit mask. We subtract
// 1 to set all of the bits below that bit, then complement the result to
// get the mask. Sorry, not sorry.
loopPoisonMask = ^uint64((1 << (63 - (iota - 1))) - 1)
)
// BenchmarkResult contains the results of a benchmark run.
type BenchmarkResult struct {
N int // The number of iterations.

View File

@ -4,13 +4,22 @@
package testing
import (
"bytes"
"strings"
)
// See also TestBenchmarkBLoop* in other files.
func TestBenchmarkBLoop(t *T) {
var initialStart highPrecisionTime
var firstStart highPrecisionTime
var lastStart highPrecisionTime
var scaledStart highPrecisionTime
var runningEnd bool
runs := 0
iters := 0
firstBN := 0
restBN := 0
finalBN := 0
bRet := Benchmark(func(b *B) {
initialStart = b.start
@ -18,8 +27,13 @@ func TestBenchmarkBLoop(t *T) {
for b.Loop() {
if iters == 0 {
firstStart = b.start
firstBN = b.N
} else {
restBN = max(restBN, b.N)
}
if iters == 1 {
scaledStart = b.start
}
lastStart = b.start
iters++
}
finalBN = b.N
@ -37,6 +51,13 @@ func TestBenchmarkBLoop(t *T) {
if finalBN != iters || bRet.N != iters {
t.Errorf("benchmark iterations mismatch: %d loop iterations, final b.N=%d, bRet.N=%d", iters, finalBN, bRet.N)
}
// Verify that b.N was 0 inside the loop
if firstBN != 0 {
t.Errorf("want b.N == 0 on first iteration, got %d", firstBN)
}
if restBN != 0 {
t.Errorf("want b.N == 0 on subsequent iterations, got %d", restBN)
}
// Make sure the benchmark ran for an appropriate amount of time.
if bRet.T < benchTime.d {
t.Fatalf("benchmark ran for %s, want >= %s", bRet.T, benchTime.d)
@ -45,8 +66,8 @@ func TestBenchmarkBLoop(t *T) {
if firstStart == initialStart {
t.Errorf("b.Loop did not reset the timer")
}
if lastStart != firstStart {
t.Errorf("timer was reset during iteration")
if scaledStart != firstStart {
t.Errorf("b.Loop stops and restarts the timer during iteration")
}
// Verify that it stopped the timer after the last loop.
if runningEnd {
@ -54,4 +75,80 @@ func TestBenchmarkBLoop(t *T) {
}
}
// See also TestBenchmarkBLoop* in other files.
func TestBenchmarkBLoopBreak(t *T) {
var bState *B
var bLog bytes.Buffer
bRet := Benchmark(func(b *B) {
// The Benchmark function provides no access to the failure state and
// discards the log, so capture the B and save its log.
bState = b
b.common.w = &bLog
for i := 0; b.Loop(); i++ {
if i == 2 {
break
}
}
})
if !bState.failed {
t.Errorf("benchmark should have failed")
}
const wantLog = "benchmark function returned without B.Loop"
if log := bLog.String(); !strings.Contains(log, wantLog) {
t.Errorf("missing error %q in output:\n%s", wantLog, log)
}
// A benchmark that exits early should not report its target iteration count
// because it's not meaningful.
if bRet.N != 0 {
t.Errorf("want N == 0, got %d", bRet.N)
}
}
func TestBenchmarkBLoopError(t *T) {
// Test that a benchmark that exits early because of an error doesn't *also*
// complain that the benchmark exited early.
var bState *B
var bLog bytes.Buffer
bRet := Benchmark(func(b *B) {
bState = b
b.common.w = &bLog
for i := 0; b.Loop(); i++ {
b.Error("error")
return
}
})
if !bState.failed {
t.Errorf("benchmark should have failed")
}
const noWantLog = "benchmark function returned without B.Loop"
if log := bLog.String(); strings.Contains(log, noWantLog) {
t.Errorf("unexpected error %q in output:\n%s", noWantLog, log)
}
if bRet.N != 0 {
t.Errorf("want N == 0, got %d", bRet.N)
}
}
func TestBenchmarkBLoopStop(t *T) {
var bState *B
var bLog bytes.Buffer
bRet := Benchmark(func(b *B) {
bState = b
b.common.w = &bLog
for i := 0; b.Loop(); i++ {
b.StopTimer()
}
})
if !bState.failed {
t.Errorf("benchmark should have failed")
}
const wantLog = "B.Loop called with timer stopped"
if log := bLog.String(); !strings.Contains(log, wantLog) {
t.Errorf("missing error %q in output:\n%s", wantLog, log)
}
if bRet.N != 0 {
t.Errorf("want N == 0, got %d", bRet.N)
}
}

View File

@ -14,6 +14,7 @@ import (
"errors"
"fmt"
"net"
"net/netip"
"net/url"
"os"
"strings"
@ -177,8 +178,10 @@ func (cfg *config) useProxy(addr string) bool {
if host == "localhost" {
return false
}
ip := net.ParseIP(host)
if ip != nil {
nip, err := netip.ParseAddr(host)
var ip net.IP
if err == nil {
ip = net.IP(nip.AsSlice())
if ip.IsLoopback() {
return false
}
@ -360,6 +363,9 @@ type domainMatch struct {
}
func (m domainMatch) match(host, port string, ip net.IP) bool {
if ip != nil {
return false
}
if strings.HasSuffix(host, m.host) || (m.matchHost && host == m.host[1:]) {
return m.port == "" || m.port == port
}

View File

@ -6,7 +6,7 @@ golang.org/x/crypto/cryptobyte
golang.org/x/crypto/cryptobyte/asn1
golang.org/x/crypto/internal/alias
golang.org/x/crypto/internal/poly1305
# golang.org/x/net v0.32.1-0.20250121202134-9a960c88dd98
# golang.org/x/net v0.32.1-0.20250304185419-76f9bf3279ef
## explicit; go 1.18
golang.org/x/net/dns/dnsmessage
golang.org/x/net/http/httpguts

View File

@ -56,6 +56,9 @@ import (
// referenced object. Typically, this batching only happens for tiny
// (on the order of 16 bytes or less) and pointer-free objects.
type Pointer[T any] struct {
// Mention T in the type definition to prevent conversions
// between Pointer types, like we do for sync/atomic.Pointer.
_ [0]*T
u unsafe.Pointer
}
@ -69,7 +72,7 @@ func Make[T any](ptr *T) Pointer[T] {
u = runtime_registerWeakPointer(unsafe.Pointer(ptr))
}
runtime.KeepAlive(ptr)
return Pointer[T]{u}
return Pointer[T]{u: u}
}
// Value returns the original pointer used to create the weak pointer.

View File

@ -6,10 +6,12 @@ package weak_test
import (
"context"
"internal/goarch"
"runtime"
"sync"
"testing"
"time"
"unsafe"
"weak"
)
@ -155,6 +157,14 @@ func TestPointerFinalizer(t *testing.T) {
}
}
func TestPointerSize(t *testing.T) {
var p weak.Pointer[T]
size := unsafe.Sizeof(p)
if size != goarch.PtrSize {
t.Errorf("weak.Pointer[T] size = %d, want %d", size, goarch.PtrSize)
}
}
// Regression test for issue 69210.
//
// Weak-to-strong conversions must shade the new strong pointer, otherwise

View File

@ -0,0 +1,99 @@
// run
// 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.
package main
//go:noinline
func i() {
for range yieldInts {
defer func() {
println("I")
recover()
}()
}
// This panic causes dead code elimination of the return block.
// The compiler should nonetheless emit a deferreturn.
panic("i panic")
}
//go:noinline
func h() {
defer func() {
println("H first")
}()
for range yieldInts {
defer func() {
println("H second")
}()
}
defer func() {
println("H third")
}()
for range yieldIntsPanic {
defer func() {
println("h recover:called")
recover()
}()
}
}
//go:noinline
func yieldInts(yield func(int) bool) {
if !yield(0) {
return
}
}
//go:noinline
func g() {
defer func() {
println("G first")
}()
for range yieldIntsPanic {
defer func() {
println("g recover:called")
recover()
}()
}
}
//go:noinline
func yieldIntsPanic(yield func(int) bool) {
if !yield(0) {
return
}
panic("yield stop")
}
//go:noinline
func next(i int) int {
if i == 0 {
panic("next stop")
}
return i + 1
}
//go:noinline
func f() {
defer func() {
println("F first")
}()
for i := 0; i < 1; i = next(i) {
defer func() {
println("f recover:called")
recover()
}()
}
}
func main() {
f()
println("f returned")
g()
println("g returned")
h()
println("h returned")
i()
println("i returned")
}

View File

@ -0,0 +1,13 @@
f recover:called
F first
f returned
g recover:called
G first
g returned
h recover:called
H third
H second
H first
h returned
I
i returned

View File

@ -0,0 +1,28 @@
// compile
// 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.
package p
type Parser struct{}
type Node struct{}
type parserState func(p *Parser) parserState
func parserStateData(root *Node) parserState {
return func(p *Parser) parserState {
return parserStateOpenMap(root)(p)
}
}
func parserStateOpenMap(root *Node) parserState {
return func(p *Parser) parserState {
switch {
case p != nil:
return parserStateData(root)(p)
}
return parserStateOpenMap(root)(p)
}
}

View File

@ -0,0 +1,23 @@
// compile
// 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.
package main
import (
"math"
)
func main() {
test(2)
}
func test(i int) {
if i <= 0 {
return
}
_ = math.Pow10(i + 2)
}

View File

@ -0,0 +1,29 @@
// run
// 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.
package main
import "sync/atomic"
//go:noinline
func f(p0, p1, p2, p3, p4, p5, p6, p7 *uint64, a *atomic.Uint64) {
old := a.Or(0xaaa)
*p0 = old
*p1 = old
*p2 = old
*p3 = old
*p4 = old
*p5 = old
*p6 = old
*p7 = old
}
func main() {
a := new(atomic.Uint64)
p := new(uint64)
f(p, p, p, p, p, p, p, p, a)
}

View File

@ -0,0 +1,50 @@
// run
// 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.
package main
import "runtime"
const C = 16
type T [C * C]byte
func main() {
var ts []*T
for i := 0; i < 100; i++ {
t := new(T)
// Save every even object.
if i%2 == 0 {
ts = append(ts, t)
}
}
// Make sure the odd objects are collected.
runtime.GC()
for _, t := range ts {
f(t, C, C)
}
}
//go:noinline
func f(t *T, i, j uint) {
if i == 0 || i > C || j == 0 || j > C {
return // gets rid of bounds check below (via prove pass)
}
p := &t[i*j-1]
*p = 0
runtime.GC()
*p = 0
// This goes badly if compiled to
// q := &t[i*j]
// *(q-1) = 0
// runtime.GC()
// *(q-1) = 0
// as at the GC call, q is an invalid pointer
// (it points past the end of t's allocation).
}

View File

@ -0,0 +1,40 @@
// run
// 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.
package main
import "fmt"
// Y is the Y-combinator based on https://dreamsongs.com/Files/WhyOfY.pdf
func Y[Endo ~func(RecFct) RecFct, RecFct ~func(T) R, T, R any](f Endo) RecFct {
type internal[RecFct ~func(T) R, T, R any] func(internal[RecFct, T, R]) RecFct
g := func(h internal[RecFct, T, R]) RecFct {
return func(t T) R {
return f(h(h))(t)
}
}
return g(g)
}
func main() {
fct := Y(func(r func(int) int) func(int) int {
return func(n int) int {
if n <= 0 {
return 1
}
return n * r(n-1)
}
})
want := 3628800
if got := fct(10); got != want {
msg := fmt.Sprintf("unexpected result, got: %d, want: %d", got, want)
panic(msg)
}
}

Some files were not shown because too many files have changed in this diff Show More