Compare commits

...

103 Commits

Author SHA1 Message Date
Heschi Kreinick
085c61ae51 [release-branch.go1.17] go1.17.10
Change-Id: I601b16bea35c7c468b25a1c6e817e0a9af0b531f
Reviewed-on: https://go-review.googlesource.com/c/go/+/405478
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: David Chase <drchase@google.com>
2022-05-10 16:14:36 +00:00
Heschi Kreinick
f7209f904d [release-branch.go1.17] cmd/objdump: skip TestDisasm* on darwin-arm64
The macOS 12 builders have an incompatible version of XCode installed.
We fixed the bug on 1.18 but not 1.17.

Updates #49700.

Change-Id: Id356786aad351568ba6665430f093f5f78bb4357
Reviewed-on: https://go-review.googlesource.com/c/go/+/405474
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2022-05-10 15:33:47 +00:00
Heschi Kreinick
5b45e19a53 [release-branch.go1.17] net: skip TestDialCancel on darwin-arm64
We're turning up Macs in a network environment that clashes with this
test. I don't think it's critical to get it working, so skip it.

For #49149.
Fixes #52705.

Change-Id: I925e3ecc5356c4cefd208bdcff3d98021215d0b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/402181
Reviewed-by: Alex Rakoczy <alex@golang.org>
Run-TryBot: Heschi Kreinick <heschi@google.com>
Auto-Submit: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 06b0a655a1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/405295
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2022-05-09 21:42:16 +00:00
Keith Randall
feec92c423 [release-branch.go1.17] cmd/compile: drop column info when line number saturates
When line number saturates, we can end up getting non-monotonic
position info, because the start of the next line after line=lineMax,col=2
is line=lineMax,col=1.

Instead, if line==lineMax, make the column always 0 (no column info).
If the line number is wrong, having column info probably isn't that helpful.

Fixes #52095

Change-Id: If3d90472691b1f6163654f3505e2cb98467f2383
Reviewed-on: https://go-review.googlesource.com/c/go/+/385795
Trust: Keith Randall <khr@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
(cherry picked from commit 1de2344af1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/401315
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Austin Clements <austin@google.com>
2022-05-09 20:27:15 +00:00
Damien Neil
04781d14d2 [release-branch.go1.17] syscall: check correct group in Faccessat
The Faccessat call checks the user, group, or other permission bits of a
file to see if the calling process can access it. The test to see if the
group permissions should be used was made with the wrong group id, using
the process's group id rather than the file's group id. Fix this to use
the correct group id.

No test since we cannot easily change file permissions when not running
as root and the test is meaningless if running as root.

For #52313
Fixes #52439

Change-Id: I4e2c84754b0af7830b40fd15dedcbc58374d75ee
Reviewed-on: https://go-review.googlesource.com/c/go/+/399539
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit f66925e854)
Reviewed-on: https://go-review.googlesource.com/c/go/+/401078
Auto-Submit: Tatiana Bradley <tatiana@golang.org>
Run-TryBot: Tatiana Bradley <tatiana@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Tatiana Bradley <tatiana@golang.org>
2022-05-09 20:18:07 +00:00
Maisem Ali
4c5acd4b57 [release-branch.go1.17] net/http/httptest: fix race in Server.Close
When run with race detector the test fails without the fix.

For #51799
Fixes #52455

Change-Id: I273adb6d3a2b1e0d606b9c27ab4c6a9aa4aa8064
GitHub-Last-Rev: a5ddd146a2
GitHub-Pull-Request: golang/go#51805
Reviewed-on: https://go-review.googlesource.com/c/go/+/393974
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 1d19cea740)
Reviewed-on: https://go-review.googlesource.com/c/go/+/401318
Reviewed-by: David Chase <drchase@google.com>
2022-05-09 20:17:13 +00:00
Ian Lance Taylor
78992411de [release-branch.go1.17] runtime: don't block preemption signal in new M's or ensureSigM
No test because we already have a test in the syscall package.
The issue reports 1 failure per 100,000 iterations, which is rare enough
that our builders won't catch the problem.

For #52226
Fixes #52374

Change-Id: I17633ff6cf676b6d575356186dce42cdacad0746
Reviewed-on: https://go-review.googlesource.com/c/go/+/400315
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
(cherry picked from commit e3982660a7)
Reviewed-on: https://go-review.googlesource.com/c/go/+/400317
Reviewed-by: Austin Clements <austin@google.com>
2022-05-06 23:11:51 +00:00
Bryan C. Mills
2150be1a9b [release-branch.go1.17] syscall: relax output check in TestGroupCleanupUserNamespace
“If you have a procedure with ten parameters, you probably missed some.”
― attr. Alan J. Perlis

I argue that the same is true for hard-coded special cases.

In TestGroupCleanupUserNamespace, instead of a curated list of strings
observed in the wild we now check for a prefix, as was done for
TestGroupCleanup in CL 24670.

Updates #52088.
Fixes #52148.

Change-Id: I59c5b0c048113e306996c0f8247e09c714d2423a
Reviewed-on: https://go-review.googlesource.com/c/go/+/397316
Trust: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 434b2a5d0d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/398235
Reviewed-by: Ian Lance Taylor <iant@google.com>
2022-05-04 15:44:36 +00:00
Roland Shoemaker
9511f6deb6 [release-branch.go1.17] crypto/x509: properly handle issuerUniqueID and subjectUniqueID
Updates #51754
Fixes #51858

Change-Id: I3bfa15db3497de9fb82d6391d87fca1ae9ba6543
Reviewed-on: https://go-review.googlesource.com/c/go/+/394297
Trust: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
(cherry picked from commit 9a53b472b5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/399501
2022-05-04 15:38:55 +00:00
Damien Neil
0fdca725c7 [release-branch.go1.17] sync: remove TestWaitGroupMisuse2 and TestWaitGroupMisuse3
These tests are inherently nondeterministic: They exercise a racy
code path for up to one million iterations, and require that an
error occur at least once.

TestWaitGroupMisuse2 in particular is an ongoing source of trybot
flakiness.

Updates #38163.
Fixes #52306.

Change-Id: Ibbbda2c998c915333487ad262d3df6829de01c2b
Reviewed-on: https://go-review.googlesource.com/c/go/+/340249
Trust: Damien Neil <dneil@google.com>
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
(cherry picked from commit 011fd00245)
Reviewed-on: https://go-review.googlesource.com/c/go/+/399821
Run-TryBot: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
2022-05-02 16:21:47 +00:00
Dmitri Shuralyov
346b18ee9d [release-branch.go1.17] go1.17.9
Change-Id: Id2437003673e7eb1c514f15e6266b93308b7d5e8
Reviewed-on: https://go-review.googlesource.com/c/go/+/399819
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2022-04-12 15:40:31 +00:00
Julie Qiu
2116d60993 [release-branch.go1.17] encoding/pem: fix stack overflow in Decode
Previously, Decode called decodeError, a recursive function that was
prone to stack overflows when given a large PEM file containing errors.

Credit to Juho Nurminen of Mattermost who reported the error.

Fixes CVE-2022-24675
Updates #51853
Fixes #52036

Change-Id: Iffe768be53c8ddc0036fea0671d290f8f797692c
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1391157
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Filippo Valsorda <valsorda@google.com>
(cherry picked from commit 794ea5e828010e8b68493b2fc6d2963263195a02)
Reviewed-on: https://go-review.googlesource.com/c/go/+/399816
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-04-12 14:42:58 +00:00
Filippo Valsorda
7139e8b024 [release-branch.go1.17] crypto/elliptic: tolerate zero-padded scalars in generic P-256
Updates #52075
Fixes #52076
Fixes CVE-2022-28327

Change-Id: I595a7514c9a0aa1b9c76aedfc2307e1124271f27
Reviewed-on: https://go-review.googlesource.com/c/go/+/397136
Trust: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Julie Qiu <julie@golang.org>
2022-04-06 16:36:21 +00:00
Cherry Mui
eb75219438 [release-branch.go1.17] cmd/link: mark unexported methods for plugins
When plugin is used, we already mark all exported methods
reachable. However, when the plugin and the host program share
a common package, an unexported method could also be reachable
from both the plugin and the host via interfaces. We need to mark
them as well.

Fixes #51736.
Updates #51621.

Change-Id: I1a70d3f96b66b803f2d0ab14d00ed0df276ea500
Reviewed-on: https://go-review.googlesource.com/c/go/+/393365
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
(cherry picked from commit 91631bc7e0)
Reviewed-on: https://go-review.googlesource.com/c/go/+/397484
2022-04-04 18:02:38 +00:00
Russ Cox
4e69fddc64 [release-branch.go1.17] runtime: fix net poll races
The netpoll code was written long ago, when the
only multiprocessors that Go ran on were x86.
It assumed that an atomic store would trigger a
full memory barrier and then used that barrier
to order otherwise racy access to a handful of fields,
including pollDesc.closing.

On ARM64, this code has finally failed, because
the atomic store is on a value completely unrelated
to any of the racily-accessed fields, and the ARMv8
hardware, unlike x86, is clever enough not to do a
full memory barrier for a simple atomic store.
We are seeing a constant background rate of trybot
failures where the net/http tests deadlock - a netpollblock
has clearly happened after the pollDesc has begun to close.

The code that does the racy reads is netpollcheckerr,
which needs to be able to run without acquiring a lock.
This CL fixes the race, without introducing unnecessary
inefficiency or deadlock, by arranging for every updater
of the relevant fields to publish a summary as a single
atomic uint32, and then having netpollcheckerr use a
single atomic load to fetch the relevant bits and then
proceed as before.

For #45211
Fixes #50611

Change-Id: Ib6788c8da4d00b7bda84d55ca3fdffb5a64c1a0a
Reviewed-on: https://go-review.googlesource.com/c/go/+/378234
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Trust: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 17b2fb1b65)
Reviewed-on: https://go-review.googlesource.com/c/go/+/392714
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
2022-03-28 16:55:47 +00:00
Ian Lance Taylor
efed283e79 [release-branch.go1.17] runtime: call testenv.MustHaveCGO in a couple of tests
For #51695
Fixes #51696

Change-Id: Icfe9d26ecc28a7db9040d50d4661cf9e8245471e
Reviewed-on: https://go-review.googlesource.com/c/go/+/392916
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
(cherry picked from commit 2d32594396)
Reviewed-on: https://go-review.googlesource.com/c/go/+/393698
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
2022-03-28 16:55:15 +00:00
Cherry Mui
88be85f18b [release-branch.go1.17] runtime: count spill slot for frame size at finalizer call
The finalizer is called using reflectcall. When register ABI is
used, the finalizer's argument is passed in register(s). But the
frame size calculation does not include the spill slot. When the
argument actually spills, it may clobber the caller's stack frame.
This CL fixes it.

Updates #51457.
Fixes #51458.

Change-Id: Ibcc7507c518ba65c1c5a7759e5cab0ae3fc7efce
Reviewed-on: https://go-review.googlesource.com/c/go/+/389574
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 58804ea67a)
Reviewed-on: https://go-review.googlesource.com/c/go/+/389794
2022-03-14 17:45:32 +00:00
Carlos Amedee
7dd10d4ce2 [release-branch.go1.17] go1.17.8
Change-Id: I14f4da429cf8562c6cab99cd0cd4edfbc03f68e9
Reviewed-on: https://go-review.googlesource.com/c/go/+/389736
Trust: Carlos Amedee <carlos@golang.org>
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
2022-03-03 16:55:45 +00:00
Bryan C. Mills
7f04645b7a [release-branch.go1.17] cmd/go: avoid +incompatible major versions if a go.mod file exists in a subdirectory for that version
Previous versions of the 'go' command would reject a pseudo-version
passed to 'go get' if that pseudo-version had a mismatched major
version and lacked a "+incompatible" suffix. However, they would
erroneously accept a version *with* a "+incompatible" suffix even if
the repo contained a vN/go.mod file for the same major version, and
would generate a "+incompatible" pseudo-version or version if the user
requested a tag, branch, or commit hash.

This change uniformly rejects "vN.…" without "+incompatible", and also
avoids resolving to "vN.…+incompatible", when vN/go.mod exists.
To maintain compatibility with existing go.mod files, it still accepts
"vN.…+incompatible" if the version is requested explicitly as such
and the repo root lacks a go.mod file.

Fixes #51332
Updates #51324
Updates #36438

Change-Id: I2b16150c73fc2abe4d0a1cd34cb1600635db7139
Reviewed-on: https://go-review.googlesource.com/c/go/+/387675
Trust: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
(cherry picked from commit 5a9fc946b4)
Reviewed-on: https://go-review.googlesource.com/c/go/+/387922
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2022-03-03 14:29:59 +00:00
Cherry Mui
7d8fa65789 [release-branch.go1.17] cmd/compile: correct type of pointer difference on RISCV64
Pointer comparison is lowered to the following on RISCV64

(EqPtr x y) => (SEQZ (SUB <x.Type> x y))

The difference of two pointers (the SUB) should not be pointer
type. Otherwise it can cause the GC to find a bad pointer.

Updates #51101.
Fixes #51199.

Change-Id: I7e73c2155c36ff403c032981a9aa9cccbfdf0f64
Reviewed-on: https://go-review.googlesource.com/c/go/+/385655
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 1ed30ca537)
Reviewed-on: https://go-review.googlesource.com/c/go/+/386474
2022-02-18 00:51:21 +00:00
Michael Anthony Knyszek
1ba25fa288 [release-branch.go1.17] runtime: simplify histogram buckets considerably
There was an off-by-one error in the time histogram buckets calculation
that caused the linear sub-buckets distances to be off by 2x.

The fix was trivial, but in writing tests I realized there was a much
simpler way to express the calculation for the histogram buckets, and
took the opportunity to do that here. The new bucket calculation also
fixes the bug.

For #50732.
Fixes #50734.

Change-Id: Idae89986de1c415ee4e148f778e0e101ca003ade
Reviewed-on: https://go-review.googlesource.com/c/go/+/380094
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 2e9dcb5086)
Reviewed-on: https://go-review.googlesource.com/c/go/+/384621
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-02-18 00:27:35 +00:00
Ian Lance Taylor
7d70adf3f5 [release-branch.go1.17] net: increase maximum accepted DNS packet to 1232 bytes
The existing value of 512 bytes as is specified by RFC 1035.
However, the WSL resolver reportedly sends larger packets without
setting the truncation bit, which breaks using the Go resolver.
For 1.18 and backports, just increase the accepted packet size.
This is what GNU glibc does (they use 65536 bytes).

For 1.19 we plan to use EDNS to set the accepted packet size.
That will give us more time to test whether that causes any problems.

No test because I'm not sure how to write one and it wouldn't really
be useful anyhow.

For #6464
For #21160
For #44135
For #51127
For #51153
Fixes #51162

Change-Id: I0243f274a06e010ebb714e138a65386086aecf17
Reviewed-on: https://go-review.googlesource.com/c/go/+/386015
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 6e82ff83cf)
Reviewed-on: https://go-review.googlesource.com/c/go/+/386035
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2022-02-17 19:27:53 +00:00
Russ Cox
ac071634c4 [release-branch.go1.17] regexp/syntax: reject very deeply nested regexps in Parse
The regexp code assumes it can recurse over the structure of
a regexp safely. Go's growable stacks make that reasonable
for all plausible regexps, but implausible ones can reach the
“infinite recursion?” stack limit.

This CL limits the depth of any parsed regexp to 1000.
That is, the depth of the parse tree is required to be ≤ 1000.
Regexps that require deeper parse trees will return ErrInternalError.
A future CL will change the error to ErrInvalidDepth,
but using ErrInternalError for now avoids introducing new API
in point releases when this is backported.

Fixes #51112.
Fixes #51118.

Change-Id: I97d2cd82195946eb43a4ea8561f5b95f91fb14c5
Reviewed-on: https://go-review.googlesource.com/c/go/+/384616
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/384854
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-02-17 19:20:55 +00:00
Roland Shoemaker
cd6e0d7cad [release-branch.go1.17] crypto/x509: support NumericString in DN components
Updates #48171
Fixes #51000

Change-Id: Ia2e1920c0938a1f8659935a4f725a7e5090ef2c0
Reviewed-on: https://go-review.googlesource.com/c/go/+/347034
Trust: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
(cherry picked from commit 896df422a7)
Reviewed-on: https://go-review.googlesource.com/c/go/+/382857
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
2022-02-09 21:57:04 +00:00
Cherry Mui
6a70ee2873 [release-branch.go1.17] go1.17.7
Change-Id: I760af1114e06bf408715e094d8d5b66c5aeb3e16
Reviewed-on: https://go-review.googlesource.com/c/go/+/384494
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
2022-02-09 18:09:24 +00:00
Cherry Mui
1952c65f9a [release-branch.go1.17] runtime: set vdsoSP to caller's SP consistently
m.vdsoSP should be set to the SP of the caller of nanotime1,
instead of the SP of nanotime1 itself, which matches m.vdsoPC.
Otherwise the unmatched vdsoPC and vdsoSP would make the stack
trace look like recursive.

We already do it correctly on AMD64, 386, and RISCV64. This CL
fixes the rest.

Also incorporate CL 352509, skipping a flaky test.

Updates #47324, #50772.
Fixes #50781.

Change-Id: I98b6fcfbe9fc6bdd28b8fe2a1299b7c505371dd4
Reviewed-on: https://go-review.googlesource.com/c/go/+/337590
Trust: Cherry Mui <cherryyz@google.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
(cherry picked from commit 217507eb03)
Reviewed-on: https://go-review.googlesource.com/c/go/+/380715
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2022-02-07 22:08:06 +00:00
Cherry Mui
4a31565cc0 [release-branch.go1.17] cmd/link: force eager binding when using plugins on darwin
When building/using plugins on darwin, we need to use flat
namespace so the same symbol from the main executable and the
plugin can be resolved to the same address. Apparently, when using
flat namespace the dynamic linker can hang at forkExec when
resolving a lazy binding. Work around it by forcing early bindings.

Updates #38824.
Fixes #50246.

Change-Id: I983aa0a0960b15bf3f7871382e8231ee244655f4
Reviewed-on: https://go-review.googlesource.com/c/go/+/372798
Trust: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit c5fee935bb)
Reviewed-on: https://go-review.googlesource.com/c/go/+/373094
2022-02-07 20:38:20 +00:00
Filippo Valsorda
e163319023 [release-branch.go1.17] crypto/elliptic: make IsOnCurve return false for invalid field elements
Updates #50974
Fixes #50978
Fixes CVE-2022-23806

Change-Id: I0201c2c88f13dd82910985a495973f1683af9259
Reviewed-on: https://go-review.googlesource.com/c/go/+/382854
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
Trust: Katie Hockman <katie@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-02-07 19:24:37 +00:00
Bryan C. Mills
fbcc30a2c9 [release-branch.go1.17] cmd/go/internal/modfetch: do not short-circuit canonical versions
Since at least CL 121857, the conversion logic in
(*modfetch).codeRepo.Stat has had a short-circuit to use the version
requested by the caller if it successfully resolves and is already
canonical.

However, we should not use that version if it refers to a branch
instead of a tag, because branches (unlike tags) usually do not refer
to a single, stable release: a branch named "v1.0.0" may be for the
development of the v1.0.0 release, or for the development of patches
based on v1.0.0, but only one commit (perhaps at the end of that
branch — but possibly not even written yet!) can be that specific
version.

We already have some logic to prefer tags that are semver-equivalent
to the version requested by the caller. That more general case
suffices for exact equality too — so we can eliminate the
special-case, fixing the bug and (happily!) also somewhat simplifying
the code.

Updates #35671
Fixes #50687
Fixes CVE-2022-23773

Change-Id: I2fd290190b8a99a580deec7e26d15659b58a50b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/378400
Trust: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit fa4d9b8e2b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/382835
2022-02-07 18:43:23 +00:00
David Chase
acb1ce53f9 [release-branch.go1.17] cmd/compile: remove incorrect arm,arm64 CMP->CMN transformations
These can go wrong when one of the operands is the minimum integer value.

Fixes #50867.

Change-Id: I238fe284f60c7ee5aeb9dc9a18e8b1578cdb77d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/381318
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit b7b44b3173)
Reviewed-on: https://go-review.googlesource.com/c/go/+/381474
Run-TryBot: Cherry Mui <cherryyz@google.com>
2022-02-07 18:41:51 +00:00
Cherry Mui
1651426f77 [release-branch.go1.17] cmd/compile: don't elide extension for LoadReg to FP register on MIPS64
For an extension operation like MOVWreg, if the operand is already
extended, we optimize the second extension out. Usually a LoadReg
of a proper type would come already extended, as a MOVW/MOVWU etc.
instruction does. But for a LoadReg to a floating point register,
the instruction does not do the extension. So we cannot elide the
extension.

Updates #50671.
Fixes #50683.

Change-Id: Id8991df78d5acdecd3fd6138c558428cbd5f6ba3
Reviewed-on: https://go-review.googlesource.com/c/go/+/379236
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit d93ff73ae2)
Reviewed-on: https://go-review.googlesource.com/c/go/+/379514
2022-02-07 17:28:28 +00:00
zhouguangyuan
17e179e187 [release-branch.go1.17] cmd/internal/obj/x86: modify the threshold of assert loop for span6
Updates #49716.
Fixes #50942.

Change-Id: I7ed73f874c2ee1ee3f31c9c4428ed484167ca803
Reviewed-on: https://go-review.googlesource.com/c/go/+/366094
Reviewed-by: Cherry Mui <cherryyz@google.com>
Trust: Heschi Kreinick <heschi@google.com>
(cherry picked from commit 14f2b2a4c5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/383214
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
2022-02-07 17:27:16 +00:00
Ethan Anderson
faa04090f8 [release-branch.go1.17] cmd/go: remove mercurial from bitbucket vcs options
Mercurial was deprecated as of July 1, 2020 as per https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket

Fixes #50812.
Updates #50810.

Change-Id: I0d40f84aaa393905cae7c4bed8919b15de9a5f6d
Reviewed-on: https://go-review.googlesource.com/c/go/+/371720
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Trust: Bryan Mills <bcmills@google.com>
(cherry picked from commit 5b1b80beb1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/380996
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2022-02-07 16:28:43 +00:00
Alessandro Arzilli
1b867ce3ef [release-branch.go1.17] debug/pe,debug/macho: add support for DWARF5 sections
Adds the same logic used in debug/elf to load DWARF5 sections.

For #49590
Fixes #50722

Change-Id: Iee05b9927a6f521842b330eab8942ade3fc2bd86
Reviewed-on: https://go-review.googlesource.com/c/go/+/363895
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Than McIntosh <thanm@google.com>
(cherry picked from commit 6c36c332fe)
Reviewed-on: https://go-review.googlesource.com/c/go/+/379914
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alessandro Arzilli <alessandro.arzilli@gmail.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
2022-02-03 20:56:27 +00:00
Katie Hockman
539d430efb [release-branch.go1.17] math/big: prevent overflow in (*Rat).SetString
Credit to rsc@ for the original patch.

Thanks to the OSS-Fuzz project for discovering this
issue and to Emmanuel Odeke (@odeke_et) for reporting it.

Updates #50699
Fixes #50701
Fixes CVE-2022-23772

Change-Id: I590395a3d55689625390cf1e58f5f40623b26ee5
Reviewed-on: https://go-review.googlesource.com/c/go/+/379537
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Julie Qiu <julie@golang.org>
(cherry picked from commit ad345c2659)
Reviewed-on: https://go-review.googlesource.com/c/go/+/381336
Reviewed-by: Filippo Valsorda <filippo@golang.org>
2022-01-28 15:39:12 +00:00
Damien Neil
3a34273b8a [release-branch.go1.17] net/http/internal/testcert: use FIPS-compliant certificate
Upgrade the test certificate from RSA 1024 (not FIPS-approved)
to RSA 2048 (FIPS-approved), allowing tests to pass when
the dev.boringcrypto branch FIPS-only mode is enabled.

For #48674.
Fixes #50586.

Change-Id: I613d2f8d0207bf3683fd0df256bf0167604996c5
Reviewed-on: https://go-review.googlesource.com/c/go/+/353869
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
(cherry picked from commit 90860e0c31)
Reviewed-on: https://go-review.googlesource.com/c/go/+/380995
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-01-27 15:54:22 +00:00
Carlos Amedee
9de1ac6ac2 [release-branch.go1.17] go1.17.6
Change-Id: I66a51a8fb3405395c066db37195e7e2a5c44a2d6
Reviewed-on: https://go-review.googlesource.com/c/go/+/375975
Trust: Carlos Amedee <carlos@golang.org>
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
2022-01-06 19:06:43 +00:00
Carlos Amedee
dbdf055101 [release-branch.go1.17] net/http: update bundled golang.org/x/net/http2
Pull in approved backports to golang.org/x/net/http2:

    21a9c9c http2: prioritize RST_STREAM frames in random write scheduler

By doing:

    $ go get -d golang.org/x/net@internal-branch.go1.17-vendor
    $ go mod tidy
    $ go mod vendor
    $ go generate -run=bundle std

Fixes #49921

Change-Id: I04739a30d84a8ae449374eca8bb11c7d2d215ad9
Reviewed-on: https://go-review.googlesource.com/c/go/+/375814
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Trust: Carlos Amedee <carlos@golang.org>
2022-01-06 15:30:17 +00:00
Ian Lance Taylor
ab70d7c799 [release-branch.go1.17] cmd/link: use SHT_INIT_ARRAY for .init_array section
For #50295
Fixes #50297

Change-Id: If55ebcd5f2af724da7c9c744458a56d21a7ddde7
Reviewed-on: https://go-review.googlesource.com/c/go/+/373734
Trust: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit cfb0cc3552)
Reviewed-on: https://go-review.googlesource.com/c/go/+/374194
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2022-01-05 18:14:20 +00:00
Michael Anthony Knyszek
1242f430a9 [release-branch.go1.17] runtime: set iOS addr space to 40 bits with incremental pagealloc
In iOS <14, the address space is strictly limited to 8 GiB, or 33 bits.
As a result, the page allocator also assumes all heap memory lives in
this region. This is especially necessary because the page allocator has
a PROT_NONE mapping proportional to the size of the usable address
space, so this keeps that mapping very small.

However starting with iOS 14, this restriction is relaxed, and mmap may
start returning addresses outside of the <14 range. Today this means
that in iOS 14 and later, users experience an error in the page
allocator when a heap arena is mapped outside of the old range.

This change increases the ios/arm64 heapAddrBits to 40 while
simultaneously making ios/arm64 use the 64-bit pagealloc implementation
(with reservations and incremental mapping) to accommodate both iOS
versions <14 and 14+.

Once iOS <14 is deprecated, we can remove these exceptions and treat
ios/arm64 like any other arm64 platform.

This change also makes the BaseChunkIdx expression a little bit easier
to read, while we're here.

For #46860.
Fixes #48116.

Change-Id: I13865f799777739109585f14f1cc49d6d57e096b
Reviewed-on: https://go-review.googlesource.com/c/go/+/344401
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Austin Clements <austin@google.com>
(cherry picked from commit af368da0b137116faba81ca249a8d964297e6e45)
Reviewed-on: https://go-review.googlesource.com/c/go/+/369737
2021-12-22 22:05:22 +00:00
Cherry Mui
59f1a26262 [release-branch.go1.17] runtime/race: rebuild darwin syso to work around macOS 12 malloc reserved address
On macOS 12 a new malloc implementation (nano) is used by default,
and apparently it reserves address range
0x600000000000-0x600020000000, which conflicts with the address
range that TSAN uses for Go. Work around the issue by changing the
address range slightly.

The actual change is made on LLVM at https://reviews.llvm.org/D114825 .
This CL includes syso's built with the patch applied.

The syso in 1.17 was identical to the syso before the equivalent fix
on the main branch, so the back-ported syso is identical to the fixed
syso on the main branch.

Fixes #50073.
Updates #49138.

Change-Id: I7b367d6e042b0db39a691c71601c98e4f8728a70
Reviewed-on: https://go-review.googlesource.com/c/go/+/367916
Trust: Cherry Mui <cherryyz@google.com>
Reviewed-by: Austin Clements <austin@google.com>
(cherry picked from commit 5f6552018d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/370697
2021-12-22 16:58:09 +00:00
hanpro
ebd1b4d97d [release-branch.go1.17] cmd/compile: avoid adding LECall to the entry block when has opendefers
The openDeferRecord always insert vardef/varlive pairs into the entry block, it may destroy the mem chain when LECall's args are writing into the same block. So create a new block before that happens.

Fixes #49413

Change-Id: Ibda6c4a45d960dd412a641f5e02276f663c80785
Reviewed-on: https://go-review.googlesource.com/c/go/+/361410
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Alberto Donizetti <alb.donizetti@gmail.com>
Trust: Than McIntosh <thanm@google.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit 4f083c7dcf)
Reviewed-on: https://go-review.googlesource.com/c/go/+/362054
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-21 23:28:20 +00:00
Keith Randall
0aa7f8fd4d [release-branch.go1.17] reflect: keep pointer in aggregate-typed args live in Call
When register ABI is used, reflect.Value.Call prepares the call
arguments in a memory representation of the argument registers.
It has special handling to keep the pointers in arguments live.
Currently, this handles pointer-typed arguments. But when an
argument is an aggregate-type that contains pointers and passed
in registers, it currently doesn't keep the pointers live. Do
so in this CL.

Fixes #49961

Change-Id: I9264a8767e2a2c48573f6047144759b845dcf480
Reviewed-on: https://go-review.googlesource.com/c/go/+/369098
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-12-21 22:57:03 +00:00
Filippo Valsorda
4223f6eb23 [release-branch.go1.17] all: update vendored golang.org/x/crypto for cryptobyte fix
Updates #49678
Fixes #50165

Change-Id: I47dd959a787180a67856e60dfa6eba3ddd045972
Reviewed-on: https://go-review.googlesource.com/c/go/+/373361
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Reviewed-by: Julie Qiu <julie@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-21 21:52:46 +00:00
Alexander Rakoczy
de690c2ff8 [release-branch.go1.17] go1.17.5
Change-Id: Ief6fb9e836c1d40ece56868d65ebf65f74e65665
Reviewed-on: https://go-review.googlesource.com/c/go/+/370555
Trust: Alex Rakoczy <alex@golang.org>
Run-TryBot: Alex Rakoczy <alex@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-09 13:44:55 +00:00
Filippo Valsorda
48d948963c [release-branch.go1.17] net/http: update bundled golang.org/x/net/http2
Pull in security fix

    84cba54 http2: cap the size of the server's canonical header cache

Updates #50058
Fixes CVE-2021-44716

Change-Id: Ia89e3d22a173c6cb83f03608d5186fcd08f2956c
Reviewed-on: https://go-review.googlesource.com/c/go/+/370574
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-09 13:07:36 +00:00
Russ Cox
65633fee16 [release-branch.go1.17] syscall: avoid writing to p when Pipe(p) fails
Generally speaking Go functions make no guarantees
about what has happened to result parameters on error,
and Pipe is no exception: callers should avoid looking at
p if Pipe returns an error.

However, we had a bug in which ForkExec was using the
content of p after a failed Pipe, and others may too.
As a robustness fix, make Pipe avoid writing to p on failure.

Updates #50057

Change-Id: Ie8955025dbd20702fabadc9bbe1d1a5ac0f36305
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1291271
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/370535
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
2021-12-09 12:28:48 +00:00
Russ Cox
e46abcb816 [release-branch.go1.17] syscall: fix ForkLock spurious close(0) on pipe failure
Pipe (and therefore forkLockPipe) does not make any guarantees
about the state of p after a failed Pipe(p). Avoid that assumption
and the too-clever goto, so that we don't accidentally Close a real fd
if the failed pipe leaves p[0] or p[1] set >= 0.

Updates #50057
Fixes CVE-2021-44717

Change-Id: Iff8e19a6efbba0c73cc8b13ecfae381c87600bb4
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1291270
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/370534
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
2021-12-09 12:28:39 +00:00
Heschi Kreinick
61317ef99e [release-branch.go1.17] misc/cgo/testplugin: skip TestIssue25756pie on darwin/arm64 builder
Repeat of CL 321349 for macOS 12. We won't need to do this again -- the
test is passing at tip.

Updates #46239.

Change-Id: Ib279ada443ee03eb8e70fde4bbfba65ce0f6322e
Reviewed-on: https://go-review.googlesource.com/c/go/+/369748
Trust: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2021-12-06 23:45:46 +00:00
Heschi Kreinick
0f2d0d0694 [release-branch.go1.17] go1.17.4
Change-Id: I11748377b7a35bd38b52e6f81093cc210f6d2857
Reviewed-on: https://go-review.googlesource.com/c/go/+/368695
Trust: Heschi Kreinick <heschi@google.com>
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2021-12-02 20:02:34 +00:00
Cuong Manh Le
759a9211d4 [release-branch.go1.17] cmd/compile: only update source type when processing struct/array
This is backport of CL 3651594, with the test from CL 360057.

CL 360057 fixed missing update source type in storeArgOrLoad. However,
we should only update the type when processing struct/array. If we
update the type right before calling storeArgOrLoad, we may generate a
value with invalid type, e.g, OpStructSelect with non-struct type.

Fixes #49392

Change-Id: Ib7e10f72f818880f550aae5c9f653db463ce29b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/361594
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/361596
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2021-12-02 17:52:07 +00:00
Michael Anthony Knyszek
01779135c0 [release-branch.go1.17] net/http: update bundled golang.org/x/net/http2
Pull in approved backports to golang.org/x/net/http2:

    85e122b net/http2: Fix handling of expect continue
    1dc0aec http2: don't count aborted streams as active in tests
    e973a42 ipv6: OpenBSD does not appear to support multicast loopback
    9592dd5 http2: avoid busy loop when ResponseHeaderTimeout is set
    94fb2bc http2: avoid spurious RoundTrip error when server closes and resets stream
    e108c19 http2: close conns after use when req.Close is set

By doing:

    $ go get -d golang.org/x/net@internal-branch.go1.17-vendor
    go: upgraded golang.org/x/net v0.0.0-20211101194204-95aca89e93de => v0.0.0-20211201233630-85e122b1a9b3
    $ go mod tidy
    $ go mod vendor
    $ go generate -run=bundle std

Fixes #49561.
Fixes #49624.
Fixes #49662.
Fixes #49905.
Fixes #49909.
Fixes #49911.

Change-Id: Ia8f432bd3ea77d24e63d46c8ed2ac8d275406b52
Reviewed-on: https://go-review.googlesource.com/c/go/+/368574
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-12-02 04:43:37 +00:00
Robert Griesemer
66007e5cfc [release-branch.go1.17] go/types: break cycles in invalid types
This is a partial port of CL 354329 from types2 to go/types.
It contains an adjustment to type.go to deal with possibly
invalid type bounds.

Fixes #48825.
For #48819.

Change-Id: I9efdcdbfa6432f3cee64d924a4c67ecc6793cf86
Reviewed-on: https://go-review.googlesource.com/c/go/+/354349
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/368456
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
2021-12-01 23:34:46 +00:00
Damien Neil
3c50f27391 [release-branch.go1.17] net/http: do not send Transfer-Encoding: identity in responses
Server handlers may set a "Transfer-Encoding: identity" header on
responses to disable chunking, but this header should not be sent
on the wire.

For #49194.
Fixes #49568.

Change-Id: I46a9e3b8ff9d93edd7d1c34d264fc309fa322ad5
Reviewed-on: https://go-review.googlesource.com/c/go/+/359176
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit b69b2f63d6)
Reviewed-on: https://go-review.googlesource.com/c/go/+/368087
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-12-01 22:10:49 +00:00
Damien Neil
ab175939e2 [release-branch.go1.17] net/http: do not cancel request context on response body read
When sending a Request with a non-context deadline, we create a
context with a timeout. This context is canceled when closing the
response body, and also if a read from the response body returns
an error (including io.EOF).

Cancelling the context in Response.Body.Read interferes with the
HTTP/2 client cleaning up after a request is completed, and is
unnecessary: The user should always close the body, the impact
from not canceling the context is minor (the context timer leaks
until it fires).

Fixes #49559.
For #49366.

Change-Id: Ieaed866116916261d9079f71d8fea7a7b303b8fb
Reviewed-on: https://go-review.googlesource.com/c/go/+/361919
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit 76fbd61673)
Reviewed-on: https://go-review.googlesource.com/c/go/+/368085
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-12-01 22:10:22 +00:00
Jason A. Donenfeld
f0ee7c6f96 [release-branch.go1.17] runtime: keep //go:cgo_unsafe_args arguments alive to prevent GC
When syscall's DLL.FindProc calls into syscall_getprocaddress with a
byte slice pointer, we need to keep those bytes alive. Otherwise the GC
will collect the allocation, and we wind up calling `GetProcAddress` on
garbage, which showed up as various flakes in the builders. It turns out
that this problem extends to many uses of //go:cgo_unsafe_args
throughout, on all platforms. So this patch fixes the issue by keeping
non-integer pointer arguments alive through their invocation in
//go:cgo_unsafe_args functions.

Fixes #49868.
Updates #49731.

Change-Id: I93e4fbc2e8e210cb3fc53149708758bb33f2f9c7
Reviewed-on: https://go-review.googlesource.com/c/go/+/368355
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
2021-12-01 22:09:30 +00:00
zhouguangyuan
b7651e5046 [release-branch.go1.17] time: fix looking for zone offset when date is close to a zone transition
The old implement passed start - 1 or end in func lookup to adjust the offset.But if the time is close to the last zoneTrans, like the issue, testcase and comment, the "start" from lookup will be omega. It can't be adjusted correctly.

Fixes #49407

Change-Id: Ibaf82dc4db6d5dd3279796f003d2b19c38a26341
Reviewed-on: https://go-review.googlesource.com/c/go/+/360616
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Robert Findley <rfindley@google.com>
(cherry picked from commit 90462dfc3a)
Reviewed-on: https://go-review.googlesource.com/c/go/+/361955
Trust: Dmitri Shuralyov <dmitshur@golang.org>
2021-11-29 19:46:17 +00:00
Dan Scales
4eaf0b7a58 [release-branch.go1.17] cmd/compile: fix case where init info of OAS node is dropped
When an OAS node is converted to an OSELRECV2 node in tcSelect(), the
possible DCL node in the Init field was being dropped, since a
completely new node was being created and the Init field was not set. I
don't expect n.Init() to be set for the ORECV case, but the code now
deals with that too.

Fixed bug in both tcSelect() and transformSelect().

Cherry-picked from https://go-review.googlesource.com/c/go/+/348569

Fixes #49511

Change-Id: Id5b736daa8e90afda88aaa3769dde801db294c0d
Reviewed-on: https://go-review.googlesource.com/c/go/+/363664
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-11-24 19:38:31 +00:00
Jason A. Donenfeld
4536558f16 [release-branch.go1.17] runtime: use correct constant when computing nsec remainder
A code comment on amd64 for windows and plan9 contained a snippet for
splitting apart the sec and nsec components of a unix timestamp, with
produced assembly below, which was then cleaned up by hand. When arm64
was ported, that code snippet in the comment went through the compiler
to produce some code that was then pasted and cleaned up. Unfortunately,
the comment had a typo in it, containing 8 zeros instead of 9.

This resulted in the constant used in the assembly being wrong, spotted
by @bufflig's eagle eyes. So, this commit fixes the comment on all three
platforms, and the assembly on windows/arm64.

Updates #48072.
Fixes #49369.

Change-Id: I786fe89147328b0d25544f52c927ddfdb9f6f1cf
Reviewed-on: https://go-review.googlesource.com/c/go/+/361474
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Patrik Nyblom <pnyb@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/361476
2021-11-24 19:34:05 +00:00
Jason A. Donenfeld
e347c89598 [release-branch.go1.17] runtime: on windows, read nanotime with one instruction or issue barrier
On 64-bit, this is more efficient, and on ARM64, this prevents the time
from moving backwards due to the weaker memory model. On ARM32 due to
the weaker memory model, we issue a memory barrier.

Updates #48072.
Updates #49369.

Change-Id: If4695716c3039d8af14e14808af217f5c99fc93a
Reviewed-on: https://go-review.googlesource.com/c/go/+/361057
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/361475
Reviewed-by: Patrik Nyblom <pnyb@google.com>
2021-11-24 19:33:56 +00:00
Keith Randall
1c05b9b024 [release-branch.go1.17] cmd/compile: fix fuse pass to do CFG surgery correctly
removePred and removeArg do different things. removePred moves the last
predecessor to index k, whereas removeArg slides all the args k or
greater down by 1 index.

Kind of unfortunate different behavior in things named similarly.

Fixes #49129

Change-Id: I9ae409bdac744e713f4c121f948e43db6fdc8542
Reviewed-on: https://go-review.googlesource.com/c/go/+/358117
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
(cherry picked from commit 8dbf3e9393)
Reviewed-on: https://go-review.googlesource.com/c/go/+/358118
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-11-24 19:33:23 +00:00
Bryan C. Mills
364f15ff9f [release-branch.go1.17] cmd/go: forward the MallocNanoZone variable to script tests
For #49138
Updates #49723
Fixes #49729

Change-Id: Ia93130fdc042a1e2107be95cccd7e7eeaa909a87
Reviewed-on: https://go-review.googlesource.com/c/go/+/366254
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit 189b4a2f42)
Reviewed-on: https://go-review.googlesource.com/c/go/+/366257
TryBot-Result: Go Bot <gobot@golang.org>
2021-11-22 20:49:19 +00:00
Cherry Mui
b954f58e9d [release-branch.go1.17] cmd/link: don't use label symbol for absolute address relocations on ARM64 PE
On ARM64 PE, when external linking, the PE relocation does not
have an explicit addend, and instead has the addend encoded in
the instruction or data. An instruction (e.g. ADRP, ADD) has
limited width for the addend, so when the addend is large we use
a label symbol, which points to the middle of the original target
symbol, and a smaller addend. But for an absolute address
relocation in the data section, we have the full width to encode
the addend and we should not use the label symbol. Also, since we
do not adjust the addend in the data, using the label symbol will
actually make it point to the wrong address. E.g for an R_ADDR
relocation targeting x+0x123456, we should emit 0x123456 in the
data with an IMAGE_REL_ARM64_ADDR64 relocation pointing to x,
whereas the current code emits  0x123456 in the data with an
IMAGE_REL_ARM64_ADDR64 relocation pointing to the label symbol
x+1MB, so it will actually be resolved to x+0x223456. This CL
fixes this.

Fixes #49479

Change-Id: I64e02b56f1d792f8c20ca61b78623ef5c3e34d7e
Reviewed-on: https://go-review.googlesource.com/c/go/+/360895
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
(cherry picked from commit 988efd5819)
Reviewed-on: https://go-review.googlesource.com/c/go/+/363014
Run-TryBot: Carlos Amedee <carlos@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-11-10 19:35:55 +00:00
Cuong Manh Le
f1935e2c43 [release-branch.go1.17] cmd/go: fix mod_get_direct
https://github.com/googleapis/google-cloud-go has changed the default
branch from master to main, causing mod_get_direct failed on longtest.

Change-Id: I8fe0356b2ff532d1fdedbcb1e1832d7335babaa0
Reviewed-on: https://go-review.googlesource.com/c/go/+/361965
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit b7529c3617)
Reviewed-on: https://go-review.googlesource.com/c/go/+/362535
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-11-09 16:04:46 +00:00
Than McIntosh
f58c78a577 [release-branch.go1.17] go1.17.3
Change-Id: Iaf0b58846a9641525f43f4dc64962c13c0c7e8e3
Reviewed-on: https://go-review.googlesource.com/c/go/+/361200
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-11-04 13:55:24 +00:00
Jason7602
b212ba6829 [release-branch.go1.17] archive/zip: don't panic on (*Reader).Open
Previously, opening a zip with (*Reader).Open could result in a panic if
the zip contained a file whose name was exclusively made up of slash
characters or ".." path elements.

Open could also panic if passed the empty string directly as an argument.

Now, any files in the zip whose name could not be made valid for
fs.FS.Open will be skipped, and no longer added to the fs.FS file list,
although they are still accessible through (*Reader).File.

Note that it was already the case that a file could be accessible from
(*Reader).Open with a name different from the one in (*Reader).File, as
the former is the cleaned name, while the latter is the original one.

Finally, made the actual panic site robust as a defense-in-depth measure.

Fixes CVE-2021-41772
Fixes #48252
Updates #48085

Co-authored-by: Filippo Valsorda <filippo@golang.org>
Change-Id: I6271a3f2892e7746f52e213b8eba9a1bba974678
Reviewed-on: https://go-review.googlesource.com/c/go/+/349770
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Trust: Katie Hockman <katie@golang.org>
Trust: Julie Qiu <julie@golang.org>
(cherry picked from commit b24687394b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/360859
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
2021-11-03 16:57:44 +00:00
Dmitri Shuralyov
f9cb33c7c9 [release-branch.go1.17] net/http: update bundled golang.org/x/net/http2
Pull in approved backports to golang.org/x/net/http2:

	95aca89 set ContentLength to -1 for HEAD response with no Content-Length
	bd5b1b8 set Response.ContentLength to 0 when headers end stream
	27001ec don't abort half-closed streams on server connection close
	f0a8156 on write errors, close ClientConn before returning from RoundTrip
	9a182eb deflake TestTransportReqBodyAfterResponse_200
	821db7b close the Request's Body when aborting a stream
	028e125 return unexpected eof on empty response with non-zero content length
	5388f2f don't rely on system TCP buffer sizes in TestServer_MaxQueuedControlFrames
	fc298ce detect write-blocked PING frames
	e96ad84 avoid race in TestTransportReqBodyAfterResponse_403.
	7f15435 avoid clientConnPool panic when NewClientConn fails
	9572bae avoid extra GetConn trace call
	b04064c refactor request write flow
	7e165c9 remove PingTimeout from TestTransportPingWhenReading
	ef976fc fix Transport connection pool TOCTOU max concurrent stream bug
	1d9597c shut down idle Transport connections after protocol errors
	c173d09 remove check for read-after-close of request bodies
	466a463 fix race in DATA frame padding refund
	4028c5f avoid blocking while holding ClientConn.mu
	b91f72d fix off-by-one error in client check for max concurrent streams
	21e6c63 close request body after early RoundTrip failures
	e79adf9 limit client initial MAX_CONCURRENT_STREAMS
	c0c2bc5 make Transport not reuse conns after a stream protocol error
	14c0235 accept zero-length block fragments in HEADERS frames
	0d2c43c close the request body if needed
	5627bb0 reduce frameScratchBuffer caching aggressiveness
	c9f4fb0 also set "http/1.1" ALPN in ConfigureServer

By doing:

	$ go get -d golang.org/x/net@internal-branch.go1.17-vendor
	go get: upgraded golang.org/x/net v0.0.0-20210901185426-6d2eada6345e => v0.0.0-20211101194204-95aca89e93de
	$ go mod tidy
	$ go mod vendor
	$ go generate -run=bundle std

Fixes #49077.
Fixes #48823.
Fixes #48650.

Change-Id: Idb972ba5313080626b60b4111d52b80197364ff4
Reviewed-on: https://go-review.googlesource.com/c/go/+/359776
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-11-01 21:27:46 +00:00
Roland Shoemaker
4a842985bf [release-branch.go1.17] debug/macho: fail on invalid dynamic symbol table command
Fail out when loading a file that contains a dynamic symbol table
command that indicates a larger number of symbols than exist in the
loaded symbol table.

Thanks to Burak Çarıkçı - Yunus Yıldırım (CT-Zer0 Crypttech) for
reporting this issue.

Updates #48990
Fixes #48992
Fixes CVE-2021-41771

Change-Id: Ic3d6e6529241afcc959544b326b21b663262bad5
Reviewed-on: https://go-review.googlesource.com/c/go/+/355990
Reviewed-by: Julie Qiu <julie@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Katie Hockman <katie@golang.org>
(cherry picked from commit 61536ec030)
Reviewed-on: https://go-review.googlesource.com/c/go/+/359455
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2021-10-29 19:42:51 +00:00
Russ Cox
f6f024f120 [release-branch.go1.17] cmd/go: update for //go:build lines
cmd/go has its own //go:build evaluator, which is needed for
patterns like 'all'. The code is a modified copy of some unexported
routines from the go/build package. Update it by copying those
again and re-modifying them. The modifications are primarily the new
func eval and also ignoring errors.

This CL will need to be backported to Go 1.17, or else Go 1.17
will break when faced with certain //go:build-only repos during
'go list all' or 'go mod tidy'.

For #41184.
Fixes #49198.

Change-Id: Ie0fe3caa8d49004935ecd76d7977f767fe50e317
Reviewed-on: https://go-review.googlesource.com/c/go/+/359355
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/359404
2021-10-28 21:17:17 +00:00
Richard Musiol
18b970277e [release-branch.go1.17] cmd/link: increase reserved space for passing env on wasm
On wasm, the wasm_exec.js helper passes the command line arguments and
environment variables via a reserved space in the wasm linear memory.
Increase this reserved space from 4096 to 8192 bytes so more environment
variables can fit into the limit.

Later, after https://golang.org/cl/350737 landed, we can switch to the
WASI interface for getting the arguments and environment. This would
remove the limit entirely.

Updates #49011.
Fixes #49154.

Change-Id: I48a6e952a97d33404ed692c98e9b49c5cd6b269b
Reviewed-on: https://go-review.googlesource.com/c/go/+/358194
Trust: Richard Musiol <neelance@gmail.com>
Run-TryBot: Richard Musiol <neelance@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit 252324e879)
Reviewed-on: https://go-review.googlesource.com/c/go/+/359399
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
2021-10-28 18:01:34 +00:00
zhouguangyuan
91aa2f190a [release-branch.go1.17] cmd/link: disable weak reference in itab if build with "-linkshared"
When build with "-linkshared", we can't tell if the interface method will be used or not. It can be used in shared library.
This CL backport this fix to 1.17.

Fixes #49086

Change-Id: Iba12812f199b7679cf2fd41a304268d6d6dd03c6
Reviewed-on: https://go-review.googlesource.com/c/go/+/350189
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Alexander Rakoczy <alex@golang.org>
(cherry picked from commit f687831e4c)
Reviewed-on: https://go-review.googlesource.com/c/go/+/357231
Trust: Ian Lance Taylor <iant@golang.org>
2021-10-28 16:34:40 +00:00
Michael Pratt
8bdb0b235a [release-branch.go1.17] runtime: consistently access pollDesc r/w Gs with atomics
Both netpollblock and netpollunblock read gpp using a non-atomic load.
When consuming a ready event, netpollblock clears gpp using a non-atomic
store, thus skipping a barrier.

Thus on systems with weak memory ordering, a sequence like so this is
possible:

             T1                                T2

1. netpollblock: read gpp -> pdReady
2. netpollblock: store gpp -> 0

                                 3. netpollunblock: read gpp -> pdReady
                                 4. netpollunblock: return

i.e., without a happens-before edge between (2) and (3), netpollunblock
may read the stale value of gpp.

Switch these access to use atomic loads and stores in order to create
these edges.

For ease of future maintainance, I've simply changed rg and wg to always
be accessed atomically, though I don't believe pollOpen or pollClose
require atomics today.

For #48925
Fixes #49010

Change-Id: I903ea667eea320277610b4f969129935731520c3
Reviewed-on: https://go-review.googlesource.com/c/go/+/355952
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit 1b072b3ed5)
Reviewed-on: https://go-review.googlesource.com/c/go/+/356369
2021-10-28 15:31:28 +00:00
Keith Randall
3a03ddf735 [release-branch.go1.17] cmd/compile: ensure constant shift amounts are in range for arm
Ensure constant shift amounts are in the range [0-31]. When shift amounts
are out of range, bad things happen. Shift amounts out of range occur
when lowering 64-bit shifts (we take an in-range shift s in [0-63] and
calculate s-32 and 32-s, both of which might be out of [0-31]).

The constant shift operations themselves still work, but their shift
amounts get copied unmolested to operations like ORshiftLL which use only
the low 5 bits. That changes an operation like <<100 which unconditionally
produces 0, to <<4, which doesn't.

Fixes #48479

Change-Id: I87363ef2b4ceaf3b2e316426064626efdfbb8ee3
Reviewed-on: https://go-review.googlesource.com/c/go/+/350969
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit eff27e858b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/351069
Reviewed-by: Austin Clements <austin@google.com>
2021-10-27 21:13:34 +00:00
Keith Randall
644555d34e [release-branch.go1.17] cmd/compile: fix simplification rules on arm/arm64
Fixes #48475

Change-Id: Ic1e918f916eae223a3b530a51a58f03031924670
Reviewed-on: https://go-review.googlesource.com/c/go/+/350913
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/351071
Reviewed-by: Austin Clements <austin@google.com>
2021-10-27 20:42:29 +00:00
Jason A. Donenfeld
11b64b428b [release-branch.go1.17] syscall: do not use handle lists on windows when NoInheritHandles is true
If NoInheritHandles is passed, then we shouldn't attempt to do anything
with handle lists. Otherwise CreateProcess fails with invalid param,
because it's being told both to not inherit handles and to inherit
certain handles.

This commit fixes that by using the same logic for handle lists as it
does for enabling or disabling handle inheritance. It also adds a test
to make sure this doesn't regress again.

Updates #48040
Fixes #48075

Change-Id: I507261baeec263091738ab90157a991d917dc92f
Reviewed-on: https://go-review.googlesource.com/c/go/+/350416
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Patrik Nyblom <pnyb@google.com>
2021-10-25 21:16:46 +00:00
Michael Anthony Knyszek
2ac3bdf378 [release-branch.go1.17] go1.17.2
Change-Id: Iffde23eabdc5c9474cd7f7b795cc187d78ca0f55
Reviewed-on: https://go-review.googlesource.com/c/go/+/354594
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-10-07 18:11:41 +00:00
Michael Knyszek
4925e0766f [release-branch.go1.17] misc/wasm, cmd/link: do not let command line args overwrite global data
On Wasm, wasm_exec.js puts command line arguments at the beginning
of the linear memory (following the "zero page"). Currently there
is no limit for this, and a very long command line can overwrite
the program's data section. Prevent this by limiting the command
line to 4096 bytes, and in the linker ensuring the data section
starts at a high enough address (8192).

(Arguably our address assignment on Wasm is a bit confusing. This
is the minimum fix I can come up with.)

Thanks to Ben Lubar for reporting this issue.

Change by Cherry Mui <cherryyz@google.com>.

For #48797
Fixes #48800
Fixes CVE-2021-38297

Change-Id: I0f50fbb2a5b6d0d047e3c134a88988d9133e4ab3
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1205933
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/354592
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2021-10-07 14:54:47 +00:00
Cuong Manh Le
b18ba59aaf [release-branch.go1.17] cmd/compile: fold handling OCONV logic to separate function
So next CL can re-use the logic to perform checkptr instrumentation.

For #48561

Change-Id: I3241e9c3c84da04db71fd1d4fd83cb76b2e18521
Reviewed-on: https://go-review.googlesource.com/c/go/+/345435
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
(cherry picked from commit 8fad81cd62)
Reviewed-on: https://go-review.googlesource.com/c/go/+/354352
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
2021-10-06 22:28:59 +00:00
Jay Conrod
04242ac88f [release-branch.go1.17] cmd/go: write go.mod requirements more consistently for go 1.17+
If go.mod declares 1.17 or higher, when the go command rewrites go.mod
(for example, after 'go mod tidy'), it will be more consistent about
moving requirements in two blocks, one containing only direct
requirements, and one containing only indirect requirements.

The go command will not move requirements into or out of a block with
comments. It may still update versions and "// indirect" comments, and
it may delete unneeded requirements though.

Fixes #47756

Change-Id: Ia6fb3e302be53097893abf01aa7cea60ac7b069a
Reviewed-on: https://go-review.googlesource.com/c/go/+/343432
Trust: Jay Conrod <jayconrod@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit 3c764babe7)
Reviewed-on: https://go-review.googlesource.com/c/go/+/351465
TryBot-Result: Go Bot <gobot@golang.org>
2021-09-28 20:30:45 +00:00
Ian Lance Taylor
c5c1d069da [release-branch.go1.17] text/template: initialize template before locking it
For #39807
For #48436
Fixes #48444

Change-Id: I75f82fd8738dd2f11f0c69b1230e1be1abc36024
Reviewed-on: https://go-review.googlesource.com/c/go/+/350730
Trust: Ian Lance Taylor <iant@golang.org>
Trust: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
(cherry picked from commit ba1c52d7d7)
Reviewed-on: https://go-review.googlesource.com/c/go/+/351115
2021-09-23 21:18:37 +00:00
Ian Lance Taylor
abc4f092ac [release-branch.go1.17] runtime: in adjustTimers back up as far as necessary
When the adjustTimers function removed a timer it assumed it was
sufficient to continue the heap traversal at that position.
However, in some cases a timer will be moved to an earlier
position in the heap. If that timer is timerModifiedEarlier,
that can leave timerModifiedEarliest not correctly representing
the earlier such timer.

Fix the problem by restarting the heap traversal at the earliest
changed position.

For #47762
Fixes #47859

Change-Id: I152bbe62793ee40a680baf49967bcb89b1f94764
Reviewed-on: https://go-review.googlesource.com/c/go/+/343882
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 2da3375e9b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/350001
2021-09-15 23:28:10 +00:00
korzhao
e79c297fa8 [release-branch.go1.17] time: propagate "," separator for fractional seconds into Format
In CL 300996 that fixed issue #6189, we made Parse recognize
"," as a separator for fractional seconds.
However, we didn't modify Format to propagate the separator
verbatim from Parse. Without this change, we break prior
functionality that relied on a comma being used in Format.

For #48037
Fixes #48177

Change-Id: I6565a25e8657ca3747a58b25acba58f27cdcddc0
Reviewed-on: https://go-review.googlesource.com/c/go/+/345438
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Cherry Mui <cherryyz@google.com>
(cherry picked from commit e1c3f2158f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/350149
Trust: Ian Lance Taylor <iant@golang.org>
2021-09-15 21:59:48 +00:00
Than McIntosh
21a4e67ad5 [release-branch.go1.17] go1.17.1
Change-Id: I05758c4bff332dbb71dbfb1f5743aeaf0a1b39d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/348813
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Trust: Than McIntosh <thanm@google.com>
2021-09-09 15:27:21 +00:00
Bryan C. Mills
328cf2e8b2 [release-branch.go1.17] cmd/go/internal/modload: scan dependencies of root paths when raising version limits in editRequirements
Updates #47979
Fixes #48156

Change-Id: I1d9d854cda1378e20c70e6c6789b77e42e467ca7
Reviewed-on: https://go-review.googlesource.com/c/go/+/347290
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
(cherry picked from commit 409434d623)
Reviewed-on: https://go-review.googlesource.com/c/go/+/348411
2021-09-08 20:41:51 +00:00
Damien Neil
fcce86c4cf [release-branch.go1.17] all: update golang.org/x/net to pull in CL 346890
For #47692.

Change-Id: I40d5a3ed245b99de5e82e336f955c60b58880cdb
Reviewed-on: https://go-review.googlesource.com/c/go/+/347009
Trust: Damien Neil <dneil@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-09-01 22:54:04 +00:00
Robert Griesemer
36c171763e [release-branch.go1.17] go/types: don't override x.mode before using it
Changing the mode of x before using the old value is clearly wrong.
And x is not needed anymore afterward so besides being misplaced,
the assignment is not needed in the first place.

Tested manually as it's a bit complicated to set up a test.

Fixes #47854.

Change-Id: I06f1fa9443eb98009b4276f566d557fd52f1d6d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/343809
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
(cherry picked from commit e17439e087)
Reviewed-on: https://go-review.googlesource.com/c/go/+/347149
Run-TryBot: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Robert Findley <rfindley@google.com>
Trust: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
2021-09-01 22:32:32 +00:00
Rob Findley
678b07d5e5 [release-branch.go1.17] go/types: fix panic with nil package name
This is a straightforward port of CL 320490 to go/types.

Fixes #48082

Change-Id: I763c806c777f926a563d8f9384764e5b3f7f083c
Reviewed-on: https://go-review.googlesource.com/c/go/+/324732
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
(cherry picked from commit e32fab145b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/347071
2021-09-01 22:31:06 +00:00
Jay Conrod
14c9b1e00b [release-branch.go1.17] cmd/go: ensure 'go get -u' can upgrade pruned (1.17+) modules
Fixes #47857

Change-Id: I981a31ba4ff716570ac4c6f35b289fa480faa5bb
Reviewed-on: https://go-review.googlesource.com/c/go/+/343879
Trust: Jay Conrod <jayconrod@google.com>
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit bdc1bef8a0)
Reviewed-on: https://go-review.googlesource.com/c/go/+/346211
2021-09-01 17:15:36 +00:00
Tobias Klauser
c35f8a37d9 [release-branch.go1.17] crypto/rand, internal/syscall/unix: don't use getentropy on iOS
CL 302489 switched crypto/rand to use getentropy on darwin, however this
function is not available on iOS. Enable getentropy only on macOS and
disable it on iOS.

Fixes #47814

Change-Id: Ib7ba5d77346aee87904bb93d60cacc845f5c0089
Reviewed-on: https://go-review.googlesource.com/c/go/+/343609
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
(cherry picked from commit 7007431374)
Reviewed-on: https://go-review.googlesource.com/c/go/+/343989
2021-09-01 17:08:11 +00:00
Cherry Mui
47a57bc4f0 [release-branch.go1.17] cmd/link: do not use GO_LDSO when cross compile
GO_LDSO is a setting that is set when the toolchain is build. It
only makes sense to use it on the host platform. Do not use it
when targetting a different platform.

In the past it was not a problem as GO_LDSO was almost always
unset. Now, with CL 301989 it is almost always set (maybe we want
to revisit it).

Updates #47760.
Fixes #47782.

Change-Id: I2704b9968781f46e2d2f8624090db19689b1a32f
Reviewed-on: https://go-review.googlesource.com/c/go/+/343010
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
(cherry picked from commit ddfcc02352)
Reviewed-on: https://go-review.googlesource.com/c/go/+/343309
2021-09-01 17:06:03 +00:00
Keith Randall
2d97a87287 [release-branch.go1.17] cmd/compile: allow embed into any byte slice type
Fixes #47754

Change-Id: Ia21ea9a67f36a3edfef1b299ae4f3b00c306cd68
Reviewed-on: https://go-review.googlesource.com/c/go/+/345092
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2021-09-01 16:49:05 +00:00
Cuong Manh Le
3969694203 [release-branch.go1.17] cmd/compile: fix method expression lookup during import
CL 309831 fixed importing of method expressions, by re-using the same
code already have for ODOTMETH. But that code does not work with
embedded field.

To fix this, we need to calculate all methods of the receiver base type
of method expression, before looking up the selection.

Fixes #48102

Change-Id: Ia244d36a3ed0f989735eb57becdfa70a81912f57
Reviewed-on: https://go-review.googlesource.com/c/go/+/346489
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/346670
Reviewed-by: Keith Randall <khr@golang.org>
2021-09-01 16:46:29 +00:00
Roland Shoemaker
1dd24caf08 [release-branch.go1.17] archive/zip: prevent preallocation check from overflowing
If the indicated directory size in the archive header is so large that
subtracting it from the archive size overflows a uint64, the check that
the indicated number of files in the archive can be effectively
bypassed. Prevent this from happening by checking that the indicated
directory size is less than the size of the archive.

Thanks to the OSS-Fuzz project for discovering this issue and to
Emmanuel Odeke for reporting it.

Fixes #47986
Updates #47801
Fixes CVE-2021-39293

Change-Id: Ifade26b98a40f3b37398ca86bd5252d12394dd24
Reviewed-on: https://go-review.googlesource.com/c/go/+/343434
Trust: Roland Shoemaker <roland@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
(cherry picked from commit bacbc33439)
Reviewed-on: https://go-review.googlesource.com/c/go/+/345410
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Cherry Mui <cherryyz@google.com>
2021-09-01 16:41:15 +00:00
Michael Anthony Knyszek
ec5170397c [release-branch.go1.17] go1.17
Change-Id: Ie59feb7f043574c7db4c7f14184603442638e4c0
Reviewed-on: https://go-review.googlesource.com/c/go/+/342470
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Trust: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
2021-08-16 16:23:06 +00:00
Jeff Wentworth
fdd6dfd507 [release-branch.go1.17] sync/atomic: fix documentation for CompareAndSwap
The documentation for CompareAndSwap atomic/value incorrectly labelled
the function as CompareAndSwapPointer. This PR fixes that.

Updates #47699.
Fixes #47703.

Change-Id: I6db08fdfe166570b775248fd24550f5d28e3434e
GitHub-Last-Rev: 41f7870792
GitHub-Pull-Request: golang/go#47700
Reviewed-on: https://go-review.googlesource.com/c/go/+/342210
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Trust: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Go Bot <gobot@golang.org>
(cherry picked from commit 0a0a160d4d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/342329
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2021-08-15 22:50:19 +00:00
Michael Pratt
f7b9470992 [release-branch.go1.17] runtime: drop SIGPROF while in ARM < 7 kernel helpers
On Linux ARMv6 and below runtime/internal/atomic.Cas calls into a kernel
cas helper at a fixed address. If a SIGPROF arrives while executing the
kernel helper, the sigprof lostAtomic logic will miss that we are
potentially in the spinlock critical section, which could cause
a deadlock when using atomics later in sigprof.

For #47505
Fixes #47688

Change-Id: If8ba0d0fc47e45d4e6c68eca98fac4c6ed4e43c1
Reviewed-on: https://go-review.googlesource.com/c/go/+/341889
Trust: Michael Pratt <mpratt@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
(cherry picked from commit 20a620fd9f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/341890
2021-08-13 16:34:25 +00:00
Russ Cox
4397d66bdd [release-branch.go1.17] time: fix docs for new comma layouts
The current text is slightly inaccurate. Make it more correct.

Change-Id: Iebe0051b74649d13982d7eefe3697f9e69c9b75d
Reviewed-on: https://go-review.googlesource.com/c/go/+/340449
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-on: https://go-review.googlesource.com/c/go/+/341949
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2021-08-13 16:26:40 +00:00
Dmitri Shuralyov
eb5a7b5050 [release-branch.go1.17] all: merge master (5805efc) into release-branch.go1.17
Merge List:

+ 2021-08-12 5805efc78e doc/go1.17: remove draft notice
+ 2021-08-12 39634e7dae CONTRIBUTORS: update for the Go 1.17 release
+ 2021-08-12 095bb790e1 os/exec: re-enable LookPathTest/16
+ 2021-08-11 dea23e9ca8 src/make.*: make --no-clean flag a no-op that prints a warning
+ 2021-08-11 d4c0ed26ac doc/go1.17: linker passes -I to extld as -Wl,--dynamic-linker
+ 2021-08-10 1f9c9d8530 doc: use "high address/low address" instead of "top/bottom"
+ 2021-08-09 f1dce319ff cmd/go: with -mod=vendor, don't panic if there are duplicate requirements
+ 2021-08-09 7aeaad5c86 runtime/cgo: when using msan explicitly unpoison cgoCallers
+ 2021-08-08 507cc341ec doc: add example for conversion from slice expressions to array ptr
+ 2021-08-07 891547e2d4 doc/go1.17: fix a typo introduced in CL 335135
+ 2021-08-06 8eaf4d16bc make.bash: do not overwrite GO_LDSO if already set
+ 2021-08-06 63b968f4f8 doc/go1.17: clarify Modules changes
+ 2021-08-06 70546f6404 runtime: allow arm64 SEH to be called if illegal instruction
+ 2021-08-05 fd45e267c2 runtime: warn that KeepAlive is not an unsafe.Pointer workaround
+ 2021-08-04 6e738868a7 net/http: speed up and deflake TestCancelRequestWhenSharingConnection
+ 2021-08-02 8a7ee4c51e io/fs: don't use absolute path in DirEntry.Name doc

Change-Id: Ie9ce48bf4e99457cde966c5f972b04140468fcf0
2021-08-12 14:04:53 -04:00
Alexander Rakoczy
72ab3ff68b [release-branch.go1.17] go1.17rc2
Change-Id: I1f1ada15d7365db3e48599fbaddd6a65a8e5d06c
Reviewed-on: https://go-review.googlesource.com/c/go/+/339130
Run-TryBot: Alexander Rakoczy <alex@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Alexander Rakoczy <alex@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2021-08-02 17:57:22 +00:00
Alexander Rakoczy
c3ccb77d1e [release-branch.go1.17] all: merge master (b8ca6e5) into release-branch.go1.17
Merge List:

+ 2021-07-31 b8ca6e59ed all: gofmt
+ 2021-07-30 b7a85e0003 net/http/httputil: close incoming ReverseProxy request body
+ 2021-07-29 70fd4e47d7 runtime: avoid possible preemption when returning from Go to C
+ 2021-07-28 9eee0ed439 cmd/go: fix go.mod file name printed in error messages for replacements
+ 2021-07-28 b39e0f461c runtime: don't crash on nil pointers in checkptrAlignment
+ 2021-07-27 7cd10c1149 cmd/go: use .mod instead of .zip to determine if version has go.mod file
+ 2021-07-27 c8cf0f74e4 cmd/go: add missing flag in UsageLine
+ 2021-07-27 7ba8e796c9 testing: clarify T.Name returns a distinct name of the running test
+ 2021-07-27 33ff155970 go/types: preserve untyped constants on the RHS of a shift expression
+ 2021-07-26 840e583ff3 runtime: correct variable name in comment
+ 2021-07-26 bfbb288574 runtime: remove adjustTimers counter
+ 2021-07-26 9c81fd53b3 cmd/vet: add missing copyright header
+ 2021-07-26 ecaa6816bf doc: clarify non-nil zero length slice to array pointer conversion
+ 2021-07-26 1868f8296e crypto/x509: update iOS bundled roots to version 55188.120.1.0.1
+ 2021-07-25 849b791129 spec: use consistent capitalization for rune literal hex constants
+ 2021-07-23 0914646ab9 doc/1.17: fix two dead rfc links
+ 2021-07-22 052da5717e cmd/compile: do not change field offset in ABI analysis
+ 2021-07-22 798ec73519 runtime: don't clear timerModifiedEarliest if adjustTimers is 0
+ 2021-07-22 fdb45acd1f runtime: move mem profile sampling into m-acquired section
+ 2021-07-21 3e48c0381f reflect: add missing copyright header
+ 2021-07-21 48c88f1b1b reflect: add Value.CanConvert
+ 2021-07-20 9e26569293 cmd/go: don't add C compiler ID to hash for standard library
+ 2021-07-20 d568e6e075 runtime/debug: skip TestPanicOnFault on netbsd/arm
+ 2021-07-19 c8f4e6152d spec: correct example comment in Conversions from slice to array
+ 2021-07-19 1d91551b73 time: correct typo in documentation for UnixMicro
+ 2021-07-19 404127c30f cmd/compile: fix off-by-one error in traceback argument counting
+ 2021-07-19 6298cfe672 cmd/compile: fix typo in fatal message of builtinCall
+ 2021-07-19 49402bee36 cmd/{compile,link}: fix bug in map.zero handling
+ 2021-07-18 a66190ecee test/bench/go1: fix size for RegexpMatchMedium_32
+ 2021-07-18 650fc2117a text/scanner: use Go convention in Position doc comment
+ 2021-07-16 aa4e0f528e net/http:  correct capitalization in cancelTimeBody comment
+ 2021-07-15 0941dbca6a testing: clarify in docs that TestMain is advanced
+ 2021-07-15 69728ead87 cmd/go: update error messages in tests to match CL 332573
+ 2021-07-15 c1cc9f9c3d cmd/compile: fix lookup package of redeclared dot import symbol
+ 2021-07-15 21a04e3335 doc/go1.17: mention GOARCH=loong64
+ 2021-07-14 2b00a54baf go/build, runtime/internal/sys: reserve GOARCH=loong64
+ 2021-07-14 60ddf42b46 cmd/go: change link in error message from /wiki to /doc.
+ 2021-07-13 d8f348a589 cmd/go: remove a duplicated word from 'go help mod graph'

Change-Id: I63a540ba823bcbde7249348999ac5a7d9908b531
2021-08-02 11:56:53 -04:00
Dmitri Shuralyov
c3b47cb598 [release-branch.go1.17] update codereview.cfg for release-branch.go1.17
The initial "branch: master" configuration was inherited from when
the release-branch.go1.17 branch was branched off the master branch.
Update the "branch" key, otherwise a modern git-codereview will mail
CLs to the wrong branch.

We can set "parent-branch" so that 'git codereview sync-branch' works
to merge latest master into release-branch.go1.17, something we want
to do for subsequent RCs, maybe up to the final release. (At some point
the release freeze will end and tree will open for Go 1.18 development,
so we'll be switching to using cherry-picks only. Having parent-branch
will not be useful then, but I think harmless.)

Change-Id: I36ab977eaeb52bc0a84cc59e807572054f54c789
Reviewed-on: https://go-review.googlesource.com/c/go/+/334376
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Trust: Dmitri Shuralyov <dmitshur@golang.org>
2021-07-13 22:45:26 +00:00
Cherry Mui
ddfd72f7d1 [release-branch.go1.17] go1.17rc1
Change-Id: Idc207e34c54b9bff0ae59348e4bc97474b1c11d2
Reviewed-on: https://go-review.googlesource.com/c/go/+/334254
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Cherry Mui <cherryyz@google.com>
2021-07-13 17:12:38 +00:00
Cherry Mui
d6f4d9a2be [release-branch.go1.17] all: merge master into release-branch.go1.17
a98589711d crypto/tls: test key type when casting
cfbd73ba33 doc/go1.17: editing pass over the "Compiler" section
ab4085ce84 runtime/pprof: call runtime.GC twice in memory profile test

Change-Id: I5b19d559629353886752e2a73ce8f37f983772df
2021-07-13 11:17:41 -04:00
195 changed files with 5408 additions and 2846 deletions

1
VERSION Normal file
View File

@@ -0,0 +1 @@
go1.17.10

View File

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

View File

@@ -753,9 +753,9 @@ func Foo() bool {
<p><!-- CL 311572 -->
The new
<a href="/pkg/database/sql/#NullInt16"><code>NullInt16</code></a>
and
<a href="/pkg/database/sql/#NullByte"><code>NullByte</code></a>
<a href="/pkg/database/sql/#NullInt16"><code>NullInt16</code></a>
and
<a href="/pkg/database/sql/#NullByte"><code>NullByte</code></a>
structs represent the int16 and byte values that may be null. These can be used as
destinations of the <a href="/pkg/database/sql/#Scan"><code>Scan</code></a> method,
similar to NullString.
@@ -1205,11 +1205,11 @@ func Foo() bool {
<p><!-- CL 300996 -->
The package now accepts comma "," as a separator for fractional seconds when parsing and formatting time.
The following time formats are now accepted:
For example, the following time layouts are now accepted:
<ul>
<li>2006-01-02 14:06:03,999999999 -0700 MST</li>
<li>Mon Jan _2 14:06:03,120007 2006</li>
<li>Mon Jan 2 14:06:03,120007 2006</li>
<li>2006-01-02 15:04:05,999999999 -0700 MST</li>
<li>Mon Jan _2 15:04:05,000000 2006</li>
<li>Monday, January 2 15:04:05,000 2006</li>
</ul>
</p>

View File

@@ -10,12 +10,14 @@ import (
"debug/elf"
"flag"
"fmt"
"io"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"syscall"
"testing"
@@ -263,6 +265,173 @@ func checkLineComments(t *testing.T, hdrname string) {
}
}
// checkArchive verifies that the created library looks OK.
// We just check a couple of things now, we can add more checks as needed.
func checkArchive(t *testing.T, arname string) {
t.Helper()
switch GOOS {
case "aix", "darwin", "ios", "windows":
// We don't have any checks for non-ELF libraries yet.
if _, err := os.Stat(arname); err != nil {
t.Errorf("archive %s does not exist: %v", arname, err)
}
default:
checkELFArchive(t, arname)
}
}
// checkELFArchive checks an ELF archive.
func checkELFArchive(t *testing.T, arname string) {
t.Helper()
f, err := os.Open(arname)
if err != nil {
t.Errorf("archive %s does not exist: %v", arname, err)
return
}
defer f.Close()
// TODO(iant): put these in a shared package? But where?
const (
magic = "!<arch>\n"
fmag = "`\n"
namelen = 16
datelen = 12
uidlen = 6
gidlen = 6
modelen = 8
sizelen = 10
fmaglen = 2
hdrlen = namelen + datelen + uidlen + gidlen + modelen + sizelen + fmaglen
)
type arhdr struct {
name string
date string
uid string
gid string
mode string
size string
fmag string
}
var magbuf [len(magic)]byte
if _, err := io.ReadFull(f, magbuf[:]); err != nil {
t.Errorf("%s: archive too short", arname)
return
}
if string(magbuf[:]) != magic {
t.Errorf("%s: incorrect archive magic string %q", arname, magbuf)
}
off := int64(len(magic))
for {
if off&1 != 0 {
var b [1]byte
if _, err := f.Read(b[:]); err != nil {
if err == io.EOF {
break
}
t.Errorf("%s: error skipping alignment byte at %d: %v", arname, off, err)
}
off++
}
var hdrbuf [hdrlen]byte
if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
if err == io.EOF {
break
}
t.Errorf("%s: error reading archive header at %d: %v", arname, off, err)
return
}
var hdr arhdr
hdrslice := hdrbuf[:]
set := func(len int, ps *string) {
*ps = string(bytes.TrimSpace(hdrslice[:len]))
hdrslice = hdrslice[len:]
}
set(namelen, &hdr.name)
set(datelen, &hdr.date)
set(uidlen, &hdr.uid)
set(gidlen, &hdr.gid)
set(modelen, &hdr.mode)
set(sizelen, &hdr.size)
hdr.fmag = string(hdrslice[:fmaglen])
hdrslice = hdrslice[fmaglen:]
if len(hdrslice) != 0 {
t.Fatalf("internal error: len(hdrslice) == %d", len(hdrslice))
}
if hdr.fmag != fmag {
t.Errorf("%s: invalid fmagic value %q at %d", arname, hdr.fmag, off)
return
}
size, err := strconv.ParseInt(hdr.size, 10, 64)
if err != nil {
t.Errorf("%s: error parsing size %q at %d: %v", arname, hdr.size, off, err)
return
}
off += hdrlen
switch hdr.name {
case "__.SYMDEF", "/", "/SYM64/":
// The archive symbol map.
case "//", "ARFILENAMES/":
// The extended name table.
default:
// This should be an ELF object.
checkELFArchiveObject(t, arname, off, io.NewSectionReader(f, off, size))
}
off += size
if _, err := f.Seek(off, os.SEEK_SET); err != nil {
t.Errorf("%s: failed to seek to %d: %v", arname, off, err)
}
}
}
// checkELFArchiveObject checks an object in an ELF archive.
func checkELFArchiveObject(t *testing.T, arname string, off int64, obj io.ReaderAt) {
t.Helper()
ef, err := elf.NewFile(obj)
if err != nil {
t.Errorf("%s: failed to open ELF file at %d: %v", arname, off, err)
return
}
defer ef.Close()
// Verify section types.
for _, sec := range ef.Sections {
want := elf.SHT_NULL
switch sec.Name {
case ".text", ".data":
want = elf.SHT_PROGBITS
case ".bss":
want = elf.SHT_NOBITS
case ".symtab":
want = elf.SHT_SYMTAB
case ".strtab":
want = elf.SHT_STRTAB
case ".init_array":
want = elf.SHT_INIT_ARRAY
case ".fini_array":
want = elf.SHT_FINI_ARRAY
case ".preinit_array":
want = elf.SHT_PREINIT_ARRAY
}
if want != elf.SHT_NULL && sec.Type != want {
t.Errorf("%s: incorrect section type in elf file at %d for section %q: got %v want %v", arname, off, sec.Name, sec.Type, want)
}
}
}
func TestInstall(t *testing.T) {
if !testWork {
defer os.RemoveAll(filepath.Join(GOPATH, "pkg"))
@@ -321,6 +490,7 @@ func TestEarlySignalHandler(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
checkArchive(t, "libgo2.a")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
if runtime.Compiler == "gccgo" {
@@ -361,6 +531,7 @@ func TestSignalForwarding(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
checkArchive(t, "libgo2.a")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if runtime.Compiler == "gccgo" {
@@ -411,6 +582,7 @@ func TestSignalForwardingExternal(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
checkArchive(t, "libgo2.a")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if runtime.Compiler == "gccgo" {
@@ -528,6 +700,7 @@ func TestOsSignal(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo3.h")
checkArchive(t, "libgo3.a")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
if runtime.Compiler == "gccgo" {
@@ -565,6 +738,7 @@ func TestSigaltstack(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo4.h")
checkArchive(t, "libgo4.a")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
if runtime.Compiler == "gccgo" {
@@ -752,6 +926,7 @@ func TestSIGPROF(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo6.h")
checkArchive(t, "libgo6.a")
ccArgs := append(cc, "-o", "testp6"+exeSuffix, "main6.c", "libgo6.a")
if runtime.Compiler == "gccgo" {
@@ -795,6 +970,7 @@ func TestCompileWithoutShared(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo2.h")
checkArchive(t, "libgo2.a")
exe := "./testnoshared" + exeSuffix
@@ -899,6 +1075,7 @@ func TestManyCalls(t *testing.T) {
t.Fatal(err)
}
checkLineComments(t, "libgo7.h")
checkArchive(t, "libgo7.a")
ccArgs := append(cc, "-o", "testp7"+exeSuffix, "main7.c", "libgo7.a")
if runtime.Compiler == "gccgo" {

View File

@@ -265,7 +265,7 @@ func TestIssue25756(t *testing.T) {
// Test with main using -buildmode=pie with plugin for issue #43228
func TestIssue25756pie(t *testing.T) {
if os.Getenv("GO_BUILDER_NAME") == "darwin-arm64-11_0-toothrot" {
if os.Getenv("GO_BUILDER_NAME") == "darwin-arm64-11_0-toothrot" || os.Getenv("GO_BUILDER_NAME") == "darwin-arm64-12_0-toothrot" {
t.Skip("broken on darwin/arm64 builder in sharded mode; see issue 46239")
}
@@ -287,9 +287,43 @@ func TestMethod2(t *testing.T) {
run(t, "./method2.exe")
}
func TestMethod3(t *testing.T) {
goCmd(t, "build", "-buildmode=plugin", "-o", "method3.so", "./method3/plugin.go")
goCmd(t, "build", "-o", "method3.exe", "./method3/main.go")
run(t, "./method3.exe")
}
func TestIssue44956(t *testing.T) {
goCmd(t, "build", "-buildmode=plugin", "-o", "issue44956p1.so", "./issue44956/plugin1.go")
goCmd(t, "build", "-buildmode=plugin", "-o", "issue44956p2.so", "./issue44956/plugin2.go")
goCmd(t, "build", "-o", "issue44956.exe", "./issue44956/main.go")
run(t, "./issue44956.exe")
}
func TestForkExec(t *testing.T) {
// Issue 38824: importing the plugin package causes it hang in forkExec on darwin.
t.Parallel()
goCmd(t, "build", "-o", "forkexec.exe", "./forkexec/main.go")
var cmd *exec.Cmd
done := make(chan int, 1)
go func() {
for i := 0; i < 100; i++ {
cmd = exec.Command("./forkexec.exe", "1")
err := cmd.Run()
if err != nil {
t.Errorf("running command failed: %v", err)
break
}
}
done <- 1
}()
select {
case <-done:
case <-time.After(5 * time.Minute):
cmd.Process.Kill()
t.Fatalf("subprocess hang")
}
}

View File

@@ -0,0 +1,30 @@
// Copyright 2021 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 (
"os"
"os/exec"
_ "plugin"
"sync"
)
func main() {
if os.Args[1] != "1" {
return
}
var wg sync.WaitGroup
for i := 0; i < 8; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// does not matter what we exec, just exec itself
cmd := exec.Command("./forkexec.exe", "0")
cmd.Run()
}()
}
wg.Wait()
}

View File

@@ -0,0 +1,32 @@
// Copyright 2022 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.
// An unexported method can be reachable from the plugin via interface
// when a package is shared. So it need to be live.
package main
import (
"plugin"
"testplugin/method3/p"
)
var i p.I
func main() {
pl, err := plugin.Open("method3.so")
if err != nil {
panic(err)
}
f, err := pl.Lookup("F")
if err != nil {
panic(err)
}
f.(func())()
i = p.T(123)
}

View File

@@ -0,0 +1,17 @@
// Copyright 2022 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 T int
func (T) m() { println("m") }
type I interface { m() }
func F() {
i.m()
}
var i I = T(123)

View File

@@ -0,0 +1,11 @@
// Copyright 2022 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 "testplugin/method3/p"
func main() {}
func F() { p.F() }

View File

@@ -1070,3 +1070,11 @@ func TestIssue44031(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue44031/b")
goCmd(t, "run", "-linkshared", "./issue44031/main")
}
// Test that we use a variable from shared libraries (which implement an
// interface in shared libraries.). A weak reference is used in the itab
// in main process. It can cause unreacheble panic. See issue 47873.
func TestIssue47873(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue47837/a")
goCmd(t, "run", "-linkshared", "./issue47837/main")
}

View File

@@ -0,0 +1,19 @@
// Copyright 2021 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 a
type A interface {
M()
}
//go:noinline
func TheFuncWithArgA(a A) {
a.M()
}
type ImplA struct{}
//go:noinline
func (A *ImplA) M() {}

View File

@@ -0,0 +1,14 @@
// Copyright 2021 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 (
"testshared/issue47837/a"
)
func main() {
var vara a.ImplA
a.TheFuncWithArgA(&vara)
}

View File

@@ -567,6 +567,13 @@
offset += 8;
});
// The linker guarantees global data starts from at least wasmMinDataAddr.
// Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
const wasmMinDataAddr = 4096 + 8192;
if (offset >= wasmMinDataAddr) {
throw new Error("total length of command line and environment variables exceeds limit");
}
this._inst.exports.run(argc, argv);
if (this.exited) {
this._resolveExitPromise();

View File

@@ -102,7 +102,7 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
// indicate it contains up to 1 << 128 - 1 files. Since each file has a
// header which will be _at least_ 30 bytes we can safely preallocate
// if (data size / 30) >= end.directoryRecords.
if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
z.File = make([]*File, 0, end.directoryRecords)
}
z.Comment = end.comment
@@ -741,6 +741,9 @@ func (r *Reader) initFileList() {
for _, file := range r.File {
isDir := len(file.Name) > 0 && file.Name[len(file.Name)-1] == '/'
name := toValidName(file.Name)
if name == "" {
continue
}
for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
dirs[dir] = true
}
@@ -782,8 +785,11 @@ func fileEntryLess(x, y string) bool {
func (r *Reader) Open(name string) (fs.File, error) {
r.initFileList()
if !fs.ValidPath(name) {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
}
e := r.openLookup(name)
if e == nil || !fs.ValidPath(name) {
if e == nil {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
}
if e.isDir {
@@ -797,7 +803,7 @@ func (r *Reader) Open(name string) (fs.File, error) {
}
func split(name string) (dir, elem string, isDir bool) {
if name[len(name)-1] == '/' {
if len(name) > 0 && name[len(name)-1] == '/' {
isDir = true
name = name[:len(name)-1]
}

View File

@@ -13,6 +13,7 @@ import (
"io/fs"
"os"
"path/filepath"
"reflect"
"regexp"
"strings"
"testing"
@@ -1202,6 +1203,15 @@ func TestCVE202127919(t *testing.T) {
if err != nil {
t.Errorf("Error reading file: %v", err)
}
if len(r.File) != 1 {
t.Fatalf("No entries in the file list")
}
if r.File[0].Name != "../test.txt" {
t.Errorf("Unexpected entry name: %s", r.File[0].Name)
}
if _, err := r.File[0].Open(); err != nil {
t.Errorf("Error opening file: %v", err)
}
}
func TestReadDataDescriptor(t *testing.T) {
@@ -1384,3 +1394,139 @@ func TestCVE202133196(t *testing.T) {
t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
}
}
func TestCVE202139293(t *testing.T) {
// directory size is so large, that the check in Reader.init
// overflows when subtracting from the archive size, causing
// the pre-allocation check to be bypassed.
data := []byte{
0x50, 0x4b, 0x06, 0x06, 0x05, 0x06, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
0xff, 0x50, 0xfe, 0x00, 0xff, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xff,
}
_, err := NewReader(bytes.NewReader(data), int64(len(data)))
if err != ErrFormat {
t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
}
}
func TestCVE202141772(t *testing.T) {
// Archive contains a file whose name is exclusively made up of '/', '\'
// characters, or "../", "..\" paths, which would previously cause a panic.
//
// Length Method Size Cmpr Date Time CRC-32 Name
// -------- ------ ------- ---- ---------- ----- -------- ----
// 0 Stored 0 0% 08-05-2021 18:32 00000000 /
// 0 Stored 0 0% 09-14-2021 12:59 00000000 //
// 0 Stored 0 0% 09-14-2021 12:59 00000000 \
// 11 Stored 11 0% 09-14-2021 13:04 0d4a1185 /test.txt
// -------- ------- --- -------
// 11 11 0% 4 files
data := []byte{
0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x08,
0x00, 0x00, 0x06, 0x94, 0x05, 0x53, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x50,
0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0x67, 0x2e, 0x53, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x50,
0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x78, 0x67, 0x2e, 0x53, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x50, 0x4b,
0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
0x91, 0x68, 0x2e, 0x53, 0x85, 0x11, 0x4a, 0x0d,
0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x2f, 0x74, 0x65, 0x73,
0x74, 0x2e, 0x74, 0x78, 0x74, 0x68, 0x65, 0x6c,
0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,
0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x0a, 0x00,
0x00, 0x08, 0x00, 0x00, 0x06, 0x94, 0x05, 0x53,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0xed, 0x41, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x50,
0x4b, 0x01, 0x02, 0x3f, 0x00, 0x0a, 0x00, 0x00,
0x00, 0x00, 0x00, 0x78, 0x67, 0x2e, 0x53, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x1f, 0x00, 0x00, 0x00, 0x2f, 0x2f, 0x0a,
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x18, 0x00, 0x93, 0x98, 0x25, 0x57, 0x25,
0xa9, 0xd7, 0x01, 0x93, 0x98, 0x25, 0x57, 0x25,
0xa9, 0xd7, 0x01, 0x93, 0x98, 0x25, 0x57, 0x25,
0xa9, 0xd7, 0x01, 0x50, 0x4b, 0x01, 0x02, 0x3f,
0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
0x67, 0x2e, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x20, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00,
0x00, 0x5c, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x93, 0x98,
0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x93, 0x98,
0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x93, 0x98,
0x25, 0x57, 0x25, 0xa9, 0xd7, 0x01, 0x50, 0x4b,
0x01, 0x02, 0x3f, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x00, 0x00, 0x91, 0x68, 0x2e, 0x53, 0x85, 0x11,
0x4a, 0x0d, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00,
0x00, 0x00, 0x09, 0x00, 0x24, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x5e, 0x00, 0x00, 0x00, 0x2f, 0x74, 0x65, 0x73,
0x74, 0x2e, 0x74, 0x78, 0x74, 0x0a, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18,
0x00, 0xa9, 0x80, 0x51, 0x01, 0x26, 0xa9, 0xd7,
0x01, 0x31, 0xd1, 0x57, 0x01, 0x26, 0xa9, 0xd7,
0x01, 0xdf, 0x48, 0x85, 0xf9, 0x25, 0xa9, 0xd7,
0x01, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00,
0x00, 0x04, 0x00, 0x04, 0x00, 0x31, 0x01, 0x00,
0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
}
r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
if err != nil {
t.Fatalf("Error reading the archive: %v", err)
}
entryNames := []string{`/`, `//`, `\`, `/test.txt`}
var names []string
for _, f := range r.File {
names = append(names, f.Name)
if _, err := f.Open(); err != nil {
t.Errorf("Error opening %q: %v", f.Name, err)
}
if _, err := r.Open(f.Name); err == nil {
t.Errorf("Opening %q with fs.FS API succeeded", f.Name)
}
}
if !reflect.DeepEqual(names, entryNames) {
t.Errorf("Unexpected file entries: %q", names)
}
if _, err := r.Open(""); err == nil {
t.Errorf("Opening %q with fs.FS API succeeded", "")
}
if _, err := r.Open("test.txt"); err != nil {
t.Errorf("Error opening %q with fs.FS API: %v", "test.txt", err)
}
dirEntries, err := fs.ReadDir(r, ".")
if err != nil {
t.Fatalf("Error reading the root directory: %v", err)
}
if len(dirEntries) != 1 || dirEntries[0].Name() != "test.txt" {
t.Errorf("Unexpected directory entries")
for _, dirEntry := range dirEntries {
_, err := r.Open(dirEntry.Name())
t.Logf("%q (Open error: %v)", dirEntry.Name(), err)
}
t.FailNow()
}
info, err := dirEntries[0].Info()
if err != nil {
t.Fatalf("Error reading info entry: %v", err)
}
if name := info.Name(); name != "test.txt" {
t.Errorf("Inconsistent name in info entry: %v", name)
}
}

View File

@@ -320,7 +320,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
for a.Op == ssa.OpCopy || a.Op == ssa.OpMIPS64MOVVreg {
a = a.Args[0]
}
if a.Op == ssa.OpLoadReg {
if a.Op == ssa.OpLoadReg && mips.REG_R0 <= a.Reg() && a.Reg() <= mips.REG_R31 {
// LoadReg from a narrower type does an extension, except loading
// to a floating point register. So only eliminate the extension
// if it is loaded to an integer register.
t := a.Type
switch {
case v.Op == ssa.OpMIPS64MOVBreg && t.Size() == 1 && t.IsSigned(),

View File

@@ -495,10 +495,11 @@ func transformSelect(sel *ir.SelectStmt) {
if ncase.Comm != nil {
n := ncase.Comm
oselrecv2 := func(dst, recv ir.Node, def bool) {
n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
n.Def = def
n.SetTypecheck(1)
ncase.Comm = n
selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
selrecv.Def = def
selrecv.SetTypecheck(1)
selrecv.SetInit(n.Init())
ncase.Comm = selrecv
}
switch n.Op() {
case ir.OAS:

View File

@@ -952,6 +952,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
eltRO := x.regWidth(elt)
source.Type = t
for i := int64(0); i < t.NumElem(); i++ {
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Width, loadRegOffset, storeRc.at(t, 0))
@@ -985,6 +986,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
source.Type = t
for i := 0; i < t.NumFields(); i++ {
fld := t.Field(i)
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)

View File

@@ -78,7 +78,11 @@ func fuseBranchRedirect(f *Func) bool {
if v.Op != OpPhi {
continue
}
v.RemoveArg(k)
n := len(v.Args)
v.Args[k].Uses--
v.Args[k] = v.Args[n-1]
v.Args[n-1] = nil
v.Args = v.Args[:n-1]
phielimValue(v)
}
// Fix up child to have one more predecessor.

View File

@@ -497,9 +497,9 @@
(XOR x (MOVWconst [c])) => (XORconst [c] x)
(BIC x (MOVWconst [c])) => (BICconst [c] x)
(SLL x (MOVWconst [c])) => (SLLconst x [c&31]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=32)
(SRL x (MOVWconst [c])) => (SRLconst x [c&31])
(SRA x (MOVWconst [c])) => (SRAconst x [c&31])
(SLL x (MOVWconst [c])) && 0 <= c && c < 32 => (SLLconst x [c])
(SRL x (MOVWconst [c])) && 0 <= c && c < 32 => (SRLconst x [c])
(SRA x (MOVWconst [c])) && 0 <= c && c < 32 => (SRAconst x [c])
(CMP x (MOVWconst [c])) => (CMPconst [c] x)
(CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x))
@@ -1072,60 +1072,60 @@
(CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))])
(CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
(ADDshiftLLreg x y (MOVWconst [c])) => (ADDshiftLL x y [c])
(ADDshiftRLreg x y (MOVWconst [c])) => (ADDshiftRL x y [c])
(ADDshiftRAreg x y (MOVWconst [c])) => (ADDshiftRA x y [c])
(ADCshiftLLreg x y (MOVWconst [c]) flags) => (ADCshiftLL x y [c] flags)
(ADCshiftRLreg x y (MOVWconst [c]) flags) => (ADCshiftRL x y [c] flags)
(ADCshiftRAreg x y (MOVWconst [c]) flags) => (ADCshiftRA x y [c] flags)
(ADDSshiftLLreg x y (MOVWconst [c])) => (ADDSshiftLL x y [c])
(ADDSshiftRLreg x y (MOVWconst [c])) => (ADDSshiftRL x y [c])
(ADDSshiftRAreg x y (MOVWconst [c])) => (ADDSshiftRA x y [c])
(SUBshiftLLreg x y (MOVWconst [c])) => (SUBshiftLL x y [c])
(SUBshiftRLreg x y (MOVWconst [c])) => (SUBshiftRL x y [c])
(SUBshiftRAreg x y (MOVWconst [c])) => (SUBshiftRA x y [c])
(SBCshiftLLreg x y (MOVWconst [c]) flags) => (SBCshiftLL x y [c] flags)
(SBCshiftRLreg x y (MOVWconst [c]) flags) => (SBCshiftRL x y [c] flags)
(SBCshiftRAreg x y (MOVWconst [c]) flags) => (SBCshiftRA x y [c] flags)
(SUBSshiftLLreg x y (MOVWconst [c])) => (SUBSshiftLL x y [c])
(SUBSshiftRLreg x y (MOVWconst [c])) => (SUBSshiftRL x y [c])
(SUBSshiftRAreg x y (MOVWconst [c])) => (SUBSshiftRA x y [c])
(RSBshiftLLreg x y (MOVWconst [c])) => (RSBshiftLL x y [c])
(RSBshiftRLreg x y (MOVWconst [c])) => (RSBshiftRL x y [c])
(RSBshiftRAreg x y (MOVWconst [c])) => (RSBshiftRA x y [c])
(RSCshiftLLreg x y (MOVWconst [c]) flags) => (RSCshiftLL x y [c] flags)
(RSCshiftRLreg x y (MOVWconst [c]) flags) => (RSCshiftRL x y [c] flags)
(RSCshiftRAreg x y (MOVWconst [c]) flags) => (RSCshiftRA x y [c] flags)
(RSBSshiftLLreg x y (MOVWconst [c])) => (RSBSshiftLL x y [c])
(RSBSshiftRLreg x y (MOVWconst [c])) => (RSBSshiftRL x y [c])
(RSBSshiftRAreg x y (MOVWconst [c])) => (RSBSshiftRA x y [c])
(ANDshiftLLreg x y (MOVWconst [c])) => (ANDshiftLL x y [c])
(ANDshiftRLreg x y (MOVWconst [c])) => (ANDshiftRL x y [c])
(ANDshiftRAreg x y (MOVWconst [c])) => (ANDshiftRA x y [c])
(ORshiftLLreg x y (MOVWconst [c])) => (ORshiftLL x y [c])
(ORshiftRLreg x y (MOVWconst [c])) => (ORshiftRL x y [c])
(ORshiftRAreg x y (MOVWconst [c])) => (ORshiftRA x y [c])
(XORshiftLLreg x y (MOVWconst [c])) => (XORshiftLL x y [c])
(XORshiftRLreg x y (MOVWconst [c])) => (XORshiftRL x y [c])
(XORshiftRAreg x y (MOVWconst [c])) => (XORshiftRA x y [c])
(BICshiftLLreg x y (MOVWconst [c])) => (BICshiftLL x y [c])
(BICshiftRLreg x y (MOVWconst [c])) => (BICshiftRL x y [c])
(BICshiftRAreg x y (MOVWconst [c])) => (BICshiftRA x y [c])
(MVNshiftLLreg x (MOVWconst [c])) => (MVNshiftLL x [c])
(MVNshiftRLreg x (MOVWconst [c])) => (MVNshiftRL x [c])
(MVNshiftRAreg x (MOVWconst [c])) => (MVNshiftRA x [c])
(CMPshiftLLreg x y (MOVWconst [c])) => (CMPshiftLL x y [c])
(CMPshiftRLreg x y (MOVWconst [c])) => (CMPshiftRL x y [c])
(CMPshiftRAreg x y (MOVWconst [c])) => (CMPshiftRA x y [c])
(TSTshiftLLreg x y (MOVWconst [c])) => (TSTshiftLL x y [c])
(TSTshiftRLreg x y (MOVWconst [c])) => (TSTshiftRL x y [c])
(TSTshiftRAreg x y (MOVWconst [c])) => (TSTshiftRA x y [c])
(TEQshiftLLreg x y (MOVWconst [c])) => (TEQshiftLL x y [c])
(TEQshiftRLreg x y (MOVWconst [c])) => (TEQshiftRL x y [c])
(TEQshiftRAreg x y (MOVWconst [c])) => (TEQshiftRA x y [c])
(CMNshiftLLreg x y (MOVWconst [c])) => (CMNshiftLL x y [c])
(CMNshiftRLreg x y (MOVWconst [c])) => (CMNshiftRL x y [c])
(CMNshiftRAreg x y (MOVWconst [c])) => (CMNshiftRA x y [c])
(ADDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftLL x y [c])
(ADDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRL x y [c])
(ADDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRA x y [c])
(ADCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftLL x y [c] flags)
(ADCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRL x y [c] flags)
(ADCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRA x y [c] flags)
(ADDSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftLL x y [c])
(ADDSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRL x y [c])
(ADDSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRA x y [c])
(SUBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftLL x y [c])
(SUBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRL x y [c])
(SUBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRA x y [c])
(SBCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftLL x y [c] flags)
(SBCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRL x y [c] flags)
(SBCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRA x y [c] flags)
(SUBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftLL x y [c])
(SUBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRL x y [c])
(SUBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRA x y [c])
(RSBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftLL x y [c])
(RSBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRL x y [c])
(RSBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRA x y [c])
(RSCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftLL x y [c] flags)
(RSCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRL x y [c] flags)
(RSCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRA x y [c] flags)
(RSBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftLL x y [c])
(RSBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRL x y [c])
(RSBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRA x y [c])
(ANDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftLL x y [c])
(ANDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRL x y [c])
(ANDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRA x y [c])
(ORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftLL x y [c])
(ORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRL x y [c])
(ORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRA x y [c])
(XORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftLL x y [c])
(XORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRL x y [c])
(XORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRA x y [c])
(BICshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftLL x y [c])
(BICshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRL x y [c])
(BICshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRA x y [c])
(MVNshiftLLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftLL x [c])
(MVNshiftRLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRL x [c])
(MVNshiftRAreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRA x [c])
(CMPshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftLL x y [c])
(CMPshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRL x y [c])
(CMPshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRA x y [c])
(TSTshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftLL x y [c])
(TSTshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRL x y [c])
(TSTshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRA x y [c])
(TEQshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftLL x y [c])
(TEQshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRL x y [c])
(TEQshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRA x y [c])
(CMNshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftLL x y [c])
(CMNshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRL x y [c])
(CMNshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRA x y [c])
// Generate rotates
(ADDshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x)
@@ -1237,24 +1237,24 @@
(AND x (MVN y)) => (BIC x y)
// simplification with *shift ops
(SUBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(SUBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(SUBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(RSBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(RSBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(RSBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(XORshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(XORshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(XORshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(BICshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVWconst [0])
(BICshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVWconst [0])
(BICshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVWconst [0])
(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(RSBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(RSBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(RSBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
(ORshiftLL y:(SLLconst x [c]) x [c]) => y
(ORshiftRL y:(SRLconst x [c]) x [c]) => y
(ORshiftRA y:(SRAconst x [c]) x [c]) => y
(XORshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(XORshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(XORshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(BICshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
(BICshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
(BICshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
(AND x (MVNshiftLL y [c])) => (BICshiftLL x y [c])
(AND x (MVNshiftRL y [c])) => (BICshiftRL x y [c])
(AND x (MVNshiftRA y [c])) => (BICshiftRA x y [c])
@@ -1268,8 +1268,8 @@
(SRLconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x)
// comparison simplification
((LT|LE|EQ|NE|GE|GT) (CMP x (RSBconst [0] y))) => ((LT|LE|EQ|NE|GE|GT) (CMN x y)) // sense of carry bit not preserved
((LT|LE|EQ|NE|GE|GT) (CMN x (RSBconst [0] y))) => ((LT|LE|EQ|NE|GE|GT) (CMP x y)) // sense of carry bit not preserved
((EQ|NE) (CMP x (RSBconst [0] y))) => ((EQ|NE) (CMN x y)) // sense of carry bit not preserved; see also #50854
((EQ|NE) (CMN x (RSBconst [0] y))) => ((EQ|NE) (CMP x y)) // sense of carry bit not preserved; see also #50864
(EQ (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (EQ (CMP x y) yes no)
(EQ (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (EQ (CMP a (MUL <x.Type> x y)) yes no)
(EQ (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (EQ (CMPconst [c] x) yes no)

View File

@@ -645,19 +645,13 @@
(GT (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GTnoov (CMNW x y) yes no)
(GE (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GEnoov (CMNW x y) yes no)
// CMP(x,-y) -> CMN(x,y) is only valid for unordered comparison, if y can be -1<<63
(EQ (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (EQ (CMN x y) yes no)
(NE (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (NE (CMN x y) yes no)
(LT (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (LT (CMN x y) yes no)
(LE (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (LE (CMN x y) yes no)
(GT (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (GT (CMN x y) yes no)
(GE (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (GE (CMN x y) yes no)
// CMPW(x,-y) -> CMNW(x,y) is only valid for unordered comparison, if y can be -1<<31
(EQ (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (EQ (CMNW x y) yes no)
(NE (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (NE (CMNW x y) yes no)
(LT (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (LT (CMNW x y) yes no)
(LE (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (LE (CMNW x y) yes no)
(GT (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (GT (CMNW x y) yes no)
(GE (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (GE (CMNW x y) yes no)
(EQ (CMPconst [0] x) yes no) => (Z x yes no)
(NE (CMPconst [0] x) yes no) => (NZ x yes no)
@@ -1698,27 +1692,27 @@
(TSTshiftRA x (MOVDconst [c]) [d]) => (TSTconst x [c>>uint64(d)])
// simplification with *shift ops
(SUBshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
(SUBshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
(SUBshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
(ANDshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ANDshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ANDshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(ORshiftLL x y:(SLLconst x [c]) [d]) && c==d => y
(ORshiftRL x y:(SRLconst x [c]) [d]) && c==d => y
(ORshiftRA x y:(SRAconst x [c]) [d]) && c==d => y
(XORshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
(XORshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
(XORshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
(BICshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [0])
(BICshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [0])
(BICshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [0])
(EONshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(EONshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(EONshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [-1])
(ORNshiftLL x (SLLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(ORNshiftRL x (SRLconst x [c]) [d]) && c==d => (MOVDconst [-1])
(ORNshiftRA x (SRAconst x [c]) [d]) && c==d => (MOVDconst [-1])
(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
(ORshiftLL y:(SLLconst x [c]) x [c]) => y
(ORshiftRL y:(SRLconst x [c]) x [c]) => y
(ORshiftRA y:(SRAconst x [c]) x [c]) => y
(XORshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
(XORshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
(XORshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
(BICshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
(BICshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
(BICshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
(EONshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
(EONshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
(EONshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
(ORNshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
(ORNshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
(ORNshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
// Generate rotates with const shift
(ADDshiftLL [c] (SRLconst x [64-c]) x) => (RORconst [64-c] x)

View File

@@ -284,9 +284,9 @@ func init() {
{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to auxInt
{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1, 32 bit
{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt, 32 bit
{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1
{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1, provided arg1 is not 1<<63
{name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // arg0 compare to -auxInt
{name: "CMNW", argLength: 2, reg: gp2flags, asm: "CMNW", typ: "Flags", commutative: true}, // arg0 compare to -arg1, 32 bit
{name: "CMNW", argLength: 2, reg: gp2flags, asm: "CMNW", typ: "Flags", commutative: true}, // arg0 compare to -arg1, 32 bit, provided arg1 is not 1<<31
{name: "CMNWconst", argLength: 1, reg: gp1flags, asm: "CMNW", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt, 32 bit
{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0
{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int64", typ: "Flags"}, // arg0 & auxInt compare to 0

View File

@@ -228,14 +228,15 @@ func init() {
// shifts
{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"}, // arg0 << arg1, shift amount is mod 256
{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt
{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, 0 <= auxInt < 32
{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"}, // arg0 >> arg1, unsigned, shift amount is mod 256
{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned
{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned, 0 <= auxInt < 32
{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"}, // arg0 >> arg1, signed, shift amount is mod 256
{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed
{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, 0 <= auxInt < 32
{name: "SRR", argLength: 2, reg: gp21}, // arg0 right rotate by arg1 bits
{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"}, // arg0 right rotate by auxInt bits
{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"}, // arg0 right rotate by auxInt bits, 0 <= auxInt < 32
// auxInt for all of these satisfy 0 <= auxInt < 32
{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt
{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift
{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift
@@ -330,7 +331,7 @@ func init() {
// comparisons
{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1
{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt
{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1
{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1, provided arg1 is not 1<<63
{name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt
{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0
{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0

View File

@@ -250,7 +250,7 @@
(Leq64F ...) => (FLED ...)
(Leq32F ...) => (FLES ...)
(EqPtr x y) => (SEQZ (SUB <x.Type> x y))
(EqPtr x y) => (SEQZ (SUB <typ.Uintptr> x y))
(Eq64 x y) => (SEQZ (SUB <x.Type> x y))
(Eq32 x y) => (SEQZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
(Eq16 x y) => (SEQZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))
@@ -258,7 +258,7 @@
(Eq64F ...) => (FEQD ...)
(Eq32F ...) => (FEQS ...)
(NeqPtr x y) => (SNEZ (SUB <x.Type> x y))
(NeqPtr x y) => (SNEZ (SUB <typ.Uintptr> x y))
(Neq64 x y) => (SNEZ (SUB <x.Type> x y))
(Neq32 x y) => (SNEZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
(Neq16 x y) => (SNEZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))

View File

@@ -106,7 +106,7 @@ var genericOps = []opData{
// For shifts, AxB means the shifted value has A bits and the shift amount has B bits.
// Shift amounts are considered unsigned.
// If arg1 is known to be less than the number of bits in arg0,
// If arg1 is known to be nonnegative and less than the number of bits in arg0,
// then auxInt may be set to 1.
// This enables better code generation on some platforms.
{name: "Lsh8x8", argLength: 2, aux: "Bool"}, // arg0 << arg1

File diff suppressed because it is too large Load Diff

View File

@@ -2265,18 +2265,16 @@ func rewriteValueARM64_OpARM64ANDshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ANDshiftLL x y:(SLLconst x [c]) [d])
// cond: c==d
// match: (ANDshiftLL y:(SLLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SLLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -2319,18 +2317,16 @@ func rewriteValueARM64_OpARM64ANDshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ANDshiftRA x y:(SRAconst x [c]) [d])
// cond: c==d
// match: (ANDshiftRA y:(SRAconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRAconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -2373,18 +2369,16 @@ func rewriteValueARM64_OpARM64ANDshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ANDshiftRL x y:(SRLconst x [c]) [d])
// cond: c==d
// match: (ANDshiftRL y:(SRLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -2495,17 +2489,15 @@ func rewriteValueARM64_OpARM64BICshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (BICshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (BICshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -2531,17 +2523,15 @@ func rewriteValueARM64_OpARM64BICshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (BICshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (BICshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -2567,17 +2557,15 @@ func rewriteValueARM64_OpARM64BICshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (BICshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (BICshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -3945,17 +3933,15 @@ func rewriteValueARM64_OpARM64EONshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (EONshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (EONshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -3981,17 +3967,15 @@ func rewriteValueARM64_OpARM64EONshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (EONshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (EONshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -4017,17 +4001,15 @@ func rewriteValueARM64_OpARM64EONshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (EONshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (EONshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -17819,17 +17801,15 @@ func rewriteValueARM64_OpARM64ORNshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORNshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (ORNshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -17855,17 +17835,15 @@ func rewriteValueARM64_OpARM64ORNshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORNshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (ORNshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -17891,17 +17869,15 @@ func rewriteValueARM64_OpARM64ORNshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORNshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (ORNshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [-1])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -18014,18 +17990,16 @@ func rewriteValueARM64_OpARM64ORshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORshiftLL x y:(SLLconst x [c]) [d])
// cond: c==d
// match: (ORshiftLL y:(SLLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SLLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -19694,18 +19668,16 @@ func rewriteValueARM64_OpARM64ORshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORshiftRA x y:(SRAconst x [c]) [d])
// cond: c==d
// match: (ORshiftRA y:(SRAconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRAconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -19748,18 +19720,16 @@ func rewriteValueARM64_OpARM64ORshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ORshiftRL x y:(SRLconst x [c]) [d])
// cond: c==d
// match: (ORshiftRL y:(SRLconst x [c]) x [c])
// result: y
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
y := v_1
if y.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
y := v_0
if y.Op != OpARM64SRLconst || auxIntToInt64(y.AuxInt) != c {
break
}
c := auxIntToInt64(y.AuxInt)
if x != y.Args[0] || !(c == d) {
x := y.Args[0]
if x != v_1 {
break
}
v.copyOf(y)
@@ -20836,17 +20806,15 @@ func rewriteValueARM64_OpARM64SUBshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (SUBshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (SUBshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -20872,17 +20840,15 @@ func rewriteValueARM64_OpARM64SUBshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (SUBshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (SUBshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -20908,17 +20874,15 @@ func rewriteValueARM64_OpARM64SUBshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (SUBshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (SUBshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -22007,17 +21971,15 @@ func rewriteValueARM64_OpARM64XORshiftLL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (XORshiftLL x (SLLconst x [c]) [d])
// cond: c==d
// match: (XORshiftLL (SLLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SLLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -22219,17 +22181,15 @@ func rewriteValueARM64_OpARM64XORshiftRA(v *Value) bool {
v.AddArg(x)
return true
}
// match: (XORshiftRA x (SRAconst x [c]) [d])
// cond: c==d
// match: (XORshiftRA (SRAconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRAconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRAconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -22273,17 +22233,15 @@ func rewriteValueARM64_OpARM64XORshiftRL(v *Value) bool {
v.AddArg(x)
return true
}
// match: (XORshiftRL x (SRLconst x [c]) [d])
// cond: c==d
// match: (XORshiftRL (SRLconst x [c]) x [c])
// result: (MOVDconst [0])
for {
d := auxIntToInt64(v.AuxInt)
x := v_0
if v_1.Op != OpARM64SRLconst {
c := auxIntToInt64(v.AuxInt)
if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != c {
break
}
c := auxIntToInt64(v_1.AuxInt)
if x != v_1.Args[0] || !(c == d) {
x := v_0.Args[0]
if x != v_1 {
break
}
v.reset(OpARM64MOVDconst)
@@ -27247,46 +27205,6 @@ func rewriteBlockARM64(b *Block) bool {
}
break
}
// match: (GE (CMP x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (GE (CMN x y) yes no)
for b.Controls[0].Op == OpARM64CMP {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64GE, v0)
return true
}
// match: (GE (CMPW x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (GE (CMNW x y) yes no)
for b.Controls[0].Op == OpARM64CMPW {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64GE, v0)
return true
}
// match: (GE (CMPconst [0] z:(MADD a x y)) yes no)
// cond: z.Uses==1
// result: (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
@@ -27683,46 +27601,6 @@ func rewriteBlockARM64(b *Block) bool {
}
break
}
// match: (GT (CMP x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (GT (CMN x y) yes no)
for b.Controls[0].Op == OpARM64CMP {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64GT, v0)
return true
}
// match: (GT (CMPW x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (GT (CMNW x y) yes no)
for b.Controls[0].Op == OpARM64CMPW {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64GT, v0)
return true
}
// match: (GT (CMPconst [0] z:(MADD a x y)) yes no)
// cond: z.Uses==1
// result: (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
@@ -28215,46 +28093,6 @@ func rewriteBlockARM64(b *Block) bool {
}
break
}
// match: (LE (CMP x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (LE (CMN x y) yes no)
for b.Controls[0].Op == OpARM64CMP {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64LE, v0)
return true
}
// match: (LE (CMPW x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (LE (CMNW x y) yes no)
for b.Controls[0].Op == OpARM64CMPW {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64LE, v0)
return true
}
// match: (LE (CMPconst [0] z:(MADD a x y)) yes no)
// cond: z.Uses==1
// result: (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
@@ -28627,46 +28465,6 @@ func rewriteBlockARM64(b *Block) bool {
}
break
}
// match: (LT (CMP x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (LT (CMN x y) yes no)
for b.Controls[0].Op == OpARM64CMP {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMN, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64LT, v0)
return true
}
// match: (LT (CMPW x z:(NEG y)) yes no)
// cond: z.Uses == 1
// result: (LT (CMNW x y) yes no)
for b.Controls[0].Op == OpARM64CMPW {
v_0 := b.Controls[0]
_ = v_0.Args[1]
x := v_0.Args[0]
z := v_0.Args[1]
if z.Op != OpARM64NEG {
break
}
y := z.Args[0]
if !(z.Uses == 1) {
break
}
v0 := b.NewValue0(v_0.Pos, OpARM64CMNW, types.TypeFlags)
v0.AddArg2(x, y)
b.resetWithControl(BlockARM64LT, v0)
return true
}
// match: (LT (CMPconst [0] z:(MADD a x y)) yes no)
// cond: z.Uses==1
// result: (LTnoov (CMN a (MUL <x.Type> x y)) yes no)

View File

@@ -1080,13 +1080,14 @@ func rewriteValueRISCV64_OpEqPtr(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (EqPtr x y)
// result: (SEQZ (SUB <x.Type> x y))
// result: (SEQZ (SUB <typ.Uintptr> x y))
for {
x := v_0
y := v_1
v.reset(OpRISCV64SEQZ)
v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type)
v0 := b.NewValue0(v.Pos, OpRISCV64SUB, typ.Uintptr)
v0.AddArg2(x, y)
v.AddArg(v0)
return true
@@ -2629,13 +2630,14 @@ func rewriteValueRISCV64_OpNeqPtr(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
b := v.Block
typ := &b.Func.Config.Types
// match: (NeqPtr x y)
// result: (SNEZ (SUB <x.Type> x y))
// result: (SNEZ (SUB <typ.Uintptr> x y))
for {
x := v_0
y := v_1
v.reset(OpRISCV64SNEZ)
v0 := b.NewValue0(v.Pos, OpRISCV64SUB, x.Type)
v0 := b.NewValue0(v.Pos, OpRISCV64SUB, typ.Uintptr)
v0.AddArg2(x, y)
v.AddArg(v0)
return true

View File

@@ -2387,6 +2387,175 @@ func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op {
return x
}
func (s *state) conv(n ir.Node, v *ssa.Value, ft, tt *types.Type) *ssa.Value {
if ft.IsBoolean() && tt.IsKind(types.TUINT8) {
// Bool -> uint8 is generated internally when indexing into runtime.staticbyte.
return s.newValue1(ssa.OpCopy, tt, v)
}
if ft.IsInteger() && tt.IsInteger() {
var op ssa.Op
if tt.Size() == ft.Size() {
op = ssa.OpCopy
} else if tt.Size() < ft.Size() {
// truncation
switch 10*ft.Size() + tt.Size() {
case 21:
op = ssa.OpTrunc16to8
case 41:
op = ssa.OpTrunc32to8
case 42:
op = ssa.OpTrunc32to16
case 81:
op = ssa.OpTrunc64to8
case 82:
op = ssa.OpTrunc64to16
case 84:
op = ssa.OpTrunc64to32
default:
s.Fatalf("weird integer truncation %v -> %v", ft, tt)
}
} else if ft.IsSigned() {
// sign extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpSignExt8to16
case 14:
op = ssa.OpSignExt8to32
case 18:
op = ssa.OpSignExt8to64
case 24:
op = ssa.OpSignExt16to32
case 28:
op = ssa.OpSignExt16to64
case 48:
op = ssa.OpSignExt32to64
default:
s.Fatalf("bad integer sign extension %v -> %v", ft, tt)
}
} else {
// zero extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpZeroExt8to16
case 14:
op = ssa.OpZeroExt8to32
case 18:
op = ssa.OpZeroExt8to64
case 24:
op = ssa.OpZeroExt16to32
case 28:
op = ssa.OpZeroExt16to64
case 48:
op = ssa.OpZeroExt32to64
default:
s.Fatalf("weird integer sign extension %v -> %v", ft, tt)
}
}
return s.newValue1(op, tt, v)
}
if ft.IsFloat() || tt.IsFloat() {
conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
if s.config.RegSize == 4 && Arch.LinkArch.Family != sys.MIPS && !s.softFloat {
if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.ARM64 || Arch.LinkArch.Family == sys.Wasm || Arch.LinkArch.Family == sys.S390X || s.softFloat {
if conv1, ok1 := uint64fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.MIPS && !s.softFloat {
if ft.Size() == 4 && ft.IsInteger() && !ft.IsSigned() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint32Tofloat32(n, v, ft, tt)
}
if tt.Size() == 8 {
return s.uint32Tofloat64(n, v, ft, tt)
}
} else if tt.Size() == 4 && tt.IsInteger() && !tt.IsSigned() {
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint32(n, v, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint32(n, v, ft, tt)
}
}
}
if !ok {
s.Fatalf("weird float conversion %v -> %v", ft, tt)
}
op1, op2, it := conv.op1, conv.op2, conv.intermediateType
if op1 != ssa.OpInvalid && op2 != ssa.OpInvalid {
// normal case, not tripping over unsigned 64
if op1 == ssa.OpCopy {
if op2 == ssa.OpCopy {
return v
}
return s.newValueOrSfCall1(op2, tt, v)
}
if op2 == ssa.OpCopy {
return s.newValueOrSfCall1(op1, tt, v)
}
return s.newValueOrSfCall1(op2, tt, s.newValueOrSfCall1(op1, types.Types[it], v))
}
// Tricky 64-bit unsigned cases.
if ft.IsInteger() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint64Tofloat32(n, v, ft, tt)
}
if tt.Size() == 8 {
return s.uint64Tofloat64(n, v, ft, tt)
}
s.Fatalf("weird unsigned integer to float conversion %v -> %v", ft, tt)
}
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint64(n, v, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint64(n, v, ft, tt)
}
s.Fatalf("weird float to unsigned integer conversion %v -> %v", ft, tt)
return nil
}
if ft.IsComplex() && tt.IsComplex() {
var op ssa.Op
if ft.Size() == tt.Size() {
switch ft.Size() {
case 8:
op = ssa.OpRound32F
case 16:
op = ssa.OpRound64F
default:
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
} else if ft.Size() == 8 && tt.Size() == 16 {
op = ssa.OpCvt32Fto64F
} else if ft.Size() == 16 && tt.Size() == 8 {
op = ssa.OpCvt64Fto32F
} else {
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
ftp := types.FloatForComplex(ft)
ttp := types.FloatForComplex(tt)
return s.newValue2(ssa.OpComplexMake, tt,
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, v)),
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, v)))
}
s.Fatalf("unhandled OCONV %s -> %s", ft.Kind(), tt.Kind())
return nil
}
// expr converts the expression n to ssa, adds it to s and returns the ssa result.
func (s *state) expr(n ir.Node) *ssa.Value {
if ir.HasUniquePos(n) {
@@ -2574,174 +2743,7 @@ func (s *state) expr(n ir.Node) *ssa.Value {
case ir.OCONV:
n := n.(*ir.ConvExpr)
x := s.expr(n.X)
ft := n.X.Type() // from type
tt := n.Type() // to type
if ft.IsBoolean() && tt.IsKind(types.TUINT8) {
// Bool -> uint8 is generated internally when indexing into runtime.staticbyte.
return s.newValue1(ssa.OpCopy, n.Type(), x)
}
if ft.IsInteger() && tt.IsInteger() {
var op ssa.Op
if tt.Size() == ft.Size() {
op = ssa.OpCopy
} else if tt.Size() < ft.Size() {
// truncation
switch 10*ft.Size() + tt.Size() {
case 21:
op = ssa.OpTrunc16to8
case 41:
op = ssa.OpTrunc32to8
case 42:
op = ssa.OpTrunc32to16
case 81:
op = ssa.OpTrunc64to8
case 82:
op = ssa.OpTrunc64to16
case 84:
op = ssa.OpTrunc64to32
default:
s.Fatalf("weird integer truncation %v -> %v", ft, tt)
}
} else if ft.IsSigned() {
// sign extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpSignExt8to16
case 14:
op = ssa.OpSignExt8to32
case 18:
op = ssa.OpSignExt8to64
case 24:
op = ssa.OpSignExt16to32
case 28:
op = ssa.OpSignExt16to64
case 48:
op = ssa.OpSignExt32to64
default:
s.Fatalf("bad integer sign extension %v -> %v", ft, tt)
}
} else {
// zero extension
switch 10*ft.Size() + tt.Size() {
case 12:
op = ssa.OpZeroExt8to16
case 14:
op = ssa.OpZeroExt8to32
case 18:
op = ssa.OpZeroExt8to64
case 24:
op = ssa.OpZeroExt16to32
case 28:
op = ssa.OpZeroExt16to64
case 48:
op = ssa.OpZeroExt32to64
default:
s.Fatalf("weird integer sign extension %v -> %v", ft, tt)
}
}
return s.newValue1(op, n.Type(), x)
}
if ft.IsFloat() || tt.IsFloat() {
conv, ok := fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]
if s.config.RegSize == 4 && Arch.LinkArch.Family != sys.MIPS && !s.softFloat {
if conv1, ok1 := fpConvOpToSSA32[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.ARM64 || Arch.LinkArch.Family == sys.Wasm || Arch.LinkArch.Family == sys.S390X || s.softFloat {
if conv1, ok1 := uint64fpConvOpToSSA[twoTypes{s.concreteEtype(ft), s.concreteEtype(tt)}]; ok1 {
conv = conv1
}
}
if Arch.LinkArch.Family == sys.MIPS && !s.softFloat {
if ft.Size() == 4 && ft.IsInteger() && !ft.IsSigned() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint32Tofloat32(n, x, ft, tt)
}
if tt.Size() == 8 {
return s.uint32Tofloat64(n, x, ft, tt)
}
} else if tt.Size() == 4 && tt.IsInteger() && !tt.IsSigned() {
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint32(n, x, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint32(n, x, ft, tt)
}
}
}
if !ok {
s.Fatalf("weird float conversion %v -> %v", ft, tt)
}
op1, op2, it := conv.op1, conv.op2, conv.intermediateType
if op1 != ssa.OpInvalid && op2 != ssa.OpInvalid {
// normal case, not tripping over unsigned 64
if op1 == ssa.OpCopy {
if op2 == ssa.OpCopy {
return x
}
return s.newValueOrSfCall1(op2, n.Type(), x)
}
if op2 == ssa.OpCopy {
return s.newValueOrSfCall1(op1, n.Type(), x)
}
return s.newValueOrSfCall1(op2, n.Type(), s.newValueOrSfCall1(op1, types.Types[it], x))
}
// Tricky 64-bit unsigned cases.
if ft.IsInteger() {
// tt is float32 or float64, and ft is also unsigned
if tt.Size() == 4 {
return s.uint64Tofloat32(n, x, ft, tt)
}
if tt.Size() == 8 {
return s.uint64Tofloat64(n, x, ft, tt)
}
s.Fatalf("weird unsigned integer to float conversion %v -> %v", ft, tt)
}
// ft is float32 or float64, and tt is unsigned integer
if ft.Size() == 4 {
return s.float32ToUint64(n, x, ft, tt)
}
if ft.Size() == 8 {
return s.float64ToUint64(n, x, ft, tt)
}
s.Fatalf("weird float to unsigned integer conversion %v -> %v", ft, tt)
return nil
}
if ft.IsComplex() && tt.IsComplex() {
var op ssa.Op
if ft.Size() == tt.Size() {
switch ft.Size() {
case 8:
op = ssa.OpRound32F
case 16:
op = ssa.OpRound64F
default:
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
} else if ft.Size() == 8 && tt.Size() == 16 {
op = ssa.OpCvt32Fto64F
} else if ft.Size() == 16 && tt.Size() == 8 {
op = ssa.OpCvt64Fto32F
} else {
s.Fatalf("weird complex conversion %v -> %v", ft, tt)
}
ftp := types.FloatForComplex(ft)
ttp := types.FloatForComplex(tt)
return s.newValue2(ssa.OpComplexMake, tt,
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexReal, ftp, x)),
s.newValueOrSfCall1(op, ttp, s.newValue1(ssa.OpComplexImag, ftp, x)))
}
s.Fatalf("unhandled OCONV %s -> %s", n.X.Type().Kind(), n.Type().Kind())
return nil
return s.conv(n, x, n.X.Type(), n.Type())
case ir.ODOTTYPE:
n := n.(*ir.TypeAssertExpr)
@@ -5116,6 +5118,18 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
for _, p := range params.InParams() { // includes receiver for interface calls
ACArgs = append(ACArgs, p.Type)
}
// Split the entry block if there are open defers, because later calls to
// openDeferSave may cause a mismatch between the mem for an OpDereference
// and the call site which uses it. See #49282.
if s.curBlock.ID == s.f.Entry.ID && s.hasOpenDefers {
b := s.endBlock()
b.Kind = ssa.BlockPlain
curb := s.f.NewBlock(ssa.BlockPlain)
b.AddEdgeTo(curb)
s.startBlock(curb)
}
for i, n := range args {
callArgs = append(callArgs, s.putArg(n, t.Params().Field(i).Type))
}

View File

@@ -73,7 +73,7 @@ func embedKind(typ *types.Type) int {
if typ.Kind() == types.TSTRING {
return embedString
}
if typ.Sym() == nil && typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
if typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
return embedBytes
}
return embedUnknown

View File

@@ -1222,12 +1222,14 @@ func (r *importReader) node() ir.Node {
switch op {
case ir.ODOT, ir.ODOTPTR, ir.ODOTINTER:
n.Selection = r.exoticField()
case ir.ODOTMETH, ir.OCALLPART, ir.OMETHEXPR:
case ir.OMETHEXPR:
n = typecheckMethodExpr(n).(*ir.SelectorExpr)
case ir.ODOTMETH, ir.OCALLPART:
// These require a Lookup to link to the correct declaration.
rcvrType := expr.Type()
typ := n.Type()
n.Selection = Lookdot(n, rcvrType, 1)
if op == ir.OCALLPART || op == ir.OMETHEXPR {
if op == ir.OCALLPART {
// Lookdot clobbers the opcode and type, undo that.
n.SetOp(op)
n.SetType(typ)

View File

@@ -383,10 +383,11 @@ func tcSelect(sel *ir.SelectStmt) {
n := Stmt(ncase.Comm)
ncase.Comm = n
oselrecv2 := func(dst, recv ir.Node, def bool) {
n := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
n.Def = def
n.SetTypecheck(1)
ncase.Comm = n
selrecv := ir.NewAssignListStmt(n.Pos(), ir.OSELRECV2, []ir.Node{dst, ir.BlankNode}, []ir.Node{recv})
selrecv.Def = def
selrecv.SetTypecheck(1)
selrecv.SetInit(n.Init())
ncase.Comm = selrecv
}
switch n.Op() {
default:

View File

@@ -4,12 +4,15 @@ go 1.17
require (
github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect
golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e // indirect
golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
golang.org/x/mod v0.5.1
golang.org/x/term v0.0.0-20210503060354-a79de5458b56
golang.org/x/tools v0.1.2-0.20210519160823-49064d2332f9
)
require (
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e // indirect
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
)

View File

@@ -10,11 +10,11 @@ golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e h1:pv3V0NlNSh5Q6AX/StwGLBjc
golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI=
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a h1:e8qnjKz4EE6OjRki9wTadWSIogINvq10sMcuBRORxMY=
golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=

View File

@@ -2,17 +2,51 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Copied from Go distribution src/go/build/build.go, syslist.go
// Copied from Go distribution src/go/build/build.go, syslist.go.
// That package does not export the ability to process raw file data,
// although we could fake it with an appropriate build.Context
// and a lot of unwrapping.
// More importantly, that package does not implement the tags["*"]
// special case, in which both tag and !tag are considered to be true
// for essentially all tags (except "ignore").
//
// If we added this API to go/build directly, we wouldn't need this
// file anymore, but this API is not terribly general-purpose and we
// don't really want to commit to any public form of it, nor do we
// want to move the core parts of go/build into a top-level internal package.
// These details change very infrequently, so the copy is fine.
package imports
import (
"bytes"
"errors"
"fmt"
"go/build/constraint"
"strings"
"unicode"
)
var slashslash = []byte("//")
var (
bSlashSlash = []byte("//")
bStarSlash = []byte("*/")
bSlashStar = []byte("/*")
bPlusBuild = []byte("+build")
goBuildComment = []byte("//go:build")
errGoBuildWithoutBuild = errors.New("//go:build comment without // +build comment")
errMultipleGoBuild = errors.New("multiple //go:build comments")
)
func isGoBuildComment(line []byte) bool {
if !bytes.HasPrefix(line, goBuildComment) {
return false
}
line = bytes.TrimSpace(line)
rest := line[len(goBuildComment):]
return len(rest) == 0 || len(bytes.TrimSpace(rest)) < len(rest)
}
// ShouldBuild reports whether it is okay to use this file,
// The rule is that in the file's leading run of // comments
@@ -34,90 +68,124 @@ var slashslash = []byte("//")
// in any build.
//
func ShouldBuild(content []byte, tags map[string]bool) bool {
// Pass 1. Identify leading run of // comments and blank lines,
// Identify leading run of // comments and blank lines,
// which must be followed by a blank line.
end := 0
p := content
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if len(line) == 0 { // Blank line
end = len(content) - len(p)
continue
}
if !bytes.HasPrefix(line, slashslash) { // Not comment line
break
}
// Also identify any //go:build comments.
content, goBuild, _, err := parseFileHeader(content)
if err != nil {
return false
}
content = content[:end]
// Pass 2. Process each line in the run.
p = content
allok := true
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
// If //go:build line is present, it controls.
// Otherwise fall back to +build processing.
var shouldBuild bool
switch {
case goBuild != nil:
x, err := constraint.Parse(string(goBuild))
if err != nil {
return false
}
line = bytes.TrimSpace(line)
if !bytes.HasPrefix(line, slashslash) {
continue
}
line = bytes.TrimSpace(line[len(slashslash):])
if len(line) > 0 && line[0] == '+' {
// Looks like a comment +line.
f := strings.Fields(string(line))
if f[0] == "+build" {
ok := false
for _, tok := range f[1:] {
if matchTags(tok, tags) {
ok = true
}
}
if !ok {
allok = false
shouldBuild = eval(x, tags, true)
default:
shouldBuild = true
p := content
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if !bytes.HasPrefix(line, bSlashSlash) || !bytes.Contains(line, bPlusBuild) {
continue
}
text := string(line)
if !constraint.IsPlusBuild(text) {
continue
}
if x, err := constraint.Parse(text); err == nil {
if !eval(x, tags, true) {
shouldBuild = false
}
}
}
}
return allok
return shouldBuild
}
// matchTags reports whether the name is one of:
//
// tag (if tags[tag] is true)
// !tag (if tags[tag] is false)
// a comma-separated list of any of these
//
func matchTags(name string, tags map[string]bool) bool {
if name == "" {
return false
func parseFileHeader(content []byte) (trimmed, goBuild []byte, sawBinaryOnly bool, err error) {
end := 0
p := content
ended := false // found non-blank, non-// line, so stopped accepting // +build lines
inSlashStar := false // in /* */ comment
Lines:
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if len(line) == 0 && !ended { // Blank line
// Remember position of most recent blank line.
// When we find the first non-blank, non-// line,
// this "end" position marks the latest file position
// where a // +build line can appear.
// (It must appear _before_ a blank line before the non-blank, non-// line.
// Yes, that's confusing, which is part of why we moved to //go:build lines.)
// Note that ended==false here means that inSlashStar==false,
// since seeing a /* would have set ended==true.
end = len(content) - len(p)
continue Lines
}
if !bytes.HasPrefix(line, bSlashSlash) { // Not comment line
ended = true
}
if !inSlashStar && isGoBuildComment(line) {
if goBuild != nil {
return nil, nil, false, errMultipleGoBuild
}
goBuild = line
}
Comments:
for len(line) > 0 {
if inSlashStar {
if i := bytes.Index(line, bStarSlash); i >= 0 {
inSlashStar = false
line = bytes.TrimSpace(line[i+len(bStarSlash):])
continue Comments
}
continue Lines
}
if bytes.HasPrefix(line, bSlashSlash) {
continue Lines
}
if bytes.HasPrefix(line, bSlashStar) {
inSlashStar = true
line = bytes.TrimSpace(line[len(bSlashStar):])
continue Comments
}
// Found non-comment text.
break Lines
}
}
if i := strings.Index(name, ","); i >= 0 {
// comma-separated list
ok1 := matchTags(name[:i], tags)
ok2 := matchTags(name[i+1:], tags)
return ok1 && ok2
}
if strings.HasPrefix(name, "!!") { // bad syntax, reject always
return false
}
if strings.HasPrefix(name, "!") { // negation
return len(name) > 1 && matchTag(name[1:], tags, false)
}
return matchTag(name, tags, true)
return content[:end], goBuild, sawBinaryOnly, nil
}
// matchTag reports whether the tag name is valid and satisfied by tags[name]==want.
func matchTag(name string, tags map[string]bool, want bool) bool {
// matchTag reports whether the tag name is valid and tags[name] is true.
// As a special case, if tags["*"] is true and name is not empty or ignore,
// then matchTag will return prefer instead of the actual answer,
// which allows the caller to pretend in that case that most tags are
// both true and false.
func matchTag(name string, tags map[string]bool, prefer bool) bool {
// Tags must be letters, digits, underscores or dots.
// Unlike in Go identifiers, all digits are fine (e.g., "386").
for _, c := range name {
@@ -131,7 +199,7 @@ func matchTag(name string, tags map[string]bool, want bool) bool {
// if we put * in the tags map then all tags
// except "ignore" are considered both present and not
// (so we return true no matter how 'want' is set).
return true
return prefer
}
have := tags[name]
@@ -144,7 +212,25 @@ func matchTag(name string, tags map[string]bool, want bool) bool {
if name == "darwin" {
have = have || tags["ios"]
}
return have == want
return have
}
// eval is like
// x.Eval(func(tag string) bool { return matchTag(tag, tags) })
// except that it implements the special case for tags["*"] meaning
// all tags are both true and false at the same time.
func eval(x constraint.Expr, tags map[string]bool, prefer bool) bool {
switch x := x.(type) {
case *constraint.TagExpr:
return matchTag(x.Tag, tags, prefer)
case *constraint.NotExpr:
return !eval(x.X, tags, !prefer)
case *constraint.AndExpr:
return eval(x.X, tags, prefer) && eval(x.Y, tags, prefer)
case *constraint.OrExpr:
return eval(x.X, tags, prefer) || eval(x.Y, tags, prefer)
}
panic(fmt.Sprintf("unexpected constraint expression %T", x))
}
// MatchFile returns false if the name contains a $GOOS or $GOARCH

View File

@@ -298,42 +298,61 @@ func (r *codeRepo) Latest() (*RevInfo, error) {
// If statVers is a valid module version, it is used for the Version field.
// Otherwise, the Version is derived from the passed-in info and recent tags.
func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, error) {
info2 := &RevInfo{
Name: info.Name,
Short: info.Short,
Time: info.Time,
}
// If this is a plain tag (no dir/ prefix)
// and the module path is unversioned,
// and if the underlying file tree has no go.mod,
// then allow using the tag with a +incompatible suffix.
var canUseIncompatible func() bool
canUseIncompatible = func() bool {
var ok bool
if r.codeDir == "" && r.pathMajor == "" {
//
// (If the version is +incompatible, then the go.mod file must not exist:
// +incompatible is not an ongoing opt-out from semantic import versioning.)
incompatibleOk := map[string]bool{}
canUseIncompatible := func(v string) bool {
if r.codeDir != "" || r.pathMajor != "" {
// A non-empty codeDir indicates a module within a subdirectory,
// which necessarily has a go.mod file indicating the module boundary.
// A non-empty pathMajor indicates a module path with a major-version
// suffix, which must match.
return false
}
ok, seen := incompatibleOk[""]
if !seen {
_, errGoMod := r.code.ReadFile(info.Name, "go.mod", codehost.MaxGoMod)
if errGoMod != nil {
ok = true
ok = (errGoMod != nil)
incompatibleOk[""] = ok
}
if !ok {
// A go.mod file exists at the repo root.
return false
}
// Per https://go.dev/issue/51324, previous versions of the 'go' command
// didn't always check for go.mod files in subdirectories, so if the user
// requests a +incompatible version explicitly, we should continue to allow
// it. Otherwise, if vN/go.mod exists, expect that release tags for that
// major version are intended for the vN module.
if v != "" && !strings.HasSuffix(statVers, "+incompatible") {
major := semver.Major(v)
ok, seen = incompatibleOk[major]
if !seen {
_, errGoModSub := r.code.ReadFile(info.Name, path.Join(major, "go.mod"), codehost.MaxGoMod)
ok = (errGoModSub != nil)
incompatibleOk[major] = ok
}
if !ok {
return false
}
}
canUseIncompatible = func() bool { return ok }
return ok
return true
}
invalidf := func(format string, args ...interface{}) error {
return &module.ModuleError{
Path: r.modPath,
Err: &module.InvalidVersionError{
Version: info2.Version,
Err: fmt.Errorf(format, args...),
},
}
}
// checkGoMod verifies that the go.mod file for the module exists or does not
// exist as required by info2.Version and the module path represented by r.
checkGoMod := func() (*RevInfo, error) {
// checkCanonical verifies that the canonical version v is compatible with the
// module path represented by r, adding a "+incompatible" suffix if needed.
//
// If statVers is also canonical, checkCanonical also verifies that v is
// either statVers or statVers with the added "+incompatible" suffix.
checkCanonical := func(v string) (*RevInfo, error) {
// If r.codeDir is non-empty, then the go.mod file must exist: the module
// author — not the module consumer, — gets to decide how to carve up the repo
// into modules.
@@ -344,73 +363,91 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
// r.findDir verifies both of these conditions. Execute it now so that
// r.Stat will correctly return a notExistError if the go.mod location or
// declared module path doesn't match.
_, _, _, err := r.findDir(info2.Version)
_, _, _, err := r.findDir(v)
if err != nil {
// TODO: It would be nice to return an error like "not a module".
// Right now we return "missing go.mod", which is a little confusing.
return nil, &module.ModuleError{
Path: r.modPath,
Err: &module.InvalidVersionError{
Version: info2.Version,
Version: v,
Err: notExistError{err: err},
},
}
}
// If the version is +incompatible, then the go.mod file must not exist:
// +incompatible is not an ongoing opt-out from semantic import versioning.
if strings.HasSuffix(info2.Version, "+incompatible") {
if !canUseIncompatible() {
if r.pathMajor != "" {
return nil, invalidf("+incompatible suffix not allowed: module path includes a major version suffix, so major version must match")
} else {
return nil, invalidf("+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required")
}
}
if err := module.CheckPathMajor(strings.TrimSuffix(info2.Version, "+incompatible"), r.pathMajor); err == nil {
return nil, invalidf("+incompatible suffix not allowed: major version %s is compatible", semver.Major(info2.Version))
invalidf := func(format string, args ...interface{}) error {
return &module.ModuleError{
Path: r.modPath,
Err: &module.InvalidVersionError{
Version: v,
Err: fmt.Errorf(format, args...),
},
}
}
return info2, nil
// Add the +incompatible suffix if needed or requested explicitly, and
// verify that its presence or absence is appropriate for this version
// (which depends on whether it has an explicit go.mod file).
if v == strings.TrimSuffix(statVers, "+incompatible") {
v = statVers
}
base := strings.TrimSuffix(v, "+incompatible")
var errIncompatible error
if !module.MatchPathMajor(base, r.pathMajor) {
if canUseIncompatible(base) {
v = base + "+incompatible"
} else {
if r.pathMajor != "" {
errIncompatible = invalidf("module path includes a major version suffix, so major version must match")
} else {
errIncompatible = invalidf("module contains a go.mod file, so module path must match major version (%q)", path.Join(r.pathPrefix, semver.Major(v)))
}
}
} else if strings.HasSuffix(v, "+incompatible") {
errIncompatible = invalidf("+incompatible suffix not allowed: major version %s is compatible", semver.Major(v))
}
if statVers != "" && statVers == module.CanonicalVersion(statVers) {
// Since the caller-requested version is canonical, it would be very
// confusing to resolve it to anything but itself, possibly with a
// "+incompatible" suffix. Error out explicitly.
if statBase := strings.TrimSuffix(statVers, "+incompatible"); statBase != base {
return nil, &module.ModuleError{
Path: r.modPath,
Err: &module.InvalidVersionError{
Version: statVers,
Err: fmt.Errorf("resolves to version %v (%s is not a tag)", v, statBase),
},
}
}
}
if errIncompatible != nil {
return nil, errIncompatible
}
return &RevInfo{
Name: info.Name,
Short: info.Short,
Time: info.Time,
Version: v,
}, nil
}
// Determine version.
//
// If statVers is canonical, then the original call was repo.Stat(statVers).
// Since the version is canonical, we must not resolve it to anything but
// itself, possibly with a '+incompatible' annotation: we do not need to do
// the work required to look for an arbitrary pseudo-version.
if statVers != "" && statVers == module.CanonicalVersion(statVers) {
info2.Version = statVers
if module.IsPseudoVersion(info2.Version) {
if err := r.validatePseudoVersion(info, info2.Version); err != nil {
return nil, err
}
return checkGoMod()
if module.IsPseudoVersion(statVers) {
if err := r.validatePseudoVersion(info, statVers); err != nil {
return nil, err
}
if err := module.CheckPathMajor(info2.Version, r.pathMajor); err != nil {
if canUseIncompatible() {
info2.Version += "+incompatible"
return checkGoMod()
} else {
if vErr, ok := err.(*module.InvalidVersionError); ok {
// We're going to describe why the version is invalid in more detail,
// so strip out the existing “invalid version” wrapper.
err = vErr.Err
}
return nil, invalidf("module contains a go.mod file, so major version must be compatible: %v", err)
}
}
return checkGoMod()
return checkCanonical(statVers)
}
// statVers is empty or non-canonical, so we need to resolve it to a canonical
// version or pseudo-version.
// statVers is not a pseudo-version, so we need to either resolve it to a
// canonical version or verify that it is already a canonical tag
// (not a branch).
// Derive or verify a version from a code repo tag.
// Tag must have a prefix matching codeDir.
@@ -441,71 +478,62 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
if v == "" || !strings.HasPrefix(trimmed, v) {
return "", false // Invalid or incomplete version (just vX or vX.Y).
}
if isRetracted(v) {
return "", false
}
if v == trimmed {
tagIsCanonical = true
}
if err := module.CheckPathMajor(v, r.pathMajor); err != nil {
if canUseIncompatible() {
return v + "+incompatible", tagIsCanonical
}
return "", false
}
return v, tagIsCanonical
}
// If the VCS gave us a valid version, use that.
if v, tagIsCanonical := tagToVersion(info.Version); tagIsCanonical {
info2.Version = v
return checkGoMod()
if info, err := checkCanonical(v); err == nil {
return info, err
}
}
// Look through the tags on the revision for either a usable canonical version
// or an appropriate base for a pseudo-version.
var pseudoBase string
var (
highestCanonical string
pseudoBase string
)
for _, pathTag := range info.Tags {
v, tagIsCanonical := tagToVersion(pathTag)
if tagIsCanonical {
if statVers != "" && semver.Compare(v, statVers) == 0 {
// The user requested a non-canonical version, but the tag for the
// canonical equivalent refers to the same revision. Use it.
info2.Version = v
return checkGoMod()
if statVers != "" && semver.Compare(v, statVers) == 0 {
// The tag is equivalent to the version requested by the user.
if tagIsCanonical {
// This tag is the canonical form of the requested version,
// not some other form with extra build metadata.
// Use this tag so that the resolved version will match exactly.
// (If it isn't actually allowed, we'll error out in checkCanonical.)
return checkCanonical(v)
} else {
// Save the highest canonical tag for the revision. If we don't find a
// better match, we'll use it as the canonical version.
// The user explicitly requested something equivalent to this tag. We
// can't use the version from the tag directly: since the tag is not
// canonical, it could be ambiguous. For example, tags v0.0.1+a and
// v0.0.1+b might both exist and refer to different revisions.
//
// NOTE: Do not replace this with semver.Max. Despite the name,
// semver.Max *also* canonicalizes its arguments, which uses
// semver.Canonical instead of module.CanonicalVersion and thereby
// strips our "+incompatible" suffix.
if semver.Compare(info2.Version, v) < 0 {
info2.Version = v
}
// The tag is otherwise valid for the module, so we can at least use it as
// the base of an unambiguous pseudo-version.
//
// If multiple tags match, tagToVersion will canonicalize them to the same
// base version.
pseudoBase = v
}
}
// Save the highest non-retracted canonical tag for the revision.
// If we don't find a better match, we'll use it as the canonical version.
if tagIsCanonical && semver.Compare(highestCanonical, v) < 0 && !isRetracted(v) {
if module.MatchPathMajor(v, r.pathMajor) || canUseIncompatible(v) {
highestCanonical = v
}
} else if v != "" && semver.Compare(v, statVers) == 0 {
// The user explicitly requested something equivalent to this tag. We
// can't use the version from the tag directly: since the tag is not
// canonical, it could be ambiguous. For example, tags v0.0.1+a and
// v0.0.1+b might both exist and refer to different revisions.
//
// The tag is otherwise valid for the module, so we can at least use it as
// the base of an unambiguous pseudo-version.
//
// If multiple tags match, tagToVersion will canonicalize them to the same
// base version.
pseudoBase = v
}
}
// If we found any canonical tag for the revision, return it.
// If we found a valid canonical tag for the revision, return it.
// Even if we found a good pseudo-version base, a canonical version is better.
if info2.Version != "" {
return checkGoMod()
if highestCanonical != "" {
return checkCanonical(highestCanonical)
}
// Find the highest tagged version in the revision's history, subject to
@@ -514,12 +542,12 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
// retracted versions.
allowedMajor := func(major string) func(v string) bool {
return func(v string) bool {
return (major == "" || semver.Major(v) == major) && !isRetracted(v)
return ((major == "" && canUseIncompatible(v)) || semver.Major(v) == major) && !isRetracted(v)
}
}
if pseudoBase == "" {
var tag string
if r.pseudoMajor != "" || canUseIncompatible() {
if r.pseudoMajor != "" || canUseIncompatible("") {
tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor(r.pseudoMajor))
} else {
// Allow either v1 or v0, but not incompatible higher versions.
@@ -528,11 +556,10 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v0"))
}
}
pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid
pseudoBase, _ = tagToVersion(tag)
}
info2.Version = module.PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short)
return checkGoMod()
return checkCanonical(module.PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short))
}
// validatePseudoVersion checks that version has a major version compatible with
@@ -556,10 +583,6 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string)
}
}()
if err := module.CheckPathMajor(version, r.pathMajor); err != nil {
return err
}
rev, err := module.PseudoVersionRev(version)
if err != nil {
return err

View File

@@ -418,171 +418,252 @@ var codeRepoTests = []codeRepoTest{
zipSum: "h1:JItBZ+gwA5WvtZEGEbuDL4lUttGtLrs53lmdurq3bOg=",
zipFileHash: "9ea9ae1673cffcc44b7fdd3cc89953d68c102449b46c982dbf085e4f2e394da5",
},
{
// Git branch with a semver name, +incompatible version, and no go.mod file.
vcs: "git",
path: "vcs-test.golang.org/go/mod/gitrepo1",
rev: "v2.3.4+incompatible",
err: `resolves to version v2.0.1+incompatible (v2.3.4 is not a tag)`,
},
{
// Git branch with a semver name, matching go.mod file, and compatible version.
vcs: "git",
path: "vcs-test.golang.org/git/semver-branch.git",
rev: "v1.0.0",
err: `resolves to version v0.1.1-0.20220202191944-09c4d8f6938c (v1.0.0 is not a tag)`,
},
{
// Git branch with a semver name, matching go.mod file, and disallowed +incompatible version.
// The version/tag mismatch takes precedence over the +incompatible mismatched.
vcs: "git",
path: "vcs-test.golang.org/git/semver-branch.git",
rev: "v2.0.0+incompatible",
err: `resolves to version v0.1.0 (v2.0.0 is not a tag)`,
},
{
// Git branch with a semver name, matching go.mod file, and mismatched version.
// The version/tag mismatch takes precedence over the +incompatible mismatched.
vcs: "git",
path: "vcs-test.golang.org/git/semver-branch.git",
rev: "v2.0.0",
err: `resolves to version v0.1.0 (v2.0.0 is not a tag)`,
},
{
// v3.0.0-devel is the same as tag v4.0.0-beta.1, but v4.0.0-beta.1 would
// not be allowed because it is incompatible and a go.mod file exists.
// The error message should refer to a valid pseudo-version, not the
// unusable semver tag.
vcs: "git",
path: "vcs-test.golang.org/git/semver-branch.git",
rev: "v3.0.0-devel",
err: `resolves to version v0.1.1-0.20220203155313-d59622f6e4d7 (v3.0.0-devel is not a tag)`,
},
// If v2/go.mod exists, then we should prefer to match the "v2"
// pseudo-versions to the nested module, and resolve the module in the parent
// directory to only compatible versions.
//
// However (https://go.dev/issue/51324), previous versions of the 'go' command
// didn't always do so, so if the user explicitly requests a +incompatible
// version (as would be present in an existing go.mod file), we should
// continue to allow it.
{
vcs: "git",
path: "vcs-test.golang.org/git/v2sub.git",
rev: "80beb17a1603",
version: "v0.0.0-20220222205507-80beb17a1603",
name: "80beb17a16036f17a5aedd1bb5bd6d407b3c6dc5",
short: "80beb17a1603",
time: time.Date(2022, 2, 22, 20, 55, 7, 0, time.UTC),
},
{
vcs: "git",
path: "vcs-test.golang.org/git/v2sub.git",
rev: "v2.0.0",
err: `module contains a go.mod file, so module path must match major version ("vcs-test.golang.org/git/v2sub.git/v2")`,
},
{
vcs: "git",
path: "vcs-test.golang.org/git/v2sub.git",
rev: "v2.0.1-0.20220222205507-80beb17a1603",
err: `module contains a go.mod file, so module path must match major version ("vcs-test.golang.org/git/v2sub.git/v2")`,
},
{
vcs: "git",
path: "vcs-test.golang.org/git/v2sub.git",
rev: "v2.0.0+incompatible",
version: "v2.0.0+incompatible",
name: "5fcd3eaeeb391d399f562fd45a50dac9fc34ae8b",
short: "5fcd3eaeeb39",
time: time.Date(2022, 2, 22, 20, 53, 33, 0, time.UTC),
},
{
vcs: "git",
path: "vcs-test.golang.org/git/v2sub.git",
rev: "v2.0.1-0.20220222205507-80beb17a1603+incompatible",
version: "v2.0.1-0.20220222205507-80beb17a1603+incompatible",
name: "80beb17a16036f17a5aedd1bb5bd6d407b3c6dc5",
short: "80beb17a1603",
time: time.Date(2022, 2, 22, 20, 55, 7, 0, time.UTC),
},
}
func TestCodeRepo(t *testing.T) {
testenv.MustHaveExternalNetwork(t)
tmpdir := t.TempDir()
tmpdir, err := os.MkdirTemp("", "modfetch-test-")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
for _, tt := range codeRepoTests {
f := func(tt codeRepoTest) func(t *testing.T) {
return func(t *testing.T) {
t.Parallel()
if tt.vcs != "mod" {
testenv.MustHaveExecPath(t, tt.vcs)
}
t.Run("parallel", func(t *testing.T) {
for _, tt := range codeRepoTests {
f := func(tt codeRepoTest) func(t *testing.T) {
return func(t *testing.T) {
t.Parallel()
if tt.vcs != "mod" {
testenv.MustHaveExecPath(t, tt.vcs)
}
repo := Lookup("direct", tt.path)
repo := Lookup("direct", tt.path)
if tt.mpath == "" {
tt.mpath = tt.path
}
if mpath := repo.ModulePath(); mpath != tt.mpath {
t.Errorf("repo.ModulePath() = %q, want %q", mpath, tt.mpath)
}
if tt.mpath == "" {
tt.mpath = tt.path
}
if mpath := repo.ModulePath(); mpath != tt.mpath {
t.Errorf("repo.ModulePath() = %q, want %q", mpath, tt.mpath)
}
info, err := repo.Stat(tt.rev)
if err != nil {
if tt.err != "" {
if !strings.Contains(err.Error(), tt.err) {
t.Fatalf("repoStat(%q): %v, wanted %q", tt.rev, err, tt.err)
}
return
}
t.Fatalf("repo.Stat(%q): %v", tt.rev, err)
}
info, err := repo.Stat(tt.rev)
if err != nil {
if tt.err != "" {
t.Errorf("repo.Stat(%q): success, wanted error", tt.rev)
}
if info.Version != tt.version {
t.Errorf("info.Version = %q, want %q", info.Version, tt.version)
}
if info.Name != tt.name {
t.Errorf("info.Name = %q, want %q", info.Name, tt.name)
}
if info.Short != tt.short {
t.Errorf("info.Short = %q, want %q", info.Short, tt.short)
}
if !info.Time.Equal(tt.time) {
t.Errorf("info.Time = %v, want %v", info.Time, tt.time)
if !strings.Contains(err.Error(), tt.err) {
t.Fatalf("repoStat(%q): %v, wanted %q", tt.rev, err, tt.err)
}
return
}
t.Fatalf("repo.Stat(%q): %v", tt.rev, err)
}
if tt.err != "" {
t.Errorf("repo.Stat(%q): success, wanted error", tt.rev)
}
if info.Version != tt.version {
t.Errorf("info.Version = %q, want %q", info.Version, tt.version)
}
if info.Name != tt.name {
t.Errorf("info.Name = %q, want %q", info.Name, tt.name)
}
if info.Short != tt.short {
t.Errorf("info.Short = %q, want %q", info.Short, tt.short)
}
if !info.Time.Equal(tt.time) {
t.Errorf("info.Time = %v, want %v", info.Time, tt.time)
}
if tt.gomod != "" || tt.gomodErr != "" {
data, err := repo.GoMod(tt.version)
if err != nil && tt.gomodErr == "" {
t.Errorf("repo.GoMod(%q): %v", tt.version, err)
} else if err != nil && tt.gomodErr != "" {
if err.Error() != tt.gomodErr {
t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomodErr)
}
} else if tt.gomodErr != "" {
t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomodErr)
} else if string(data) != tt.gomod {
t.Errorf("repo.GoMod(%q) = %q, want %q", tt.version, data, tt.gomod)
}
}
needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "")
if tt.zip != nil || tt.zipErr != "" || needHash {
f, err := os.CreateTemp(tmpdir, tt.version+".zip.")
if err != nil {
t.Fatalf("os.CreateTemp: %v", err)
}
zipfile := f.Name()
defer func() {
f.Close()
os.Remove(zipfile)
}()
var w io.Writer
var h hash.Hash
if needHash {
h = sha256.New()
w = io.MultiWriter(f, h)
} else {
w = f
}
err = repo.Zip(w, tt.version)
f.Close()
if err != nil {
if tt.zipErr != "" {
if err.Error() == tt.zipErr {
return
}
t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.zipErr)
}
t.Fatalf("repo.Zip(%q): %v", tt.version, err)
}
if tt.zipErr != "" {
t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.zipErr)
}
if tt.zip != nil {
prefix := tt.path + "@" + tt.version + "/"
z, err := zip.OpenReader(zipfile)
if err != nil {
t.Fatalf("open zip %s: %v", zipfile, err)
}
var names []string
for _, file := range z.File {
if !strings.HasPrefix(file.Name, prefix) {
t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix)
continue
}
names = append(names, file.Name[len(prefix):])
}
z.Close()
if !reflect.DeepEqual(names, tt.zip) {
t.Fatalf("zip = %v\nwant %v\n", names, tt.zip)
}
}
if needHash {
sum, err := dirhash.HashZip(zipfile, dirhash.Hash1)
if err != nil {
t.Errorf("repo.Zip(%q): %v", tt.version, err)
} else if sum != tt.zipSum {
t.Errorf("repo.Zip(%q): got file with sum %q, want %q", tt.version, sum, tt.zipSum)
} else if zipFileHash := hex.EncodeToString(h.Sum(nil)); zipFileHash != tt.zipFileHash {
t.Errorf("repo.Zip(%q): got file with hash %q, want %q (but content has correct sum)", tt.version, zipFileHash, tt.zipFileHash)
}
if tt.gomod != "" || tt.gomodErr != "" {
data, err := repo.GoMod(tt.version)
if err != nil && tt.gomodErr == "" {
t.Errorf("repo.GoMod(%q): %v", tt.version, err)
} else if err != nil && tt.gomodErr != "" {
if err.Error() != tt.gomodErr {
t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomodErr)
}
} else if tt.gomodErr != "" {
t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomodErr)
} else if string(data) != tt.gomod {
t.Errorf("repo.GoMod(%q) = %q, want %q", tt.version, data, tt.gomod)
}
}
}
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
if strings.HasPrefix(tt.path, vgotest1git) {
for vcs, alt := range altVgotests {
altTest := tt
altTest.vcs = vcs
altTest.path = alt + strings.TrimPrefix(altTest.path, vgotest1git)
if strings.HasPrefix(altTest.mpath, vgotest1git) {
altTest.mpath = alt + strings.TrimPrefix(altTest.mpath, vgotest1git)
needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "")
if tt.zip != nil || tt.zipErr != "" || needHash {
f, err := os.CreateTemp(tmpdir, tt.version+".zip.")
if err != nil {
t.Fatalf("os.CreateTemp: %v", err)
}
var m map[string]string
if alt == vgotest1hg {
m = hgmap
zipfile := f.Name()
defer func() {
f.Close()
os.Remove(zipfile)
}()
var w io.Writer
var h hash.Hash
if needHash {
h = sha256.New()
w = io.MultiWriter(f, h)
} else {
w = f
}
err = repo.Zip(w, tt.version)
f.Close()
if err != nil {
if tt.zipErr != "" {
if err.Error() == tt.zipErr {
return
}
t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.zipErr)
}
t.Fatalf("repo.Zip(%q): %v", tt.version, err)
}
if tt.zipErr != "" {
t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.zipErr)
}
if tt.zip != nil {
prefix := tt.path + "@" + tt.version + "/"
z, err := zip.OpenReader(zipfile)
if err != nil {
t.Fatalf("open zip %s: %v", zipfile, err)
}
var names []string
for _, file := range z.File {
if !strings.HasPrefix(file.Name, prefix) {
t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix)
continue
}
names = append(names, file.Name[len(prefix):])
}
z.Close()
if !reflect.DeepEqual(names, tt.zip) {
t.Fatalf("zip = %v\nwant %v\n", names, tt.zip)
}
}
if needHash {
sum, err := dirhash.HashZip(zipfile, dirhash.Hash1)
if err != nil {
t.Errorf("repo.Zip(%q): %v", tt.version, err)
} else if sum != tt.zipSum {
t.Errorf("repo.Zip(%q): got file with sum %q, want %q", tt.version, sum, tt.zipSum)
} else if zipFileHash := hex.EncodeToString(h.Sum(nil)); zipFileHash != tt.zipFileHash {
t.Errorf("repo.Zip(%q): got file with hash %q, want %q (but content has correct sum)", tt.version, zipFileHash, tt.zipFileHash)
}
}
altTest.version = remap(altTest.version, m)
altTest.name = remap(altTest.name, m)
altTest.short = remap(altTest.short, m)
altTest.rev = remap(altTest.rev, m)
altTest.err = remap(altTest.err, m)
altTest.gomodErr = remap(altTest.gomodErr, m)
altTest.zipErr = remap(altTest.zipErr, m)
altTest.zipSum = ""
altTest.zipFileHash = ""
t.Run(strings.ReplaceAll(altTest.path, "/", "_")+"/"+altTest.rev, f(altTest))
}
}
}
})
t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt))
if strings.HasPrefix(tt.path, vgotest1git) {
for vcs, alt := range altVgotests {
altTest := tt
altTest.vcs = vcs
altTest.path = alt + strings.TrimPrefix(altTest.path, vgotest1git)
if strings.HasPrefix(altTest.mpath, vgotest1git) {
altTest.mpath = alt + strings.TrimPrefix(altTest.mpath, vgotest1git)
}
var m map[string]string
if alt == vgotest1hg {
m = hgmap
}
altTest.version = remap(altTest.version, m)
altTest.name = remap(altTest.name, m)
altTest.short = remap(altTest.short, m)
altTest.rev = remap(altTest.rev, m)
altTest.err = remap(altTest.err, m)
altTest.gomodErr = remap(altTest.gomodErr, m)
altTest.zipErr = remap(altTest.zipErr, m)
altTest.zipSum = ""
altTest.zipFileHash = ""
t.Run(strings.ReplaceAll(altTest.path, "/", "_")+"/"+altTest.rev, f(altTest))
}
}
}
}
var hgmap = map[string]string{

View File

@@ -190,8 +190,8 @@ func limiterForEdit(ctx context.Context, rs *Requirements, tryUpgrade, mustSelec
// raiseLimitsForUpgrades increases the module versions in maxVersions to the
// versions that would be needed to allow each of the modules in tryUpgrade
// (individually) and all of the modules in mustSelect (simultaneously) to be
// added as roots.
// (individually or in any combination) and all of the modules in mustSelect
// (simultaneously) to be added as roots.
//
// Versions not present in maxVersion are unrestricted, and it is assumed that
// they will not be promoted to root requirements (and thus will not contribute
@@ -213,18 +213,42 @@ func raiseLimitsForUpgrades(ctx context.Context, maxVersion map[string]string, d
}
}
var eagerUpgrades []module.Version
var (
eagerUpgrades []module.Version
isLazyRootPath map[string]bool
)
if depth == eager {
eagerUpgrades = tryUpgrade
} else {
isLazyRootPath = make(map[string]bool, len(maxVersion))
for p := range maxVersion {
isLazyRootPath[p] = true
}
for _, m := range tryUpgrade {
isLazyRootPath[m.Path] = true
}
for _, m := range mustSelect {
isLazyRootPath[m.Path] = true
}
allowedRoot := map[module.Version]bool{}
var allowRoot func(m module.Version) error
allowRoot = func(m module.Version) error {
if allowedRoot[m] {
return nil
}
allowedRoot[m] = true
if m.Path == Target.Path {
// Target is already considered to be higher than any possible m, so we
// won't be upgrading to it anyway and there is no point scanning its
// dependencies.
continue
return nil
}
allow(m)
summary, err := goModSummary(m)
if err != nil {
return err
@@ -234,12 +258,27 @@ func raiseLimitsForUpgrades(ctx context.Context, maxVersion map[string]string, d
// graph, rather than loading the (potentially-overlapping) subgraph for
// each upgrade individually.
eagerUpgrades = append(eagerUpgrades, m)
continue
return nil
}
for _, r := range summary.require {
allow(r)
if isLazyRootPath[r.Path] {
// r could become a root as the result of an upgrade or downgrade,
// in which case its dependencies will not be pruned out.
// We need to allow those dependencies to be upgraded too.
if err := allowRoot(r); err != nil {
return err
}
} else {
// r will not become a root, so its dependencies don't matter.
// Allow only r itself.
allow(r)
}
}
return nil
}
for _, m := range tryUpgrade {
allowRoot(m)
}
}
@@ -268,16 +307,41 @@ func raiseLimitsForUpgrades(ctx context.Context, maxVersion map[string]string, d
}
}
if len(mustSelect) > 0 {
mustGraph, err := readModGraph(ctx, depth, mustSelect)
// Explicitly allow any (transitive) upgrades implied by mustSelect.
nextRoots := append([]module.Version(nil), mustSelect...)
for nextRoots != nil {
module.Sort(nextRoots)
rs := newRequirements(depth, nextRoots, nil)
nextRoots = nil
rs, mustGraph, err := expandGraph(ctx, rs)
if err != nil {
return err
}
for _, r := range mustGraph.BuildList() {
// Some module in mustSelect requires r, so we must allow at least r.Version
// unless it conflicts with an entry in mustSelect.
// Some module in mustSelect requires r, so we must allow at least
// r.Version (unless it conflicts with another entry in mustSelect, in
// which case we will error out either way).
allow(r)
if isLazyRootPath[r.Path] {
if v, ok := rs.rootSelected(r.Path); ok && r.Version == v {
// r is already a root, so its requirements are already included in
// the build list.
continue
}
// The dependencies in mustSelect may upgrade (or downgrade) an existing
// root to match r, which will remain as a root. However, since r is not
// a root of rs, its dependencies have been pruned out of this build
// list. We need to add it back explicitly so that we allow any
// transitive upgrades that r will pull in.
if nextRoots == nil {
nextRoots = rs.rootModules // already capped
}
nextRoots = append(nextRoots, r)
}
}
}

View File

@@ -5,7 +5,6 @@
package vcs
import (
"encoding/json"
"errors"
"fmt"
exec "internal/execabs"
@@ -1189,8 +1188,9 @@ var vcsPaths = []*vcsPath{
{
pathPrefix: "bitbucket.org",
regexp: lazyregexp.New(`^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`),
vcs: "git",
repo: "https://{root}",
check: bitbucketVCS,
check: noVCSSuffix,
},
// IBM DevOps Services (JazzHub)
@@ -1262,56 +1262,6 @@ func noVCSSuffix(match map[string]string) error {
return nil
}
// bitbucketVCS determines the version control system for a
// Bitbucket repository, by using the Bitbucket API.
func bitbucketVCS(match map[string]string) error {
if err := noVCSSuffix(match); err != nil {
return err
}
var resp struct {
SCM string `json:"scm"`
}
url := &urlpkg.URL{
Scheme: "https",
Host: "api.bitbucket.org",
Path: expand(match, "/2.0/repositories/{bitname}"),
RawQuery: "fields=scm",
}
data, err := web.GetBytes(url)
if err != nil {
if httpErr, ok := err.(*web.HTTPError); ok && httpErr.StatusCode == 403 {
// this may be a private repository. If so, attempt to determine which
// VCS it uses. See issue 5375.
root := match["root"]
for _, vcs := range []string{"git", "hg"} {
if vcsByCmd(vcs).Ping("https", root) == nil {
resp.SCM = vcs
break
}
}
}
if resp.SCM == "" {
return err
}
} else {
if err := json.Unmarshal(data, &resp); err != nil {
return fmt.Errorf("decoding %s: %v", url, err)
}
}
if vcsByCmd(resp.SCM) != nil {
match["vcs"] = resp.SCM
if resp.SCM == "git" {
match["repo"] += ".git"
}
return nil
}
return fmt.Errorf("unable to detect version control system for bitbucket.org/ path")
}
// launchpadVCS solves the ambiguity for "lp.net/project/foo". In this case,
// "foo" could be a series name registered in Launchpad with its own branch,
// and it could also be the name of a directory within the main project

View File

@@ -183,6 +183,13 @@ func TestRepoRootForImportPath(t *testing.T) {
"chiselapp.com/user/kyle/fossilgg",
nil,
},
{
"bitbucket.org/workspace/pkgname",
&RepoRoot{
VCS: vcsGit,
Repo: "https://bitbucket.org/workspace/pkgname",
},
},
}
for _, test := range tests {

View File

@@ -142,6 +142,7 @@ var extraEnvKeys = []string{
"GO_TESTING_GOTOOLS", // for gccgo testing
"GCCGO", // for gccgo testing
"GCCGOTOOLDIR", // for gccgo testing
"MallocNanoZone", // Needed to work around an apparent kernel bug in macOS 12; see https://golang.org/issue/49138.
}
// setup sets up the test execution temporary directory and environment.

View File

@@ -0,0 +1,41 @@
# go list all should work with GOOS=linux because all packages build on Linux
env GOOS=linux
go list all
# go list all should work with GOOS=darwin, but it used to fail because
# in the absence of //go:build support, p looked like it needed q
# (p_test.go was not properly excluded), and q was Linux-only.
#
# Also testing with r and s that +build lines keep working.
env GOOS=darwin
go list all
-- go.mod --
go 1.17
module m
-- p/p.go --
package p
-- p/p_test.go --
//go:build linux
package p
import "m/q"
-- q/q_linux.go --
package q
-- r/r.go --
package r
-- r/r_test.go --
// +build linux
package r
import "m/s"
-- s/s_linux.go --
package s

View File

@@ -202,9 +202,9 @@ go mod edit -go=1.17 u/go.mod
go mod edit -go=1.17 w/go.mod
go mod edit -go=1.17 x/go.mod
go mod edit -go=1.17
cp go.mod go.mod.orig
cmp go.mod go.mod.beforetidy
go mod tidy
cmp go.mod go.mod.orig
cmp go.mod go.mod.aftertidy
# With lazy loading, 'go list all' with neither -mod=vendor nor -test should
# match -mod=vendor without -test in 1.15.
@@ -466,3 +466,66 @@ module example.com/x
go 1.15
-- x/x.go --
package x
-- go.mod.beforetidy --
module example.com/main
// Note: this go.mod file initially specifies go 1.15,
// but includes some redundant roots so that it
// also already obeys the 1.17 lazy loading invariants.
go 1.17
require (
example.com/a v0.1.0
example.com/b v0.1.0 // indirect
example.com/q v0.1.0
example.com/r v0.1.0 // indirect
example.com/t v0.1.0
example.com/u v0.1.0 // indirect
)
replace (
example.com/a v0.1.0 => ./a
example.com/b v0.1.0 => ./b
example.com/c v0.1.0 => ./c
example.com/d v0.1.0 => ./d
example.com/q v0.1.0 => ./q
example.com/r v0.1.0 => ./r
example.com/s v0.1.0 => ./s
example.com/t v0.1.0 => ./t
example.com/u v0.1.0 => ./u
example.com/w v0.1.0 => ./w
example.com/x v0.1.0 => ./x
)
-- go.mod.aftertidy --
module example.com/main
// Note: this go.mod file initially specifies go 1.15,
// but includes some redundant roots so that it
// also already obeys the 1.17 lazy loading invariants.
go 1.17
require (
example.com/a v0.1.0
example.com/q v0.1.0
example.com/t v0.1.0
)
require (
example.com/b v0.1.0 // indirect
example.com/r v0.1.0 // indirect
example.com/u v0.1.0 // indirect
)
replace (
example.com/a v0.1.0 => ./a
example.com/b v0.1.0 => ./b
example.com/c v0.1.0 => ./c
example.com/d v0.1.0 => ./d
example.com/q v0.1.0 => ./q
example.com/r v0.1.0 => ./r
example.com/s v0.1.0 => ./s
example.com/t v0.1.0 => ./t
example.com/u v0.1.0 => ./u
example.com/w v0.1.0 => ./w
example.com/x v0.1.0 => ./x
)

View File

@@ -10,7 +10,7 @@ env GO111MODULE=on
env GOPROXY=direct
env GOSUMDB=off
go list -m cloud.google.com/go@master
go list -m cloud.google.com/go@main
! stdout 'v0.0.0-'
-- go.mod --

View File

@@ -0,0 +1,117 @@
# Regression test for https://golang.org/issue/47979:
#
# An argument to 'go get' that results in an upgrade to a different existing
# root should be allowed, and should not panic the 'go' command.
cp go.mod go.mod.orig
# Transitive upgrades from upgraded roots should not prevent
# 'go get -u' from performing upgrades.
cp go.mod.orig go.mod
go get -u -d .
cmp go.mod go.mod.want
# 'go get' of a specific version should allow upgrades of
# every dependency (transitively) required by that version,
# including dependencies that are pulled into the module
# graph by upgrading other root requirements
# (in this case, example.net/indirect).
cp go.mod.orig go.mod
go get -d example.net/a@v0.2.0
cmp go.mod go.mod.want
-- go.mod --
module golang.org/issue47979
go 1.17
replace (
example.net/a v0.1.0 => ./a1
example.net/a v0.2.0 => ./a2
example.net/indirect v0.1.0 => ./indirect1
example.net/indirect v0.2.0 => ./indirect2
example.net/other v0.1.0 => ./other
example.net/other v0.2.0 => ./other
)
require (
example.net/a v0.1.0
example.net/other v0.1.0
)
require example.net/indirect v0.1.0 // indirect
-- go.mod.want --
module golang.org/issue47979
go 1.17
replace (
example.net/a v0.1.0 => ./a1
example.net/a v0.2.0 => ./a2
example.net/indirect v0.1.0 => ./indirect1
example.net/indirect v0.2.0 => ./indirect2
example.net/other v0.1.0 => ./other
example.net/other v0.2.0 => ./other
)
require (
example.net/a v0.2.0
example.net/other v0.2.0
)
require example.net/indirect v0.2.0 // indirect
-- issue.go --
package issue
import _ "example.net/a"
-- useother/useother.go --
package useother
import _ "example.net/other"
-- a1/go.mod --
module example.net/a
go 1.17
require example.net/indirect v0.1.0
-- a1/a.go --
package a
-- a2/go.mod --
module example.net/a
go 1.17
require example.net/indirect v0.2.0
-- a2/a.go --
package a
import "example.net/indirect"
-- indirect1/go.mod --
module example.net/indirect
go 1.17
require example.net/other v0.1.0
-- indirect1/indirect.go --
package indirect
-- indirect2/go.mod --
module example.net/indirect
go 1.17
require example.net/other v0.2.0
-- indirect2/indirect.go --
package indirect
import "example.net/other"
-- other/go.mod --
module example.net/other
go 1.17
-- other/other.go --
package other

View File

@@ -0,0 +1,68 @@
# Check that 'go get -u' will upgrade a dependency (direct or indirect)
# when the main module and the dependency are both lazy.
# Verifies #47768.
# Check that go.mod is tidy, and an upgrade is available.
cp go.mod go.mod.orig
go mod tidy
cmp go.mod go.mod.orig
go list -m -u example.com/lazyupgrade
stdout '^example.com/lazyupgrade v0.1.0 \[v0.1.1\] => ./lazyupgrade@v0.1.0$'
# 'go get -u' on a package that directly imports the dependency should upgrade.
go get -u ./usedirect
go list -m example.com/lazyupgrade
stdout '^example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1$'
cp go.mod.orig go.mod
# 'go get -u' on a package that indirectly imports the dependency should upgrade.
go get -u ./useindirect
go list -m example.com/lazyupgrade
stdout '^example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1$'
-- go.mod --
module use
go 1.17
require (
direct v0.0.0
example.com/lazyupgrade v0.1.0
)
replace (
direct => ./direct
example.com/lazyupgrade v0.1.0 => ./lazyupgrade@v0.1.0
example.com/lazyupgrade v0.1.1 => ./lazyupgrade@v0.1.1
)
-- usedirect/usedirect.go --
package use
import _ "example.com/lazyupgrade"
-- useindirect/useindirect.go --
package use
import _ "direct"
-- direct/go.mod --
module direct
go 1.17
require example.com/lazyupgrade v0.1.0
-- direct/direct.go --
package direct
import _ "example.com/lazyupgrade"
-- lazyupgrade@v0.1.0/go.mod --
module example.com/lazyupgrade
go 1.17
-- lazyupgrade@v0.1.0/lazyupgrade.go --
package lazyupgrade
-- lazyupgrade@v0.1.1/go.mod --
module example.com/lazyupgrade
go 1.17
-- lazyupgrade@v0.1.1/lazyupgrade.go --
package lazyupgrade

View File

@@ -194,10 +194,10 @@ cp go.mod.orig go.mod
go mod edit -require github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d+incompatible
cd outside
! go list -m github.com/pierrec/lz4
stderr 'go list -m: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
stderr '^go list -m: example.com@v0.0.0 requires\n\tgithub.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$'
cd ..
! go list -m github.com/pierrec/lz4
stderr 'github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
stderr '^go list -m: github.com/pierrec/lz4@v2.0.9-0.20190209155647-9a39efadad3d\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$'
# A +incompatible pseudo-version is valid for a revision of the module
# that lacks a go.mod file.
@@ -222,7 +222,7 @@ stdout 'github.com/pierrec/lz4 v2.0.5\+incompatible'
# not resolve to a pseudo-version with a different major version.
cp go.mod.orig go.mod
! go get -d github.com/pierrec/lz4@v2.0.8
stderr 'go get: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2'
stderr 'go get: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$'
# An invalid +incompatible suffix for a canonical version should error out,
# not resolve to a pseudo-version.
@@ -233,10 +233,10 @@ cp go.mod.orig go.mod
go mod edit -require github.com/pierrec/lz4@v2.0.8+incompatible
cd outside
! go list -m github.com/pierrec/lz4
stderr 'github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
stderr '^go list -m: github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$'
cd ..
! go list -m github.com/pierrec/lz4
stderr 'github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: \+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required'
stderr '^go list -m: github.com/pierrec/lz4@v2.0.8\+incompatible: invalid version: module contains a go.mod file, so module path must match major version \("github.com/pierrec/lz4/v2"\)$'
-- go.mod.orig --
module example.com

View File

@@ -81,14 +81,14 @@ require (
package x
import _ "rsc.io/quote"
-- go.mod.crlf --
module m
go 1.14
require (
rsc.io/quote v1.5.2
rsc.io/testonly v1.0.0 // indirect
)
module m
go 1.14
require (
rsc.io/quote v1.5.2
rsc.io/testonly v1.0.0 // indirect
)
-- go.mod.unsorted --
module m
@@ -139,10 +139,10 @@ module m
go $goversion
require rsc.io/quote v1.5.2
require (
rsc.io/quote v1.5.2
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
rsc.io/sampler v1.3.0 // indirect
rsc.io/testonly v1.0.0 // indirect
)
require golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect

View File

@@ -72,10 +72,9 @@ go 1.17
replace example.net/indirect v0.1.0 => ./indirect
require (
example.net/ambiguous/nested v0.1.0 // indirect
example.net/indirect v0.1.0
)
require example.net/indirect v0.1.0
require example.net/ambiguous/nested v0.1.0 // indirect
-- all-m.txt --
example.com/m
example.net/ambiguous v0.1.0

View File

@@ -97,10 +97,9 @@ replace (
example.net/requireincompatible v0.1.0 => ./requireincompatible
)
require (
example.com/retract/incompatible v1.0.0 // indirect
example.net/lazy v0.1.0
)
require example.net/lazy v0.1.0
require example.com/retract/incompatible v1.0.0 // indirect
-- incompatible.go --
package incompatible

View File

@@ -2170,7 +2170,7 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
}
n++
if n > 20 {
if n > 1000 {
ctxt.Diag("span must be looping")
log.Fatalf("loop")
}

View File

@@ -389,9 +389,12 @@ func makeBogusLico() lico {
}
func makeLico(line, col uint) lico {
if line > lineMax {
if line >= lineMax {
// cannot represent line, use max. line so we have some information
line = lineMax
// Drop column information if line number saturates.
// Ensures line+col is monotonic. See issue 51193.
col = 0
}
if col > colMax {
// cannot represent column, use max. column so we have some information

View File

@@ -140,8 +140,8 @@ func TestLico(t *testing.T) {
{makeLico(1, 0), ":1", 1, 0},
{makeLico(1, 1), ":1:1", 1, 1},
{makeLico(2, 3), ":2:3", 2, 3},
{makeLico(lineMax, 1), fmt.Sprintf(":%d:1", lineMax), lineMax, 1},
{makeLico(lineMax+1, 1), fmt.Sprintf(":%d:1", lineMax), lineMax, 1}, // line too large, stick with max. line
{makeLico(lineMax, 1), fmt.Sprintf(":%d", lineMax), lineMax, 1},
{makeLico(lineMax+1, 1), fmt.Sprintf(":%d", lineMax), lineMax, 1}, // line too large, stick with max. line
{makeLico(1, colMax), ":1", 1, colMax},
{makeLico(1, colMax+1), ":1", 1, 0}, // column too large
{makeLico(lineMax+1, colMax+1), fmt.Sprintf(":%d", lineMax), lineMax, 0},
@@ -170,8 +170,8 @@ func TestIsStmt(t *testing.T) {
{makeLico(1, 1), ":1:1" + def, 1, 1},
{makeLico(1, 1).withIsStmt(), ":1:1" + is, 1, 1},
{makeLico(1, 1).withNotStmt(), ":1:1" + not, 1, 1},
{makeLico(lineMax, 1), fmt.Sprintf(":%d:1", lineMax) + def, lineMax, 1},
{makeLico(lineMax+1, 1), fmt.Sprintf(":%d:1", lineMax) + def, lineMax, 1}, // line too large, stick with max. line
{makeLico(lineMax, 1), fmt.Sprintf(":%d", lineMax) + def, lineMax, 1},
{makeLico(lineMax+1, 1), fmt.Sprintf(":%d", lineMax) + def, lineMax, 1}, // line too large, stick with max. line
{makeLico(1, colMax), ":1" + def, 1, colMax},
{makeLico(1, colMax+1), ":1" + def, 1, 0}, // column too large
{makeLico(lineMax+1, colMax+1), fmt.Sprintf(":%d", lineMax) + def, lineMax, 0},
@@ -214,9 +214,9 @@ func TestLogue(t *testing.T) {
{makeLico(1, 1).withXlogue(PosPrologueEnd), ":1:1" + defs + pro, 1, 1},
{makeLico(1, 1).withXlogue(PosEpilogueBegin), ":1:1" + defs + epi, 1, 1},
{makeLico(lineMax, 1).withXlogue(PosDefaultLogue), fmt.Sprintf(":%d:1", lineMax) + defs + defp, lineMax, 1},
{makeLico(lineMax, 1).withXlogue(PosPrologueEnd), fmt.Sprintf(":%d:1", lineMax) + defs + pro, lineMax, 1},
{makeLico(lineMax, 1).withXlogue(PosEpilogueBegin), fmt.Sprintf(":%d:1", lineMax) + defs + epi, lineMax, 1},
{makeLico(lineMax, 1).withXlogue(PosDefaultLogue), fmt.Sprintf(":%d", lineMax) + defs + defp, lineMax, 1},
{makeLico(lineMax, 1).withXlogue(PosPrologueEnd), fmt.Sprintf(":%d", lineMax) + defs + pro, lineMax, 1},
{makeLico(lineMax, 1).withXlogue(PosEpilogueBegin), fmt.Sprintf(":%d", lineMax) + defs + epi, lineMax, 1},
} {
x := test.x
if got := formatstr("", x.Line(), x.Col(), true) + fmt.Sprintf(":%d:%d", x.IsStmt(), x.Xlogue()); got != test.string {

View File

@@ -602,7 +602,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
rs := r.Xsym
rt := r.Type
if r.Xadd != signext21(r.Xadd) {
if rt == objabi.R_ADDRARM64 && r.Xadd != signext21(r.Xadd) {
// If the relocation target would overflow the addend, then target
// a linker-manufactured label symbol with a smaller addend instead.
label := ldr.Lookup(offsetLabelName(ldr, rs, r.Xadd/peRelocLimit*peRelocLimit), ldr.SymVersion(rs))

View File

@@ -2450,6 +2450,12 @@ func splitTextSections(ctxt *Link) bool {
return (ctxt.IsPPC64() || (ctxt.IsARM64() && ctxt.IsDarwin())) && ctxt.IsExternal()
}
// On Wasm, we reserve 4096 bytes for zero page, then 8192 bytes for wasm_exec.js
// to store command line args and environment variables.
// Data sections starts from at least address 12288.
// Keep in sync with wasm_exec.js.
const wasmMinDataAddr = 4096 + 8192
// address assigns virtual addresses to all segments and sections and
// returns all segments in file order.
func (ctxt *Link) address() []*sym.Segment {
@@ -2459,10 +2465,14 @@ func (ctxt *Link) address() []*sym.Segment {
order = append(order, &Segtext)
Segtext.Rwx = 05
Segtext.Vaddr = va
for _, s := range Segtext.Sections {
for i, s := range Segtext.Sections {
va = uint64(Rnd(int64(va), int64(s.Align)))
s.Vaddr = va
va += s.Length
if ctxt.IsWasm() && i == 0 && va < wasmMinDataAddr {
va = wasmMinDataAddr
}
}
Segtext.Length = va - uint64(*FlagTextAddr)

View File

@@ -132,7 +132,9 @@ func (d *deadcodePass) flood() {
methods = methods[:0]
for i := 0; i < relocs.Count(); i++ {
r := relocs.At(i)
if r.Weak() {
// When build with "-linkshared", we can't tell if the interface
// method in itab will be used or not. Ignore the weak attribute.
if r.Weak() && !(d.ctxt.linkShared && d.ldr.IsItab(symIdx)) {
continue
}
t := r.Type()
@@ -348,7 +350,7 @@ func deadcode(ctxt *Link) {
// in the last pass.
rem := d.markableMethods[:0]
for _, m := range d.markableMethods {
if (d.reflectSeen && m.isExported()) || d.ifaceMethod[m.m] {
if (d.reflectSeen && (m.isExported() || d.dynlink)) || d.ifaceMethod[m.m] {
d.markMethod(m)
} else {
rem = append(rem, m)

View File

@@ -16,6 +16,7 @@ import (
"fmt"
"internal/buildcfg"
"path/filepath"
"runtime"
"sort"
"strings"
)
@@ -1083,7 +1084,12 @@ func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
}
if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
sh.Type = uint32(elf.SHT_PROGBITS)
switch sect.Name {
case ".init_array":
sh.Type = uint32(elf.SHT_INIT_ARRAY)
default:
sh.Type = uint32(elf.SHT_PROGBITS)
}
} else {
sh.Type = uint32(elf.SHT_NOBITS)
}
@@ -1749,7 +1755,7 @@ func asmbElf(ctxt *Link) {
sh.Flags = uint64(elf.SHF_ALLOC)
sh.Addralign = 1
if interpreter == "" && buildcfg.GO_LDSO != "" {
if interpreter == "" && buildcfg.GOOS == runtime.GOOS && buildcfg.GOARCH == runtime.GOARCH && buildcfg.GO_LDSO != "" {
interpreter = buildcfg.GO_LDSO
}

View File

@@ -1267,7 +1267,10 @@ func (ctxt *Link) hostlink() {
if ctxt.DynlinkingGo() && buildcfg.GOOS != "ios" {
// -flat_namespace is deprecated on iOS.
// It is useful for supporting plugins. We don't support plugins on iOS.
argv = append(argv, "-Wl,-flat_namespace")
// -flat_namespace may cause the dynamic linker to hang at forkExec when
// resolving a lazy binding. See issue 38824.
// Force eager resolution to work around.
argv = append(argv, "-Wl,-flat_namespace", "-Wl,-bind_at_load")
}
if !combineDwarf {
argv = append(argv, "-Wl,-S") // suppress STAB (symbolic debugging) symbols

View File

@@ -993,13 +993,31 @@ package main
var x = [1<<25]byte{1<<23: 23, 1<<24: 24}
var addr = [...]*byte{
&x[1<<23-1],
&x[1<<23],
&x[1<<23+1],
&x[1<<24-1],
&x[1<<24],
&x[1<<24+1],
}
func main() {
// check relocations in instructions
check(x[1<<23-1], 0)
check(x[1<<23], 23)
check(x[1<<23+1], 0)
check(x[1<<24-1], 0)
check(x[1<<24], 24)
check(x[1<<24+1], 0)
// check absolute address relocations in data
check(*addr[0], 0)
check(*addr[1], 23)
check(*addr[2], 0)
check(*addr[3], 0)
check(*addr[4], 24)
check(*addr[5], 0)
}
func check(x, y byte) {

View File

@@ -106,6 +106,9 @@ var ppcGnuNeed = []string{
}
func mustHaveDisasm(t *testing.T) {
if strings.HasPrefix(testenv.Builder(), "darwin-arm64") {
t.Skipf("builder %q has an incompatible version of XCode installed, see go.dev/issue/49700", testenv.Builder())
}
switch runtime.GOARCH {
case "mips", "mipsle", "mips64", "mips64le":
t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)

View File

@@ -956,170 +956,217 @@ func (f *File) SetRequire(req []*Require) {
// SetRequireSeparateIndirect updates the requirements of f to contain the given
// requirements. Comment contents (except for 'indirect' markings) are retained
// from the first existing requirement for each module path, and block structure
// is maintained as long as the indirect markings match.
// from the first existing requirement for each module path. Like SetRequire,
// SetRequireSeparateIndirect adds requirements for new paths in req,
// updates the version and "// indirect" comment on existing requirements,
// and deletes requirements on paths not in req. Existing duplicate requirements
// are deleted.
//
// Any requirements on paths not already present in the file are added. Direct
// requirements are added to the last block containing *any* other direct
// requirement. Indirect requirements are added to the last block containing
// *only* other indirect requirements. If no suitable block exists, a new one is
// added, with the last block containing a direct dependency (if any)
// immediately before the first block containing only indirect dependencies.
// As its name suggests, SetRequireSeparateIndirect puts direct and indirect
// requirements into two separate blocks, one containing only direct
// requirements, and the other containing only indirect requirements.
// SetRequireSeparateIndirect may move requirements between these two blocks
// when their indirect markings change. However, SetRequireSeparateIndirect
// won't move requirements from other blocks, especially blocks with comments.
//
// The Syntax field is ignored for requirements in the given blocks.
// If the file initially has one uncommented block of requirements,
// SetRequireSeparateIndirect will split it into a direct-only and indirect-only
// block. This aids in the transition to separate blocks.
func (f *File) SetRequireSeparateIndirect(req []*Require) {
type modKey struct {
path string
indirect bool
}
need := make(map[modKey]string)
for _, r := range req {
need[modKey{r.Mod.Path, r.Indirect}] = r.Mod.Version
// hasComments returns whether a line or block has comments
// other than "indirect".
hasComments := func(c Comments) bool {
return len(c.Before) > 0 || len(c.After) > 0 || len(c.Suffix) > 1 ||
(len(c.Suffix) == 1 &&
strings.TrimSpace(strings.TrimPrefix(c.Suffix[0].Token, string(slashSlash))) != "indirect")
}
comments := make(map[string]Comments)
for _, r := range f.Require {
v, ok := need[modKey{r.Mod.Path, r.Indirect}]
if !ok {
if _, ok := need[modKey{r.Mod.Path, !r.Indirect}]; ok {
if _, dup := comments[r.Mod.Path]; !dup {
comments[r.Mod.Path] = r.Syntax.Comments
}
// moveReq adds r to block. If r was in another block, moveReq deletes
// it from that block and transfers its comments.
moveReq := func(r *Require, block *LineBlock) {
var line *Line
if r.Syntax == nil {
line = &Line{Token: []string{AutoQuote(r.Mod.Path), r.Mod.Version}}
r.Syntax = line
if r.Indirect {
r.setIndirect(true)
}
r.markRemoved()
continue
} else {
line = new(Line)
*line = *r.Syntax
if !line.InBlock && len(line.Token) > 0 && line.Token[0] == "require" {
line.Token = line.Token[1:]
}
r.Syntax.Token = nil // Cleanup will delete the old line.
r.Syntax = line
}
r.setVersion(v)
delete(need, modKey{r.Mod.Path, r.Indirect})
line.InBlock = true
block.Line = append(block.Line, line)
}
// Examine existing require lines and blocks.
var (
lastDirectOrMixedBlock Expr
firstIndirectOnlyBlock Expr
lastIndirectOnlyBlock Expr
// We may insert new requirements into the last uncommented
// direct-only and indirect-only blocks. We may also move requirements
// to the opposite block if their indirect markings change.
lastDirectIndex = -1
lastIndirectIndex = -1
// If there are no direct-only or indirect-only blocks, a new block may
// be inserted after the last require line or block.
lastRequireIndex = -1
// If there's only one require line or block, and it's uncommented,
// we'll move its requirements to the direct-only or indirect-only blocks.
requireLineOrBlockCount = 0
// Track the block each requirement belongs to (if any) so we can
// move them later.
lineToBlock = make(map[*Line]*LineBlock)
)
for _, stmt := range f.Syntax.Stmt {
for i, stmt := range f.Syntax.Stmt {
switch stmt := stmt.(type) {
case *Line:
if len(stmt.Token) == 0 || stmt.Token[0] != "require" {
continue
}
if isIndirect(stmt) {
lastIndirectOnlyBlock = stmt
} else {
lastDirectOrMixedBlock = stmt
lastRequireIndex = i
requireLineOrBlockCount++
if !hasComments(stmt.Comments) {
if isIndirect(stmt) {
lastIndirectIndex = i
} else {
lastDirectIndex = i
}
}
case *LineBlock:
if len(stmt.Token) == 0 || stmt.Token[0] != "require" {
continue
}
indirectOnly := true
lastRequireIndex = i
requireLineOrBlockCount++
allDirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments)
allIndirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments)
for _, line := range stmt.Line {
if len(line.Token) == 0 {
continue
}
if !isIndirect(line) {
indirectOnly = false
break
}
}
if indirectOnly {
lastIndirectOnlyBlock = stmt
if firstIndirectOnlyBlock == nil {
firstIndirectOnlyBlock = stmt
}
} else {
lastDirectOrMixedBlock = stmt
}
}
}
isOrContainsStmt := func(stmt Expr, target Expr) bool {
if stmt == target {
return true
}
if stmt, ok := stmt.(*LineBlock); ok {
if target, ok := target.(*Line); ok {
for _, line := range stmt.Line {
if line == target {
return true
}
}
}
}
return false
}
addRequire := func(path, vers string, indirect bool, comments Comments) {
var line *Line
if indirect {
if lastIndirectOnlyBlock != nil {
line = f.Syntax.addLine(lastIndirectOnlyBlock, "require", path, vers)
} else {
// Add a new require block after the last direct-only or mixed "require"
// block (if any).
//
// (f.Syntax.addLine would add the line to an existing "require" block if
// present, but here the existing "require" blocks are all direct-only, so
// we know we need to add a new block instead.)
line = &Line{Token: []string{"require", path, vers}}
lastIndirectOnlyBlock = line
firstIndirectOnlyBlock = line // only block implies first block
if lastDirectOrMixedBlock == nil {
f.Syntax.Stmt = append(f.Syntax.Stmt, line)
lineToBlock[line] = stmt
if hasComments(line.Comments) {
allDirect = false
allIndirect = false
} else if isIndirect(line) {
allDirect = false
} else {
for i, stmt := range f.Syntax.Stmt {
if isOrContainsStmt(stmt, lastDirectOrMixedBlock) {
f.Syntax.Stmt = append(f.Syntax.Stmt, nil) // increase size
copy(f.Syntax.Stmt[i+2:], f.Syntax.Stmt[i+1:]) // shuffle elements up
f.Syntax.Stmt[i+1] = line
break
}
}
allIndirect = false
}
}
if allDirect {
lastDirectIndex = i
}
if allIndirect {
lastIndirectIndex = i
}
}
}
oneFlatUncommentedBlock := requireLineOrBlockCount == 1 &&
!hasComments(*f.Syntax.Stmt[lastRequireIndex].Comment())
// Create direct and indirect blocks if needed. Convert lines into blocks
// if needed. If we end up with an empty block or a one-line block,
// Cleanup will delete it or convert it to a line later.
insertBlock := func(i int) *LineBlock {
block := &LineBlock{Token: []string{"require"}}
f.Syntax.Stmt = append(f.Syntax.Stmt, nil)
copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:])
f.Syntax.Stmt[i] = block
return block
}
ensureBlock := func(i int) *LineBlock {
switch stmt := f.Syntax.Stmt[i].(type) {
case *LineBlock:
return stmt
case *Line:
block := &LineBlock{
Token: []string{"require"},
Line: []*Line{stmt},
}
stmt.Token = stmt.Token[1:] // remove "require"
stmt.InBlock = true
f.Syntax.Stmt[i] = block
return block
default:
panic(fmt.Sprintf("unexpected statement: %v", stmt))
}
}
var lastDirectBlock *LineBlock
if lastDirectIndex < 0 {
if lastIndirectIndex >= 0 {
lastDirectIndex = lastIndirectIndex
lastIndirectIndex++
} else if lastRequireIndex >= 0 {
lastDirectIndex = lastRequireIndex + 1
} else {
if lastDirectOrMixedBlock != nil {
line = f.Syntax.addLine(lastDirectOrMixedBlock, "require", path, vers)
lastDirectIndex = len(f.Syntax.Stmt)
}
lastDirectBlock = insertBlock(lastDirectIndex)
} else {
lastDirectBlock = ensureBlock(lastDirectIndex)
}
var lastIndirectBlock *LineBlock
if lastIndirectIndex < 0 {
lastIndirectIndex = lastDirectIndex + 1
lastIndirectBlock = insertBlock(lastIndirectIndex)
} else {
lastIndirectBlock = ensureBlock(lastIndirectIndex)
}
// Delete requirements we don't want anymore.
// Update versions and indirect comments on requirements we want to keep.
// If a requirement is in last{Direct,Indirect}Block with the wrong
// indirect marking after this, or if the requirement is in an single
// uncommented mixed block (oneFlatUncommentedBlock), move it to the
// correct block.
//
// Some blocks may be empty after this. Cleanup will remove them.
need := make(map[string]*Require)
for _, r := range req {
need[r.Mod.Path] = r
}
have := make(map[string]*Require)
for _, r := range f.Require {
path := r.Mod.Path
if need[path] == nil || have[path] != nil {
// Requirement not needed, or duplicate requirement. Delete.
r.markRemoved()
continue
}
have[r.Mod.Path] = r
r.setVersion(need[path].Mod.Version)
r.setIndirect(need[path].Indirect)
if need[path].Indirect &&
(oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastDirectBlock) {
moveReq(r, lastIndirectBlock)
} else if !need[path].Indirect &&
(oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastIndirectBlock) {
moveReq(r, lastDirectBlock)
}
}
// Add new requirements.
for path, r := range need {
if have[path] == nil {
if r.Indirect {
moveReq(r, lastIndirectBlock)
} else {
// Add a new require block before the first indirect block (if any).
//
// That way if the file initially contains only indirect lines,
// the direct lines still appear before it: we preserve existing
// structure, but only to the extent that that structure already
// reflects the direct/indirect split.
line = &Line{Token: []string{"require", path, vers}}
lastDirectOrMixedBlock = line
if firstIndirectOnlyBlock == nil {
f.Syntax.Stmt = append(f.Syntax.Stmt, line)
} else {
for i, stmt := range f.Syntax.Stmt {
if isOrContainsStmt(stmt, firstIndirectOnlyBlock) {
f.Syntax.Stmt = append(f.Syntax.Stmt, nil) // increase size
copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:]) // shuffle elements up
f.Syntax.Stmt[i] = line
break
}
}
}
moveReq(r, lastDirectBlock)
}
f.Require = append(f.Require, r)
}
line.Comments.Before = commentsAdd(line.Comments.Before, comments.Before)
line.Comments.Suffix = commentsAdd(line.Comments.Suffix, comments.Suffix)
r := &Require{
Mod: module.Version{Path: path, Version: vers},
Indirect: indirect,
Syntax: line,
}
r.setIndirect(indirect)
f.Require = append(f.Require, r)
}
for k, vers := range need {
addRequire(k.path, vers, k.indirect, comments[k.path])
}
f.SortBlocks()
}

View File

@@ -24,11 +24,11 @@ golang.org/x/arch/arm/armasm
golang.org/x/arch/arm64/arm64asm
golang.org/x/arch/ppc64/ppc64asm
golang.org/x/arch/x86/x86asm
# golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e
# golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
## explicit; go 1.17
golang.org/x/crypto/ed25519
golang.org/x/crypto/ed25519/internal/edwards25519
# golang.org/x/mod v0.4.3-0.20210608190319-0f08993efd8a
# golang.org/x/mod v0.5.1
## explicit; go 1.17
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/modfile

View File

@@ -86,6 +86,11 @@ func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
return specific.IsOnCurve(x, y)
}
if x.Sign() < 0 || x.Cmp(curve.P) >= 0 ||
y.Sign() < 0 || y.Cmp(curve.P) >= 0 {
return false
}
// y² = x³ - 3x + b
y2 := new(big.Int).Mul(y, y)
y2.Mod(y2, curve.P)

View File

@@ -174,6 +174,61 @@ func testUnmarshalToLargeCoordinates(t *testing.T, curve Curve) {
}
}
// TestInvalidCoordinates tests big.Int values that are not valid field elements
// (negative or bigger than P). They are expected to return false from
// IsOnCurve, all other behavior is undefined.
func TestInvalidCoordinates(t *testing.T) {
testAllCurves(t, testInvalidCoordinates)
}
func testInvalidCoordinates(t *testing.T, curve Curve) {
checkIsOnCurveFalse := func(name string, x, y *big.Int) {
if curve.IsOnCurve(x, y) {
t.Errorf("IsOnCurve(%s) unexpectedly returned true", name)
}
}
p := curve.Params().P
_, x, y, _ := GenerateKey(curve, rand.Reader)
xx, yy := new(big.Int), new(big.Int)
// Check if the sign is getting dropped.
xx.Neg(x)
checkIsOnCurveFalse("-x, y", xx, y)
yy.Neg(y)
checkIsOnCurveFalse("x, -y", x, yy)
// Check if negative values are reduced modulo P.
xx.Sub(x, p)
checkIsOnCurveFalse("x-P, y", xx, y)
yy.Sub(y, p)
checkIsOnCurveFalse("x, y-P", x, yy)
// Check if positive values are reduced modulo P.
xx.Add(x, p)
checkIsOnCurveFalse("x+P, y", xx, y)
yy.Add(y, p)
checkIsOnCurveFalse("x, y+P", x, yy)
// Check if the overflow is dropped.
xx.Add(x, new(big.Int).Lsh(big.NewInt(1), 535))
checkIsOnCurveFalse("x+2⁵³⁵, y", xx, y)
yy.Add(y, new(big.Int).Lsh(big.NewInt(1), 535))
checkIsOnCurveFalse("x, y+2⁵³⁵", x, yy)
// Check if P is treated like zero (if possible).
// y^2 = x^3 - 3x + B
// y = mod_sqrt(x^3 - 3x + B)
// y = mod_sqrt(B) if x = 0
// If there is no modsqrt, there is no point with x = 0, can't test x = P.
if yy := new(big.Int).ModSqrt(curve.Params().B, p); yy != nil {
if !curve.IsOnCurve(big.NewInt(0), yy) {
t.Fatal("(0, mod_sqrt(B)) is not on the curve?")
}
checkIsOnCurveFalse("P, y", p, yy)
}
}
func TestMarshalCompressed(t *testing.T) {
t.Run("P-256/03", func(t *testing.T) {
data, _ := hex.DecodeString("031e3987d9f9ea9d7dd7155a56a86b2009e1e0ab332f962d10d8beb6406ab1ad79")

View File

@@ -48,6 +48,11 @@ func (curve p224Curve) Params() *CurveParams {
}
func (curve p224Curve) IsOnCurve(bigX, bigY *big.Int) bool {
if bigX.Sign() < 0 || bigX.Cmp(curve.P) >= 0 ||
bigY.Sign() < 0 || bigY.Cmp(curve.P) >= 0 {
return false
}
var x, y p224FieldElement
p224FromBig(&x, bigX)
p224FromBig(&y, bigY)

View File

@@ -52,7 +52,7 @@ func p256GetScalar(out *[32]byte, in []byte) {
n := new(big.Int).SetBytes(in)
var scalarBytes []byte
if n.Cmp(p256Params.N) >= 0 {
if n.Cmp(p256Params.N) >= 0 || len(in) > len(out) {
n.Mod(n, p256Params.N)
scalarBytes = n.Bytes()
} else {

View File

@@ -153,3 +153,17 @@ func TestP256CombinedMult(t *testing.T) {
t.Errorf("1×G + (-1)×G = (%d, %d), should be ∞", x, y)
}
}
func TestIssue52075(t *testing.T) {
Gx, Gy := P256().Params().Gx, P256().Params().Gy
scalar := make([]byte, 33)
scalar[32] = 1
x, y := P256().ScalarBaseMult(scalar)
if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
t.Errorf("unexpected output (%v,%v)", x, y)
}
x, y = P256().ScalarMult(Gx, Gy, scalar)
if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
t.Errorf("unexpected output (%v,%v)", x, y)
}
}

View File

@@ -32,6 +32,11 @@ func (curve p521Curve) Params() *CurveParams {
}
func (curve p521Curve) IsOnCurve(x, y *big.Int) bool {
if x.Sign() < 0 || x.Cmp(curve.P) >= 0 ||
y.Sign() < 0 || y.Cmp(curve.P) >= 0 {
return false
}
x1 := bigIntToFiatP521(x)
y1 := bigIntToFiatP521(y)
b := bigIntToFiatP521(curve.B) // TODO: precompute this value.

View File

@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin || openbsd
// +build darwin openbsd
//go:build (darwin && !ios) || openbsd
// +build darwin,!ios openbsd
package rand

View File

@@ -51,9 +51,9 @@ func isPrintable(b byte) bool {
}
// parseASN1String parses the ASN.1 string types T61String, PrintableString,
// UTF8String, BMPString, and IA5String. This is mostly copied from the
// respective encoding/asn1.parse... methods, rather than just increasing
// the API surface of that package.
// UTF8String, BMPString, IA5String, and NumericString. This is mostly copied
// from the respective encoding/asn1.parse... methods, rather than just
// increasing the API surface of that package.
func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
switch tag {
case cryptobyte_asn1.T61String:
@@ -93,6 +93,13 @@ func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
return "", errors.New("invalid IA5String")
}
return s, nil
case cryptobyte_asn1.Tag(asn1.TagNumericString):
for _, b := range value {
if !('0' <= b && b <= '9' || b == ' ') {
return "", errors.New("invalid NumericString")
}
}
return string(value), nil
}
return "", fmt.Errorf("unsupported string type: %v", tag)
}
@@ -934,10 +941,10 @@ func parseCertificate(der []byte) (*Certificate, error) {
}
if cert.Version > 1 {
if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).Constructed().ContextSpecific()) {
if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
return nil, errors.New("x509: malformed issuerUniqueID")
}
if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).Constructed().ContextSpecific()) {
if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).ContextSpecific()) {
return nil, errors.New("x509: malformed subjectUniqueID")
}
if cert.Version == 3 {

View File

@@ -0,0 +1,102 @@
// Copyright 2021 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 x509
import (
"encoding/asn1"
"testing"
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
)
func TestParseASN1String(t *testing.T) {
tests := []struct {
name string
tag cryptobyte_asn1.Tag
value []byte
expected string
expectedErr string
}{
{
name: "T61String",
tag: cryptobyte_asn1.T61String,
value: []byte{80, 81, 82},
expected: string("PQR"),
},
{
name: "PrintableString",
tag: cryptobyte_asn1.PrintableString,
value: []byte{80, 81, 82},
expected: string("PQR"),
},
{
name: "PrintableString (invalid)",
tag: cryptobyte_asn1.PrintableString,
value: []byte{1, 2, 3},
expectedErr: "invalid PrintableString",
},
{
name: "UTF8String",
tag: cryptobyte_asn1.UTF8String,
value: []byte{80, 81, 82},
expected: string("PQR"),
},
{
name: "UTF8String (invalid)",
tag: cryptobyte_asn1.UTF8String,
value: []byte{255},
expectedErr: "invalid UTF-8 string",
},
{
name: "BMPString",
tag: cryptobyte_asn1.Tag(asn1.TagBMPString),
value: []byte{80, 81},
expected: string("偑"),
},
{
name: "BMPString (invalid length)",
tag: cryptobyte_asn1.Tag(asn1.TagBMPString),
value: []byte{255},
expectedErr: "invalid BMPString",
},
{
name: "IA5String",
tag: cryptobyte_asn1.IA5String,
value: []byte{80, 81},
expected: string("PQ"),
},
{
name: "IA5String (invalid)",
tag: cryptobyte_asn1.IA5String,
value: []byte{255},
expectedErr: "invalid IA5String",
},
{
name: "NumericString",
tag: cryptobyte_asn1.Tag(asn1.TagNumericString),
value: []byte{49, 50},
expected: string("12"),
},
{
name: "NumericString (invalid)",
tag: cryptobyte_asn1.Tag(asn1.TagNumericString),
value: []byte{80},
expectedErr: "invalid NumericString",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
out, err := parseASN1String(tc.tag, tc.value)
if err != nil && err.Error() != tc.expectedErr {
t.Fatalf("parseASN1String returned unexpected error: got %q, want %q", err, tc.expectedErr)
} else if err == nil && tc.expectedErr != "" {
t.Fatalf("parseASN1String didn't fail, expected: %s", tc.expectedErr)
}
if out != tc.expected {
t.Fatalf("parseASN1String returned unexpected value: got %q, want %q", out, tc.expected)
}
})
}
}

View File

@@ -3216,3 +3216,146 @@ func TestAuthKeyIdOptional(t *testing.T) {
t.Fatalf("ParseCertificate to failed to parse certificate with optional authority key identifier fields: %s", err)
}
}
const largeOIDPEM = `
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
da:ba:53:19:1b:09:4b:82:b2:89:26:7d:c7:6f:a0:02
Signature Algorithm: sha256WithRSAEncryption
Issuer: O = Acme Co
Validity
Not Before: Dec 21 16:59:27 2021 GMT
Not After : Dec 21 16:59:27 2022 GMT
Subject: O = Acme Co
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:bf:17:16:d8:bc:29:9c:16:e5:76:b4:93:15:78:
ad:6e:45:c5:4a:63:46:a1:b2:76:71:65:51:9c:14:
c4:ea:74:13:e4:34:df:2f:2c:65:11:e8:56:52:69:
11:f9:0e:fc:77:bb:63:a8:7c:1a:c6:a1:7b:6e:6c:
e7:18:25:25:c9:e8:fb:06:7f:a2:a9:98:fe:2a:bc:
8a:b3:75:b6:b8:7d:b6:c9:6b:29:08:32:22:10:cb:
8d:d6:60:c8:83:ad:f5:58:91:d6:11:e8:55:56:fb:
8f:a3:a2:9f:48:cb:79:e4:65:4a:8c:a6:52:64:9f:
99:38:35:d4:d5:ac:6f:cf:a0:cb:42:8c:07:eb:21:
17:31:3a:eb:91:7b:62:43:a4:75:5f:ef:a7:2f:94:
f8:69:0b:d4:ec:09:e6:00:c0:8c:dd:07:63:0b:e4:
77:aa:60:18:3c:a0:e0:ae:0a:ea:0e:52:3b:b4:fa:
6a:30:1b:50:62:21:73:53:33:01:60:a1:6b:99:58:
00:f3:77:c6:0f:46:19:ca:c2:5d:cd:f5:e2:52:4d:
84:94:23:d3:32:2f:ae:5f:da:43:a1:19:95:d2:17:
dd:49:14:b4:d9:48:1c:08:13:93:8e:d5:09:43:21:
b6:ce:52:e8:87:bb:d2:60:0d:c6:4e:bf:c5:93:6a:
c6:bf
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Alternative Name:
DNS:longOID.example
X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.311.21.8.1492336001
Signature Algorithm: sha256WithRSAEncryption
72:77:8b:de:48:fb:6d:9a:94:b1:be:d4:90:7d:4c:e6:d3:79:
fa:fb:fc:3e:d5:3d:e9:a0:ce:28:2b:2f:94:77:3f:87:f8:9c:
9f:91:1c:f3:f6:58:91:15:6b:24:b9:ca:ae:9f:ee:ca:c8:31:
db:1a:3d:bb:6b:83:6d:bc:81:8b:a1:79:d5:3e:bb:dd:93:fe:
35:3e:b7:99:e0:d6:eb:58:0c:fd:42:73:dc:49:da:e2:b7:ae:
15:ee:e6:cc:aa:ef:91:41:9a:18:46:8d:4a:39:65:a2:85:3c:
7f:0c:41:f8:0b:9c:e8:1f:35:36:60:8d:8c:e0:8e:18:b1:06:
57:d0:4e:c4:c3:cd:8f:6f:e7:76:02:52:da:03:43:61:2b:b3:
bf:19:fd:73:0d:6a:0b:b4:b6:cb:a9:6f:70:4e:53:2a:54:07:
b3:74:fd:85:49:57:5b:23:8d:8c:6b:53:2b:09:e8:41:a5:80:
3f:69:1b:11:d1:6b:13:35:2e:f9:d6:50:15:d9:91:38:42:43:
e9:17:af:67:d9:96:a4:d1:6a:4f:cc:b4:a7:8e:48:1f:00:72:
69:de:4d:f1:73:a4:47:12:67:e9:f9:07:3e:79:75:90:42:b8:
d4:b5:fd:d1:7e:35:04:f7:00:04:cf:f1:36:be:0f:27:81:1f:
a6:ba:88:6c
-----BEGIN CERTIFICATE-----
MIIDHTCCAgWgAwIBAgIRANq6UxkbCUuCsokmfcdvoAIwDQYJKoZIhvcNAQELBQAw
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0yMTEyMjExNjU5MjdaFw0yMjEyMjExNjU5
MjdaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQC/FxbYvCmcFuV2tJMVeK1uRcVKY0ahsnZxZVGcFMTqdBPkNN8vLGUR
6FZSaRH5Dvx3u2OofBrGoXtubOcYJSXJ6PsGf6KpmP4qvIqzdba4fbbJaykIMiIQ
y43WYMiDrfVYkdYR6FVW+4+jop9Iy3nkZUqMplJkn5k4NdTVrG/PoMtCjAfrIRcx
OuuRe2JDpHVf76cvlPhpC9TsCeYAwIzdB2ML5HeqYBg8oOCuCuoOUju0+mowG1Bi
IXNTMwFgoWuZWADzd8YPRhnKwl3N9eJSTYSUI9MyL65f2kOhGZXSF91JFLTZSBwI
E5OO1QlDIbbOUuiHu9JgDcZOv8WTasa/AgMBAAGjbjBsMA4GA1UdDwEB/wQEAwIF
oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGC
D2xvbmdPSUQuZXhhbXBsZTAbBgNVHSAEFDASMBAGDisGAQQBgjcVCIXHzPsBMA0G
CSqGSIb3DQEBCwUAA4IBAQByd4veSPttmpSxvtSQfUzm03n6+/w+1T3poM4oKy+U
dz+H+JyfkRzz9liRFWskucqun+7KyDHbGj27a4NtvIGLoXnVPrvdk/41PreZ4Nbr
WAz9QnPcSdrit64V7ubMqu+RQZoYRo1KOWWihTx/DEH4C5zoHzU2YI2M4I4YsQZX
0E7Ew82Pb+d2AlLaA0NhK7O/Gf1zDWoLtLbLqW9wTlMqVAezdP2FSVdbI42Ma1Mr
CehBpYA/aRsR0WsTNS751lAV2ZE4QkPpF69n2Zak0WpPzLSnjkgfAHJp3k3xc6RH
Emfp+Qc+eXWQQrjUtf3RfjUE9wAEz/E2vg8ngR+muohs
-----END CERTIFICATE-----`
func TestLargeOID(t *testing.T) {
// See Issue 49678.
b, _ := pem.Decode([]byte(largeOIDPEM))
if b == nil {
t.Fatalf("couldn't decode test certificate")
}
_, err := ParseCertificate(b.Bytes)
if err != nil {
t.Fatalf("ParseCertificate to failed to parse certificate with large OID: %s", err)
}
}
const uniqueIDPEM = `-----BEGIN CERTIFICATE-----
MIIFsDCCBJigAwIBAgIIrOyC1ydafZMwDQYJKoZIhvcNAQEFBQAwgY4xgYswgYgG
A1UEAx6BgABNAGkAYwByAG8AcwBvAGYAdAAgAEYAbwByAGUAZgByAG8AbgB0ACAA
VABNAEcAIABIAFQAVABQAFMAIABJAG4AcwBwAGUAYwB0AGkAbwBuACAAQwBlAHIA
dABpAGYAaQBjAGEAdABpAG8AbgAgAEEAdQB0AGgAbwByAGkAdAB5MB4XDTE0MDEx
ODAwNDEwMFoXDTE1MTExNTA5Mzc1NlowgZYxCzAJBgNVBAYTAklEMRAwDgYDVQQI
EwdqYWthcnRhMRIwEAYDVQQHEwlJbmRvbmVzaWExHDAaBgNVBAoTE3N0aG9ub3Jl
aG90ZWxyZXNvcnQxHDAaBgNVBAsTE3N0aG9ub3JlaG90ZWxyZXNvcnQxJTAjBgNV
BAMTHG1haWwuc3Rob25vcmVob3RlbHJlc29ydC5jb20wggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCvuu0qpI+Ko2X84Twkf84cRD/rgp6vpgc5Ebejx/D4
PEVON5edZkazrMGocK/oQqIlRxx/lefponN/chlGcllcVVPWTuFjs8k+Aat6T1qp
4iXxZekAqX+U4XZMIGJD3PckPL6G2RQSlF7/LhGCsRNRdKpMWSTbou2Ma39g52Kf
gsl3SK/GwLiWpxpcSkNQD1hugguEIsQYLxbeNwpcheXZtxbBGguPzQ7rH8c5vuKU
BkMOzaiNKLzHbBdFSrua8KWwCJg76Vdq/q36O9GlW6YgG3i+A4pCJjXWerI1lWwX
Ktk5V+SvUHGey1bkDuZKJ6myMk2pGrrPWCT7jP7WskChAgMBAAGBCQBCr1dgEleo
cKOCAfswggH3MIHDBgNVHREEgbswgbiCHG1haWwuc3Rob25vcmVob3RlbHJlc29y
dC5jb22CIGFzaGNoc3ZyLnN0aG9ub3JlaG90ZWxyZXNvcnQuY29tgiRBdXRvRGlz
Y292ZXIuc3Rob25vcmVob3RlbHJlc29ydC5jb22CHEF1dG9EaXNjb3Zlci5ob3Rl
bHJlc29ydC5jb22CCEFTSENIU1ZSghdzdGhvbm9yZWhvdGVscmVzb3J0LmNvbYIP
aG90ZWxyZXNvcnQuY29tMCEGCSsGAQQBgjcUAgQUHhIAVwBlAGIAUwBlAHIAdgBl
AHIwHQYDVR0OBBYEFMAC3UR4FwAdGekbhMgnd6lMejtbMAsGA1UdDwQEAwIFoDAT
BgNVHSUEDDAKBggrBgEFBQcDATAJBgNVHRMEAjAAMIG/BgNVHQEEgbcwgbSAFGfF
6xihk+gJJ5TfwvtWe1UFnHLQoYGRMIGOMYGLMIGIBgNVBAMegYAATQBpAGMAcgBv
AHMAbwBmAHQAIABGAG8AcgBlAGYAcgBvAG4AdAAgAFQATQBHACAASABUAFQAUABT
ACAASQBuAHMAcABlAGMAdABpAG8AbgAgAEMAZQByAHQAaQBmAGkAYwBhAHQAaQBv
AG4AIABBAHUAdABoAG8AcgBpAHQAeYIIcKhXEmBXr0IwDQYJKoZIhvcNAQEFBQAD
ggEBABlSxyCMr3+ANr+WmPSjyN5YCJBgnS0IFCwJAzIYP87bcTye/U8eQ2+E6PqG
Q7Huj7nfHEw9qnGo+HNyPp1ad3KORzXDb54c6xEoi+DeuPzYHPbn4c3hlH49I0aQ
eWW2w4RslSWpLvO6Y7Lboyz2/Thk/s2kd4RHxkkWpH2ltPqJuYYg3X6oM5+gIFHJ
WGnh+ojZ5clKvS5yXh3Wkj78M6sb32KfcBk0Hx6NkCYPt60ODYmWtvqwtw6r73u5
TnTYWRNvo2svX69TriL+CkHY9O1Hkwf2It5zHl3gNiKTJVaak8AuEz/CKWZneovt
yYLwhUhg3PX5Co1VKYE+9TxloiE=
-----END CERTIFICATE-----`
func TestParseUniqueID(t *testing.T) {
b, _ := pem.Decode([]byte(uniqueIDPEM))
if b == nil {
t.Fatalf("couldn't decode test certificate")
}
cert, err := ParseCertificate(b.Bytes)
if err != nil {
t.Fatalf("ParseCertificate to failed to parse certificate with unique identifier id: %s", err)
}
if len(cert.Extensions) != 7 {
t.Fatalf("unexpected number of extensions (probably because the extension section was not parsed): got %d, want 7", len(cert.Extensions))
}
}

View File

@@ -345,6 +345,15 @@ func NewFile(r io.ReaderAt) (*File, error) {
if err := binary.Read(b, bo, &hdr); err != nil {
return nil, err
}
if hdr.Iundefsym > uint32(len(f.Symtab.Syms)) {
return nil, &FormatError{offset, fmt.Sprintf(
"undefined symbols index in dynamic symbol table command is greater than symbol table length (%d > %d)",
hdr.Iundefsym, len(f.Symtab.Syms)), nil}
} else if hdr.Iundefsym+hdr.Nundefsym > uint32(len(f.Symtab.Syms)) {
return nil, &FormatError{offset, fmt.Sprintf(
"number of undefined symbols after index in dynamic symbol table command is greater than symbol table length (%d > %d)",
hdr.Iundefsym+hdr.Nundefsym, len(f.Symtab.Syms)), nil}
}
dat := make([]byte, hdr.Nindirectsyms*4)
if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
return nil, err
@@ -641,10 +650,14 @@ func (f *File) DWARF() (*dwarf.Data, error) {
return nil, err
}
// Look for DWARF4 .debug_types sections.
// Look for DWARF4 .debug_types sections and DWARF5 sections.
for i, s := range f.Sections {
suffix := dwarfSuffix(s)
if suffix != "types" {
if suffix == "" {
continue
}
if _, ok := dat[suffix]; ok {
// Already handled.
continue
}
@@ -653,7 +666,11 @@ func (f *File) DWARF() (*dwarf.Data, error) {
return nil, err
}
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
if suffix == "types" {
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
} else {
err = d.AddSection(".debug_"+suffix, b)
}
if err != nil {
return nil, err
}

View File

@@ -416,3 +416,10 @@ func TestTypeString(t *testing.T) {
t.Errorf("got %v, want %v", TypeExec.GoString(), "macho.Exec")
}
}
func TestOpenBadDysymCmd(t *testing.T) {
_, err := openObscured("testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64")
if err == nil {
t.Fatal("openObscured did not fail when opening a file with an invalid dynamic symbol table command")
}
}

File diff suppressed because one or more lines are too long

View File

@@ -272,10 +272,14 @@ func (f *File) DWARF() (*dwarf.Data, error) {
return nil, err
}
// Look for DWARF4 .debug_types sections.
// Look for DWARF4 .debug_types sections and DWARF5 sections.
for i, s := range f.Sections {
suffix := dwarfSuffix(s)
if suffix != "types" {
if suffix == "" {
continue
}
if _, ok := dat[suffix]; ok {
// Already handled.
continue
}
@@ -284,7 +288,11 @@ func (f *File) DWARF() (*dwarf.Data, error) {
return nil, err
}
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
if suffix == "types" {
err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
} else {
err = d.AddSection(".debug_"+suffix, b)
}
if err != nil {
return nil, err
}

View File

@@ -129,3 +129,43 @@ func TestUninitialized(t *testing.T) {
t.Errorf("in uninitialized embed.FS, . is not a directory")
}
}
var (
//go:embed "testdata/hello.txt"
helloT []T
//go:embed "testdata/hello.txt"
helloUint8 []uint8
//go:embed "testdata/hello.txt"
helloEUint8 []EmbedUint8
//go:embed "testdata/hello.txt"
helloBytes EmbedBytes
//go:embed "testdata/hello.txt"
helloString EmbedString
)
type T byte
type EmbedUint8 uint8
type EmbedBytes []byte
type EmbedString string
// golang.org/issue/47735
func TestAliases(t *testing.T) {
all := testDirAll
want, e := all.ReadFile("testdata/hello.txt")
if e != nil {
t.Fatal("ReadFile:", e)
}
check := func(g interface{}) {
got := reflect.ValueOf(g)
for i := 0; i < got.Len(); i++ {
if byte(got.Index(i).Uint()) != want[i] {
t.Fatalf("got %v want %v", got.Bytes(), want)
}
}
}
check(helloT)
check(helloUint8)
check(helloEUint8)
check(helloBytes)
check(helloString)
}

View File

@@ -87,123 +87,97 @@ func Decode(data []byte) (p *Block, rest []byte) {
// pemStart begins with a newline. However, at the very beginning of
// the byte array, we'll accept the start string without it.
rest = data
if bytes.HasPrefix(data, pemStart[1:]) {
rest = rest[len(pemStart)-1 : len(data)]
} else if i := bytes.Index(data, pemStart); i >= 0 {
rest = rest[i+len(pemStart) : len(data)]
} else {
return nil, data
}
typeLine, rest := getLine(rest)
if !bytes.HasSuffix(typeLine, pemEndOfLine) {
return decodeError(data, rest)
}
typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
p = &Block{
Headers: make(map[string]string),
Type: string(typeLine),
}
for {
// This loop terminates because getLine's second result is
// always smaller than its argument.
if len(rest) == 0 {
if bytes.HasPrefix(rest, pemStart[1:]) {
rest = rest[len(pemStart)-1:]
} else if i := bytes.Index(rest, pemStart); i >= 0 {
rest = rest[i+len(pemStart) : len(rest)]
} else {
return nil, data
}
line, next := getLine(rest)
i := bytes.IndexByte(line, ':')
if i == -1 {
break
var typeLine []byte
typeLine, rest = getLine(rest)
if !bytes.HasSuffix(typeLine, pemEndOfLine) {
continue
}
typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
p = &Block{
Headers: make(map[string]string),
Type: string(typeLine),
}
// TODO(agl): need to cope with values that spread across lines.
key, val := line[:i], line[i+1:]
key = bytes.TrimSpace(key)
val = bytes.TrimSpace(val)
p.Headers[string(key)] = string(val)
rest = next
for {
// This loop terminates because getLine's second result is
// always smaller than its argument.
if len(rest) == 0 {
return nil, data
}
line, next := getLine(rest)
i := bytes.IndexByte(line, ':')
if i == -1 {
break
}
// TODO(agl): need to cope with values that spread across lines.
key, val := line[:i], line[i+1:]
key = bytes.TrimSpace(key)
val = bytes.TrimSpace(val)
p.Headers[string(key)] = string(val)
rest = next
}
var endIndex, endTrailerIndex int
// If there were no headers, the END line might occur
// immediately, without a leading newline.
if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
endIndex = 0
endTrailerIndex = len(pemEnd) - 1
} else {
endIndex = bytes.Index(rest, pemEnd)
endTrailerIndex = endIndex + len(pemEnd)
}
if endIndex < 0 {
continue
}
// After the "-----" of the ending line, there should be the same type
// and then a final five dashes.
endTrailer := rest[endTrailerIndex:]
endTrailerLen := len(typeLine) + len(pemEndOfLine)
if len(endTrailer) < endTrailerLen {
continue
}
restOfEndLine := endTrailer[endTrailerLen:]
endTrailer = endTrailer[:endTrailerLen]
if !bytes.HasPrefix(endTrailer, typeLine) ||
!bytes.HasSuffix(endTrailer, pemEndOfLine) {
continue
}
// The line must end with only whitespace.
if s, _ := getLine(restOfEndLine); len(s) != 0 {
continue
}
base64Data := removeSpacesAndTabs(rest[:endIndex])
p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
if err != nil {
continue
}
p.Bytes = p.Bytes[:n]
// the -1 is because we might have only matched pemEnd without the
// leading newline if the PEM block was empty.
_, rest = getLine(rest[endIndex+len(pemEnd)-1:])
return p, rest
}
var endIndex, endTrailerIndex int
// If there were no headers, the END line might occur
// immediately, without a leading newline.
if len(p.Headers) == 0 && bytes.HasPrefix(rest, pemEnd[1:]) {
endIndex = 0
endTrailerIndex = len(pemEnd) - 1
} else {
endIndex = bytes.Index(rest, pemEnd)
endTrailerIndex = endIndex + len(pemEnd)
}
if endIndex < 0 {
return decodeError(data, rest)
}
// After the "-----" of the ending line, there should be the same type
// and then a final five dashes.
endTrailer := rest[endTrailerIndex:]
endTrailerLen := len(typeLine) + len(pemEndOfLine)
if len(endTrailer) < endTrailerLen {
return decodeError(data, rest)
}
restOfEndLine := endTrailer[endTrailerLen:]
endTrailer = endTrailer[:endTrailerLen]
if !bytes.HasPrefix(endTrailer, typeLine) ||
!bytes.HasSuffix(endTrailer, pemEndOfLine) {
return decodeError(data, rest)
}
// The line must end with only whitespace.
if s, _ := getLine(restOfEndLine); len(s) != 0 {
return decodeError(data, rest)
}
base64Data := removeSpacesAndTabs(rest[:endIndex])
p.Bytes = make([]byte, base64.StdEncoding.DecodedLen(len(base64Data)))
n, err := base64.StdEncoding.Decode(p.Bytes, base64Data)
if err != nil {
return decodeError(data, rest)
}
p.Bytes = p.Bytes[:n]
// the -1 is because we might have only matched pemEnd without the
// leading newline if the PEM block was empty.
_, rest = getLine(rest[endIndex+len(pemEnd)-1:])
return
}
func decodeError(data, rest []byte) (*Block, []byte) {
// If we get here then we have rejected a likely looking, but
// ultimately invalid PEM block. We need to start over from a new
// position. We have consumed the preamble line and will have consumed
// any lines which could be header lines. However, a valid preamble
// line is not a valid header line, therefore we cannot have consumed
// the preamble line for the any subsequent block. Thus, we will always
// find any valid block, no matter what bytes precede it.
//
// For example, if the input is
//
// -----BEGIN MALFORMED BLOCK-----
// junk that may look like header lines
// or data lines, but no END line
//
// -----BEGIN ACTUAL BLOCK-----
// realdata
// -----END ACTUAL BLOCK-----
//
// we've failed to parse using the first BEGIN line
// and now will try again, using the second BEGIN line.
p, rest := Decode(rest)
if p == nil {
rest = data
}
return p, rest
}
const pemLineLength = 64

View File

@@ -107,6 +107,12 @@ const pemMissingEndingSpace = `
dGVzdA==
-----ENDBAR-----`
const pemMissingEndLine = `
-----BEGIN FOO-----
Header: 1`
var pemRepeatingBegin = strings.Repeat("-----BEGIN \n", 10)
var badPEMTests = []struct {
name string
input string
@@ -131,14 +137,34 @@ var badPEMTests = []struct {
"missing ending space",
pemMissingEndingSpace,
},
{
"repeating begin",
pemRepeatingBegin,
},
{
"missing end line",
pemMissingEndLine,
},
}
func TestBadDecode(t *testing.T) {
for _, test := range badPEMTests {
result, _ := Decode([]byte(test.input))
result, rest := Decode([]byte(test.input))
if result != nil {
t.Errorf("unexpected success while parsing %q", test.name)
}
if string(rest) != test.input {
t.Errorf("unexpected rest: %q; want = %q", rest, test.input)
}
}
}
func TestCVE202224675(t *testing.T) {
// Prior to CVE-2022-24675, this input would cause a stack overflow.
input := []byte(strings.Repeat("-----BEGIN \n", 10000000))
result, rest := Decode(input)
if result != nil || !reflect.DeepEqual(rest, input) {
t.Errorf("Encode of %#v decoded as %#v", input, rest)
}
}

View File

@@ -3,8 +3,11 @@ module std
go 1.17
require (
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e
golang.org/x/net v0.0.0-20210510120150-4163338589ed
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e
golang.org/x/net v0.0.0-20220106012031-21a9c9cfe9c3
)
require (
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 // indirect
golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f // indirect
)

View File

@@ -1,8 +1,8 @@
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e h1:8foAy0aoO5GkqCvAEJ4VC4P3zksTg4X4aJCDpZzmgQI=
golang.org/x/crypto v0.0.0-20210503195802-e9a32991a82e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU=
golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220106012031-21a9c9cfe9c3 h1:3S9JjS9zI0UiDupLpAuaeuciTu/gEk5jf35rQgqOhXQ=
golang.org/x/net v0.0.0-20220106012031-21a9c9cfe9c3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744 h1:yhBbb4IRs2HS9PPlAg6DMC6mUOKexJBNsLf4Z+6En1Q=

View File

@@ -224,7 +224,6 @@ func (check *Checker) exprList(elist []ast.Expr, allowCommaOk bool) (xlist []*op
// exactly one (possibly invalid or comma-ok) value
xlist = []*operand{&x}
if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
x.mode = value
x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
if x.mode == commaerr {
x2.typ = universeError

View File

@@ -343,6 +343,7 @@ func (check *Checker) validType(typ Type, path []Object) typeInfo {
if tn == t.obj {
check.cycleError(path[i:])
t.info = invalid
t.underlying = Typ[Invalid]
return t.info
}
}

View File

@@ -276,7 +276,7 @@ func (check *Checker) collectObjects() {
}
if name == "init" {
check.errorf(d.spec.Name, _InvalidInitDecl, "cannot import package as init - init must be a func")
check.errorf(d.spec, _InvalidInitDecl, "cannot import package as init - init must be a func")
return
}

View File

@@ -0,0 +1,15 @@
// Copyright 2021 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
import "unsafe"
type T /* ERROR illegal cycle in declaration of T */ struct {
T
}
func _(t T) {
_ = unsafe.Sizeof(t) // should not go into infinite recursion here
}

View File

@@ -759,6 +759,9 @@ func (check *Checker) newTypeParam(obj *TypeName, index int, bound Type) *_TypeP
func (t *_TypeParam) Bound() *Interface {
iface := asInterface(t.bound)
if iface == nil {
return &emptyInterface
}
// use the type bound position if we have one
pos := token.NoPos
if n, _ := t.bound.(*Named); n != nil {

View File

@@ -33,6 +33,24 @@ type RegArgs struct {
ReturnIsPtr IntArgRegBitmap
}
func (r *RegArgs) Dump() {
print("Ints:")
for _, x := range r.Ints {
print(" ", x)
}
println()
print("Floats:")
for _, x := range r.Floats {
print(" ", x)
}
println()
print("Ptrs:")
for _, x := range r.Ptrs {
print(" ", x)
}
println()
}
// IntArgRegBitmap is a bitmap large enough to hold one bit per
// integer argument/return register.
type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8

View File

@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin && !ios
// +build darwin,!ios
package unix
import (

View File

@@ -169,6 +169,11 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
n := exp5
if n < 0 {
n = -n
if n < 0 {
// This can occur if -n overflows. -(-1 << 63) would become
// -1 << 63, which is still negative.
return nil, false
}
}
if n > 1e6 {
return nil, false // avoid excessively large exponents

View File

@@ -104,6 +104,7 @@ var setStringTests = []StringTest{
{in: "4/3/"},
{in: "4/3."},
{in: "4/"},
{in: "13e-9223372036854775808"}, // CVE-2022-23772
// valid
{"0", "0", true},

View File

@@ -751,6 +751,12 @@ func TestDialerKeepAlive(t *testing.T) {
func TestDialCancel(t *testing.T) {
mustHaveExternalNetwork(t)
if strings.HasPrefix(testenv.Builder(), "darwin-arm64") {
// The darwin-arm64 machines run in an environment that's not
// compatible with this test.
t.Skipf("builder %q gives no route to host for 198.18.0.0", testenv.Builder())
}
blackholeIPPort := JoinHostPort(slowDst4, "1234")
if !supportsIPv4() {
blackholeIPPort = JoinHostPort(slowDst6, "1234")

View File

@@ -31,6 +31,10 @@ const (
// to be used as a useTCP parameter to exchange
useTCPOnly = true
useUDPOrTCP = false
// Maximum DNS packet size.
// Value taken from https://dnsflagday.net/2020/.
maxDNSPacketSize = 1232
)
var (
@@ -83,7 +87,7 @@ func dnsPacketRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte)
return dnsmessage.Parser{}, dnsmessage.Header{}, err
}
b = make([]byte, 512) // see RFC 1035
b = make([]byte, maxDNSPacketSize)
for {
n, err := c.Read(b)
if err != nil {

View File

@@ -882,7 +882,7 @@ func (f *fakeDNSPacketConn) Close() error {
func TestIgnoreDNSForgeries(t *testing.T) {
c, s := Pipe()
go func() {
b := make([]byte, 512)
b := make([]byte, maxDNSPacketSize)
n, err := s.Read(b)
if err != nil {
t.Error(err)

View File

@@ -965,7 +965,6 @@ func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
if err == nil {
return n, nil
}
b.stop()
if err == io.EOF {
return n, err
}

View File

@@ -1353,6 +1353,33 @@ func TestClientTimeoutCancel(t *testing.T) {
}
}
func TestClientTimeoutDoesNotExpire_h1(t *testing.T) { testClientTimeoutDoesNotExpire(t, h1Mode) }
func TestClientTimeoutDoesNotExpire_h2(t *testing.T) { testClientTimeoutDoesNotExpire(t, h2Mode) }
// Issue 49366: if Client.Timeout is set but not hit, no error should be returned.
func testClientTimeoutDoesNotExpire(t *testing.T, h2 bool) {
setParallel(t)
defer afterTest(t)
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
w.Write([]byte("body"))
}))
defer cst.close()
cst.c.Timeout = 1 * time.Hour
req, _ := NewRequest("GET", cst.ts.URL, nil)
res, err := cst.c.Do(req)
if err != nil {
t.Fatal(err)
}
if _, err = io.Copy(io.Discard, res.Body); err != nil {
t.Fatalf("io.Copy(io.Discard, res.Body) = %v, want nil", err)
}
if err = res.Body.Close(); err != nil {
t.Fatalf("res.Body.Close() = %v, want nil", err)
}
}
func TestClientRedirectEatsBody_h1(t *testing.T) { testClientRedirectEatsBody(t, h1Mode) }
func TestClientRedirectEatsBody_h2(t *testing.T) { testClientRedirectEatsBody(t, h2Mode) }
func testClientRedirectEatsBody(t *testing.T, h2 bool) {

View File

@@ -1582,3 +1582,37 @@ func TestH12_WebSocketUpgrade(t *testing.T) {
},
}.run(t)
}
func TestIdentityTransferEncoding_h1(t *testing.T) { testIdentityTransferEncoding(t, h1Mode) }
func TestIdentityTransferEncoding_h2(t *testing.T) { testIdentityTransferEncoding(t, h2Mode) }
func testIdentityTransferEncoding(t *testing.T, h2 bool) {
setParallel(t)
defer afterTest(t)
const body = "body"
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
gotBody, _ := io.ReadAll(r.Body)
if got, want := string(gotBody), body; got != want {
t.Errorf("got request body = %q; want %q", got, want)
}
w.Header().Set("Transfer-Encoding", "identity")
w.WriteHeader(StatusOK)
w.(Flusher).Flush()
io.WriteString(w, body)
}))
defer cst.close()
req, _ := NewRequest("GET", cst.ts.URL, strings.NewReader(body))
res, err := cst.c.Do(req)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
gotBody, err := io.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
if got, want := string(gotBody), body; got != want {
t.Errorf("got response body = %q; want %q", got, want)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -317,21 +317,17 @@ func (s *Server) wrap() {
s.mu.Lock()
defer s.mu.Unlock()
// Keep Close from returning until the user's ConnState hook
// (if any) finishes. Without this, the call to forgetConn
// below might send the count to 0 before we run the hook.
s.wg.Add(1)
defer s.wg.Done()
switch cs {
case http.StateNew:
s.wg.Add(1)
if _, exists := s.conns[c]; exists {
panic("invalid state transition")
}
if s.conns == nil {
s.conns = make(map[net.Conn]http.ConnState)
}
// Add c to the set of tracked conns and increment it to the
// waitgroup.
s.wg.Add(1)
s.conns[c] = cs
if s.closed {
// Probably just a socket-late-binding dial from
@@ -358,7 +354,14 @@ func (s *Server) wrap() {
s.closeConn(c)
}
case http.StateHijacked, http.StateClosed:
s.forgetConn(c)
// Remove c from the set of tracked conns and decrement it from the
// waitgroup, unless it was previously removed.
if _, ok := s.conns[c]; ok {
delete(s.conns, c)
// Keep Close from returning until the user's ConnState hook
// (if any) finishes.
defer s.wg.Done()
}
}
if oldHook != nil {
oldHook(c, cs)
@@ -378,13 +381,3 @@ func (s *Server) closeConnChan(c net.Conn, done chan<- struct{}) {
done <- struct{}{}
}
}
// forgetConn removes c from the set of tracked conns and decrements it from the
// waitgroup, unless it was previously removed.
// s.mu must be held.
func (s *Server) forgetConn(c net.Conn) {
if _, ok := s.conns[c]; ok {
delete(s.conns, c)
s.wg.Done()
}
}

View File

@@ -9,6 +9,7 @@ import (
"io"
"net"
"net/http"
"sync"
"testing"
)
@@ -203,6 +204,59 @@ func TestServerZeroValueClose(t *testing.T) {
ts.Close() // tests that it doesn't panic
}
// Issue 51799: test hijacking a connection and then closing it
// concurrently with closing the server.
func TestCloseHijackedConnection(t *testing.T) {
hijacked := make(chan net.Conn)
ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer close(hijacked)
hj, ok := w.(http.Hijacker)
if !ok {
t.Fatal("failed to hijack")
}
c, _, err := hj.Hijack()
if err != nil {
t.Fatal(err)
}
hijacked <- c
}))
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
req, err := http.NewRequest("GET", ts.URL, nil)
if err != nil {
t.Log(err)
}
// Use a client not associated with the Server.
var c http.Client
resp, err := c.Do(req)
if err != nil {
t.Log(err)
return
}
resp.Body.Close()
}()
wg.Add(1)
conn := <-hijacked
go func(conn net.Conn) {
defer wg.Done()
// Close the connection and then inform the Server that
// we closed it.
conn.Close()
ts.Config.ConnState(conn, http.StateClosed)
}(conn)
wg.Add(1)
go func() {
defer wg.Done()
ts.Close()
}()
wg.Wait()
}
func TestTLSServerWithHTTP2(t *testing.T) {
modes := []struct {
name string

View File

@@ -10,37 +10,56 @@ import "strings"
// LocalhostCert is a PEM-encoded TLS cert with SAN IPs
// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT.
// generated from src/crypto/tls:
// go run generate_cert.go --rsa-bits 1024 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
// go run generate_cert.go --rsa-bits 2048 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
var LocalhostCert = []byte(`-----BEGIN CERTIFICATE-----
MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS
MIIDOTCCAiGgAwIBAgIQSRJrEpBGFc7tNb1fb5pKFzANBgkqhkiG9w0BAQsFADAS
MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4
iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul
rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO
BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw
AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA
AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9
tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs
h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM
fblo6RBxUQ==
MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA6Gba5tHV1dAKouAaXO3/ebDUU4rvwCUg/CNaJ2PT5xLD4N1Vcb8r
bFSW2HXKq+MPfVdwIKR/1DczEoAGf/JWQTW7EgzlXrCd3rlajEX2D73faWJekD0U
aUgz5vtrTXZ90BQL7WvRICd7FlEZ6FPOcPlumiyNmzUqtwGhO+9ad1W5BqJaRI6P
YfouNkwR6Na4TzSj5BrqUfP0FwDizKSJ0XXmh8g8G9mtwxOSN3Ru1QFc61Xyeluk
POGKBV/q6RBNklTNe0gI8usUMlYyoC7ytppNMW7X2vodAelSu25jgx2anj9fDVZu
h7AXF5+4nJS4AAt0n1lNY7nGSsdZas8PbQIDAQABo4GIMIGFMA4GA1UdDwEB/wQE
AwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
DgQWBBStsdjh3/JCXXYlQryOrL4Sh7BW5TAuBgNVHREEJzAlggtleGFtcGxlLmNv
bYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAxWGI
5NhpF3nwwy/4yB4i/CwwSpLrWUa70NyhvprUBC50PxiXav1TeDzwzLx/o5HyNwsv
cxv3HdkLW59i/0SlJSrNnWdfZ19oTcS+6PtLoVyISgtyN6DpkKpdG1cOkW3Cy2P2
+tK/tKHRP1Y/Ra0RiDpOAmqn0gCOFGz8+lqDIor/T7MTpibL3IxqWfPrvfVRHL3B
grw/ZQTTIVjjh4JBSW3WyWgNo/ikC1lrVxzl4iPUGptxT36Cr7Zk2Bsg0XqwbOvK
5d+NTDREkSnUbie4GeutujmX3Dsx88UiV6UY/4lHJa6I5leHUNOHahRbpbWeOfs/
WkBKOclmOV2xlTVuPw==
-----END CERTIFICATE-----`)
// LocalhostKey is the private key for LocalhostCert.
var LocalhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9
SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB
l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB
AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet
3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb
uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H
qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp
jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY
fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U
fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU
y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX
qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo
f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA==
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDoZtrm0dXV0Aqi
4Bpc7f95sNRTiu/AJSD8I1onY9PnEsPg3VVxvytsVJbYdcqr4w99V3AgpH/UNzMS
gAZ/8lZBNbsSDOVesJ3euVqMRfYPvd9pYl6QPRRpSDPm+2tNdn3QFAvta9EgJ3sW
URnoU85w+W6aLI2bNSq3AaE771p3VbkGolpEjo9h+i42TBHo1rhPNKPkGupR8/QX
AOLMpInRdeaHyDwb2a3DE5I3dG7VAVzrVfJ6W6Q84YoFX+rpEE2SVM17SAjy6xQy
VjKgLvK2mk0xbtfa+h0B6VK7bmODHZqeP18NVm6HsBcXn7iclLgAC3SfWU1jucZK
x1lqzw9tAgMBAAECggEABWzxS1Y2wckblnXY57Z+sl6YdmLV+gxj2r8Qib7g4ZIk
lIlWR1OJNfw7kU4eryib4fc6nOh6O4AWZyYqAK6tqNQSS/eVG0LQTLTTEldHyVJL
dvBe+MsUQOj4nTndZW+QvFzbcm2D8lY5n2nBSxU5ypVoKZ1EqQzytFcLZpTN7d89
EPj0qDyrV4NZlWAwL1AygCwnlwhMQjXEalVF1ylXwU3QzyZ/6MgvF6d3SSUlh+sq
XefuyigXw484cQQgbzopv6niMOmGP3of+yV4JQqUSb3IDmmT68XjGd2Dkxl4iPki
6ZwXf3CCi+c+i/zVEcufgZ3SLf8D99kUGE7v7fZ6AQKBgQD1ZX3RAla9hIhxCf+O
3D+I1j2LMrdjAh0ZKKqwMR4JnHX3mjQI6LwqIctPWTU8wYFECSh9klEclSdCa64s
uI/GNpcqPXejd0cAAdqHEEeG5sHMDt0oFSurL4lyud0GtZvwlzLuwEweuDtvT9cJ
Wfvl86uyO36IW8JdvUprYDctrQKBgQDycZ697qutBieZlGkHpnYWUAeImVA878sJ
w44NuXHvMxBPz+lbJGAg8Cn8fcxNAPqHIraK+kx3po8cZGQywKHUWsxi23ozHoxo
+bGqeQb9U661TnfdDspIXia+xilZt3mm5BPzOUuRqlh4Y9SOBpSWRmEhyw76w4ZP
OPxjWYAgwQKBgA/FehSYxeJgRjSdo+MWnK66tjHgDJE8bYpUZsP0JC4R9DL5oiaA
brd2fI6Y+SbyeNBallObt8LSgzdtnEAbjIH8uDJqyOmknNePRvAvR6mP4xyuR+Bv
m+Lgp0DMWTw5J9CKpydZDItc49T/mJ5tPhdFVd+am0NAQnmr1MCZ6nHxAoGABS3Y
LkaC9FdFUUqSU8+Chkd/YbOkuyiENdkvl6t2e52jo5DVc1T7mLiIrRQi4SI8N9bN
/3oJWCT+uaSLX2ouCtNFunblzWHBrhxnZzTeqVq4SLc8aESAnbslKL4i8/+vYZlN
s8xtiNcSvL+lMsOBORSXzpj/4Ot8WwTkn1qyGgECgYBKNTypzAHeLE6yVadFp3nQ
Ckq9yzvP/ib05rvgbvrne00YeOxqJ9gtTrzgh7koqJyX1L4NwdkEza4ilDWpucn0
xiUZS4SoaJq6ZvcBYS62Yr1t8n09iG47YL8ibgtmH3L+svaotvpVxVK+d7BLevA/
ZboOWVe3icTy64BT3OQhmg==
-----END RSA TESTING KEY-----`))
func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }

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