From 9f4d7ffd06e50e5f0748fe836ab920a2bd09b2ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Jul 2026 09:27:05 +0000 Subject: [PATCH] chore(deps): bump the go-modules group across 1 directory with 5 updates Bumps the go-modules group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [charm.land/bubbletea/v2](https://github.com/charmbracelet/bubbletea) | `2.0.7` | `2.0.8` | | [charm.land/lipgloss/v2](https://github.com/charmbracelet/lipgloss) | `2.0.4` | `2.0.5` | | [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) | `1.24.0` | `1.24.1` | | [golang.org/x/tools](https://github.com/golang/tools) | `0.47.0` | `0.48.0` | | [github.com/mdlayher/netlink](https://github.com/mdlayher/netlink) | `1.9.0` | `1.11.2` | Updates `charm.land/bubbletea/v2` from 2.0.7 to 2.0.8 - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Commits](https://github.com/charmbracelet/bubbletea/compare/v2.0.7...v2.0.8) Updates `charm.land/lipgloss/v2` from 2.0.4 to 2.0.5 - [Release notes](https://github.com/charmbracelet/lipgloss/releases) - [Commits](https://github.com/charmbracelet/lipgloss/compare/v2.0.4...v2.0.5) Updates `github.com/prometheus/client_golang` from 1.24.0 to 1.24.1 - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/v1.24.1/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.24.0...v1.24.1) Updates `golang.org/x/tools` from 0.47.0 to 0.48.0 - [Release notes](https://github.com/golang/tools/releases) - [Commits](https://github.com/golang/tools/compare/v0.47.0...v0.48.0) Updates `github.com/mdlayher/netlink` from 1.9.0 to 1.11.2 - [Release notes](https://github.com/mdlayher/netlink/releases) - [Changelog](https://github.com/mdlayher/netlink/blob/main/CHANGELOG.md) - [Commits](https://github.com/mdlayher/netlink/compare/v1.9.0...v1.11.2) --- updated-dependencies: - dependency-name: charm.land/bubbletea/v2 dependency-version: 2.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-modules - dependency-name: charm.land/lipgloss/v2 dependency-version: 2.0.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-modules - dependency-name: github.com/prometheus/client_golang dependency-version: 1.24.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-modules - dependency-name: golang.org/x/tools dependency-version: 0.48.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-modules - dependency-name: github.com/mdlayher/netlink dependency-version: 1.11.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-modules ... Signed-off-by: dependabot[bot] --- go.mod | 18 +- go.sum | 36 +- .../charmbracelet/ultraviolet/buffer.go | 3 +- .../charmbracelet/ultraviolet/cell.go | 6 + .../charmbracelet/ultraviolet/decoder.go | 1 - .../charmbracelet/ultraviolet/terminal.go | 26 + .../ultraviolet/terminal_renderer.go | 62 +- .../ultraviolet/terminal_screen.go | 61 +- vendor/github.com/gokrazy/updater/updater.go | 22 +- .../github.com/klauspost/compress/README.md | 12 + .../compress/zstd/fse_decoder_arm64.s | 13 +- .../klauspost/compress/zstd/seqdec_arm64.s | 8 +- .../klauspost/compress/zstd/snappy.go | 7 +- .../github.com/mdlayher/netlink/.golangci.yml | 21 + .../github.com/mdlayher/netlink/CHANGELOG.md | 76 +- vendor/github.com/mdlayher/netlink/align.go | 18 +- .../github.com/mdlayher/netlink/attribute.go | 10 +- vendor/github.com/mdlayher/netlink/conn.go | 185 +++-- .../github.com/mdlayher/netlink/conn_linux.go | 111 ++- .../mdlayher/netlink/conn_others.go | 6 + vendor/github.com/mdlayher/netlink/debug.go | 46 +- .../mdlayher/netlink/debug_linux.go | 196 +++++ .../mdlayher/netlink/debug_others.go | 40 ++ vendor/github.com/mdlayher/netlink/doc.go | 3 + vendor/github.com/mdlayher/netlink/errors.go | 16 +- vendor/github.com/mdlayher/netlink/message.go | 68 +- .../github.com/mdlayher/netlink/nlenc/doc.go | 2 + .../github.com/mdlayher/netlink/nlenc/int.go | 52 +- .../mdlayher/netlink/nltest/errors_unix.go | 10 +- .../mdlayher/netlink/nltest/nltest.go | 124 ++-- .../client_golang/prometheus/promhttp/http.go | 13 +- .../x/tools/cmd/goimports/goimports.go | 8 +- .../x/tools/go/types/objectpath/objectpath.go | 9 +- .../x/tools/internal/imports/fix.go | 49 +- .../x/tools/internal/imports/mod.go | 25 +- .../x/tools/internal/imports/source_env.go | 2 +- .../x/tools/internal/modindex/directories.go | 131 ++++ .../x/tools/internal/modindex/index.go | 295 ++++++++ .../x/tools/internal/modindex/lookup.go | 184 +++++ .../x/tools/internal/modindex/modindex.go | 121 ++++ .../x/tools/internal/modindex/symbols.go | 244 +++++++ .../x/tools/internal/stdlib/deps.go | 669 +++++++++--------- .../x/tools/internal/stdlib/manifest.go | 2 + vendor/modules.txt | 21 +- 44 files changed, 2374 insertions(+), 658 deletions(-) create mode 100644 vendor/github.com/mdlayher/netlink/.golangci.yml create mode 100644 vendor/github.com/mdlayher/netlink/debug_linux.go create mode 100644 vendor/github.com/mdlayher/netlink/debug_others.go create mode 100644 vendor/golang.org/x/tools/internal/modindex/directories.go create mode 100644 vendor/golang.org/x/tools/internal/modindex/index.go create mode 100644 vendor/golang.org/x/tools/internal/modindex/lookup.go create mode 100644 vendor/golang.org/x/tools/internal/modindex/modindex.go create mode 100644 vendor/golang.org/x/tools/internal/modindex/symbols.go diff --git a/go.mod b/go.mod index ba66a3b562..12338e8601 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.26 require ( charm.land/bubbles/v2 v2.1.1 - charm.land/bubbletea/v2 v2.0.7 - charm.land/lipgloss/v2 v2.0.4 + charm.land/bubbletea/v2 v2.0.8 + charm.land/lipgloss/v2 v2.0.5 charm.land/wish/v2 v2.0.1 github.com/beevik/ntp v1.5.0 github.com/charmbracelet/colorprofile v0.4.3 @@ -17,7 +17,7 @@ require ( github.com/muesli/reflow v0.3.0 github.com/openconfig/goyang v1.6.3 github.com/packetcap/go-pcap v0.0.0-20251215121130-f2cf9f991e7c - github.com/prometheus/client_golang v1.24.0 + github.com/prometheus/client_golang v1.24.1 github.com/stretchr/testify v1.11.1 github.com/vishvananda/netlink v1.3.1 github.com/vishvananda/netns v0.0.5 @@ -26,7 +26,7 @@ require ( golang.org/x/net v0.57.0 golang.org/x/sys v0.47.0 golang.org/x/term v0.45.0 - golang.org/x/tools v0.47.0 + golang.org/x/tools v0.48.0 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 google.golang.org/grpc v1.82.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 @@ -48,7 +48,7 @@ require ( github.com/gokrazy/internal v0.0.0-20260625065634-6994f9152c44 // indirect github.com/google/renameio/v2 v2.0.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/klauspost/compress v1.19.0 // indirect + github.com/klauspost/compress v1.19.1 // indirect github.com/mattn/go-isatty v0.0.22 // indirect github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect @@ -63,7 +63,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/keygen v0.5.4 // indirect - github.com/charmbracelet/ultraviolet v0.0.0-20260525132238-948f4557a654 // indirect + github.com/charmbracelet/ultraviolet v0.0.0-20260703014108-f5a850f9c2b7 // indirect github.com/charmbracelet/x/ansi v0.11.7 // indirect github.com/charmbracelet/x/conpty v0.1.1 // indirect github.com/charmbracelet/x/errors v0.0.0-20251110184232-6ab307057ac7 // indirect @@ -83,7 +83,7 @@ require ( github.com/lunixbochs/struc v0.0.0-20200521075829-a4cb8d33dbbe // indirect github.com/mattn/go-runewidth v0.0.24 // indirect github.com/mdlayher/genetlink v1.4.0 - github.com/mdlayher/netlink v1.9.0 + github.com/mdlayher/netlink v1.11.2 github.com/mdlayher/packet v1.1.2 github.com/mdlayher/socket v0.6.0 // indirect github.com/muesli/cancelreader v0.2.2 // indirect @@ -91,7 +91,7 @@ require ( github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.70.0 // indirect + github.com/prometheus/common v0.70.1 // indirect github.com/prometheus/procfs v0.21.1 github.com/rivo/uniseg v0.4.7 // indirect github.com/sirupsen/logrus v1.9.4 @@ -100,7 +100,7 @@ require ( golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect golang.org/x/mod v0.38.0 golang.org/x/sync v0.22.0 // indirect - golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57 // indirect + golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 // indirect golang.org/x/text v0.40.0 // indirect golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect diff --git a/go.sum b/go.sum index e39c9d43d2..e65e7db0e4 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ charm.land/bubbles/v2 v2.1.1 h1:7r55WzBxpo/R3z98hGmY7KKPd3ET6vsf0Fb9sDHOV60= charm.land/bubbles/v2 v2.1.1/go.mod h1:GE6M31gaWZVXzGw73OeuTTgy4lX+OtkH0E5ymnNsHxo= -charm.land/bubbletea/v2 v2.0.7 h1:7qw2tTAVar7m7klOPBYfTB0mniv/RuexsYwMRNxSeL0= -charm.land/bubbletea/v2 v2.0.7/go.mod h1:DGW2q8gvzHnOpMpZTORs0aySVHCox5C+2Svk0fci1qs= -charm.land/lipgloss/v2 v2.0.4 h1:lcPeVtcp23SNra7lHy8iYE4UC2aIipVQ47sbGyyxR5Q= -charm.land/lipgloss/v2 v2.0.4/go.mod h1:0653x8epbZSzdDfO/XPS1a/uYPOBeSsCssOpJOqDzik= +charm.land/bubbletea/v2 v2.0.8 h1:SxTJMhCAI3lbPmy4SgX5LWZ24AdINr4I6UEqzZvYJuY= +charm.land/bubbletea/v2 v2.0.8/go.mod h1:2SkdgoTXluXJHOUwAoRlRXF/28vklb1rFl6GcgV1/ss= +charm.land/lipgloss/v2 v2.0.5 h1:kbNxgeeUOYv5J0YdpxFjfvf3dFvqH8Aci4zB6xqFtrY= +charm.land/lipgloss/v2 v2.0.5/go.mod h1:9oqhxt4yxIMe6q5A4kHr44DremZk7J9UNh74GlWa5nc= charm.land/log/v2 v2.0.0 h1:SY3Cey7ipx86/MBXQHwsguOT6X1exT94mmJRdzTNs+s= charm.land/log/v2 v2.0.0/go.mod h1:c3cZSRqm20qUVVAR1WmS/7ab8bgha3C6G7DjPcaVZz0= charm.land/wish/v2 v2.0.1 h1:xYOsvQG/bYNRoKUBt0AEyMiCv9rksmCOG/fD5WifAzg= @@ -28,8 +28,8 @@ github.com/charmbracelet/keygen v0.5.4 h1:XQYgf6UEaTGgQSSmiPpIQ78WfseNQp4Pz8N/c1 github.com/charmbracelet/keygen v0.5.4/go.mod h1:t4oBRr41bvK7FaJsAaAQhhkUuHslzFXVjOBwA55CZNM= github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309 h1:dCVbCRRtg9+tsfiTXTp0WupDlHruAXyp+YoxGVofHHc= github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309/go.mod h1:R9cISUs5kAH4Cq/rguNbSwcR+slE5Dfm8FEs//uoIGE= -github.com/charmbracelet/ultraviolet v0.0.0-20260525132238-948f4557a654 h1:FpSYhY28ucg9ZRr+2wj67FAQ0Ey5yiK0072PmRDJNek= -github.com/charmbracelet/ultraviolet v0.0.0-20260525132238-948f4557a654/go.mod h1:hFpumms29Smx3LStRfku8vcCTBe1Kq8aCXtHUJa3mjY= +github.com/charmbracelet/ultraviolet v0.0.0-20260703014108-f5a850f9c2b7 h1:3FmWoGNWK4STvqg0O0Aeav2T7rodWJAPeF0QpH+8gFw= +github.com/charmbracelet/ultraviolet v0.0.0-20260703014108-f5a850f9c2b7/go.mod h1:f/jRa757WUmaOZrbPspXymbg/GnbF+rwe4OLsG7aXYo= github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI= github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ= github.com/charmbracelet/x/conpty v0.1.1 h1:s1bUxjoi7EpqiXysVtC+a8RrvPPNcNvAjfi4jxsAuEs= @@ -103,8 +103,8 @@ github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2C github.com/jsimonetti/rtnetlink v1.3.5 h1:hVlNQNRlLDGZz31gBPicsG7Q53rnlsz1l1Ix/9XlpVA= github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM= github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= -github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ= -github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk= +github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -122,8 +122,8 @@ github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/a github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mdlayher/genetlink v1.4.0 h1:f/Xs7Y2T+GyX9b3dbiUhnLE9InGs5F9RxJ2JwBMl71o= github.com/mdlayher/genetlink v1.4.0/go.mod h1:d1hrKr8fwZU2JkcAtQUAzeTrI7nbgQSl+5k1cC0biSA= -github.com/mdlayher/netlink v1.9.0 h1:G8+GLq2x3v4D4MVIqDdNUhTUC7TKiCy/6MDkmItfKco= -github.com/mdlayher/netlink v1.9.0/go.mod h1:YBnl5BXsCoRuwBjKKlZ+aYmEoq0r12FDA/3JC+94KDg= +github.com/mdlayher/netlink v1.11.2 h1:HKh2jqe+omdSWcQ88nrT7INE61B0NXfiSPFdgL4YbNI= +github.com/mdlayher/netlink v1.11.2/go.mod h1:uT2Yc/QLaZubzDpZIBi9d4GoeLwtp3x1AMeqSRrK2sA= github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY= github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU+x0kew4= github.com/mdlayher/socket v0.6.0 h1:ScZPaAGyO1icQnbFrhPM8mnXyMu9qukC1K4ZoM2IQKU= @@ -150,12 +150,12 @@ github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.24.0 h1:5XStIklKuAtJSNpdD3s8XJj/Yv78IQmE1kbNk87JrAI= -github.com/prometheus/client_golang v1.24.0/go.mod h1:QcsNdotprC2nS4BTM2ucbcqxd2CeXTEa9jW7zHO9iDE= +github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU= +github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.70.0 h1:bcpru3tWPVnxGnETLgOV5jbp/JRXgYEyv65CuBLAMMI= -github.com/prometheus/common v0.70.0/go.mod h1:S/SFasQmgGiYH6C81LKCtYa8QACgthGg5zxL2udV7SY= +github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY= +github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc= github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI= github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -225,14 +225,14 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57 h1:nwGZBCt+FnXUrGsj5vjzAsEmkcaFvd82BbOjECiFYZc= -golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc= +golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959 h1:RJhm5l6Fo4rmEIcndxDllNhhf/fAx8qIm4t6A7vpm2A= +golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959/go.mod h1:LV7u5Oco+Z/g6XI7PqN+EUUUGGkEcmB1uj2ceI0fOVg= golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= -golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= -golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= +golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE= +golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA= golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 h1:3GDAcqdIg1ozBNLgPy4SLT84nfcBjr6rhGtXYtrkWLU= diff --git a/vendor/github.com/charmbracelet/ultraviolet/buffer.go b/vendor/github.com/charmbracelet/ultraviolet/buffer.go index db8f6b8885..053db7c539 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/buffer.go +++ b/vendor/github.com/charmbracelet/ultraviolet/buffer.go @@ -89,8 +89,7 @@ func (l Line) Set(x int, c *Cell) { } if cw > 1 { - // Mark wide cells with an zero cells. - // We set the wide cell down below + // Mark wide cells with zero-width placeholder cells. for j := 1; j < cw && x+j < lineWidth; j++ { l[x+j] = Cell{} } diff --git a/vendor/github.com/charmbracelet/ultraviolet/cell.go b/vendor/github.com/charmbracelet/ultraviolet/cell.go index ea89b553a3..a5d9e823c6 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/cell.go +++ b/vendor/github.com/charmbracelet/ultraviolet/cell.go @@ -65,6 +65,12 @@ func (c *Cell) IsZero() bool { return *c == Cell{} } +// isWidePlaceholder reports whether the cell is the continuation column of a +// wide cell, marked with a zero display width. +func (c *Cell) isWidePlaceholder() bool { + return c != nil && c.Width == 0 +} + // Clone returns a copy of the cell. func (c *Cell) Clone() (n *Cell) { n = new(Cell) diff --git a/vendor/github.com/charmbracelet/ultraviolet/decoder.go b/vendor/github.com/charmbracelet/ultraviolet/decoder.go index 45ef17d727..a891dc27d3 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/decoder.go +++ b/vendor/github.com/charmbracelet/ultraviolet/decoder.go @@ -1530,7 +1530,6 @@ func parseKittyKeyboard(params ansi.Params) (Event Event) { func parseKittyKeyboardExt(params ansi.Params, k KeyPressEvent) Event { // Handle Kitty keyboard protocol if len(params) > 2 && // We have at least 3 parameters - params[0].Param(1) == 1 && // The first parameter is 1 (defaults to 1) params[1].HasMore() { // The second parameter is a subparameter (separated by a ":") switch params[2].Param(1) { // The third parameter is the event type (defaults to 1) case 2: diff --git a/vendor/github.com/charmbracelet/ultraviolet/terminal.go b/vendor/github.com/charmbracelet/ultraviolet/terminal.go index bf79dce9f0..a9fb453806 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/terminal.go +++ b/vendor/github.com/charmbracelet/ultraviolet/terminal.go @@ -6,6 +6,7 @@ import ( "os/signal" "time" + "github.com/charmbracelet/x/ansi" "golang.org/x/sync/errgroup" ) @@ -208,6 +209,7 @@ func (t *Terminal) Start() error { sendEvents := func(buf []byte, expired bool) int { n, events := evs.scanEvents(buf, expired) for _, ev := range events { + t.handleEvent(ev) t.SendEvent(ev) } return n @@ -290,6 +292,10 @@ func (t *Terminal) Start() error { // Restore any previous screen state. t.scr.Restore() + // Query whether the terminal supports Unicode core mode (DEC mode 2027) so + // we can negotiate grapheme-cluster width. The response is handled in the + // event loop. + t.scr.requestGraphemeWidth() if err := t.scr.Flush(); err != nil { return fmt.Errorf("failed to flush terminal screen: %w", err) } @@ -297,6 +303,26 @@ func (t *Terminal) Start() error { return nil } +// handleEvent reacts to internal events before they are forwarded to the +// application. It negotiates Unicode core mode (DEC mode 2027): when the +// terminal reports the mode is in a settable or active state, it enables +// grapheme-cluster width so wide-glyph measurement matches the terminal. The +// event is still forwarded to the application. +// +// The mode is only enabled for settable/active states (mode set, reset but +// settable, or permanently set). It is explicitly not enabled when the mode is +// not recognized or permanently reset, since those terminals cannot honor it. +// Enabling goes through the screen's locked write path so it cannot race with +// the application's Render/Flush. +func (t *Terminal) handleEvent(ev Event) { + if mr, ok := ev.(ModeReportEvent); ok { + if mr.Mode == ansi.ModeUnicodeCore && + (mr.Value.IsSet() || mr.Value == ansi.ModeReset) { + t.scr.enableGraphemeWidth() + } + } +} + // Wait waits for the terminal event loop to exit and returns any error that // occurred. func (t *Terminal) Wait() error { diff --git a/vendor/github.com/charmbracelet/ultraviolet/terminal_renderer.go b/vendor/github.com/charmbracelet/ultraviolet/terminal_renderer.go index aad5a0ef29..d7c2fbfcb8 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/terminal_renderer.go +++ b/vendor/github.com/charmbracelet/ultraviolet/terminal_renderer.go @@ -88,6 +88,9 @@ const ( tFullscreen tMapNewline tScrollOptim + // tGraphemeWidth indicates the terminal measures cell width using Unicode + // grapheme clustering (DEC mode 2027 / Unicode core). + tGraphemeWidth ) // Set sets the given flags. @@ -136,10 +139,12 @@ type TerminalRenderer struct { oldnum []int // old indices from previous hash cur, saved cursor // the current and saved cursors flags tFlag // terminal writer flags. + method ansi.Method // the width method used to measure cell width term string // the terminal type clear bool // whether to force clear the screen caps capabilities // terminal control sequence capabilities atPhantom bool // whether the cursor is out of bounds and at a phantom cell + lineHadWide bool // whether the line currently being transformed contained a wide cell logger Logger // The logger used for debugging. // profile is the color profile to use when downsampling colors. This is @@ -202,6 +207,28 @@ func (s *TerminalRenderer) SetMapNewline(v bool) { } } +// SetWidthMethod sets the width method the renderer uses to measure the +// display width of strings. This should match the width method configured on +// the screen so that the renderer doesn't disagree with the cell widths it is +// asked to draw. +func (s *TerminalRenderer) SetWidthMethod(method ansi.Method) { + s.method = method +} + +// SetGraphemeWidth sets whether the terminal measures cell width using Unicode +// grapheme clustering (DEC mode 2027 / Unicode core). When enabled, the +// renderer measures string width using [ansi.GraphemeWidth]; otherwise it +// falls back to [ansi.WcWidth]. +func (s *TerminalRenderer) SetGraphemeWidth(v bool) { + if v { + s.flags.Set(tGraphemeWidth) + s.method = ansi.GraphemeWidth + } else { + s.flags.Reset(tGraphemeWidth) + s.method = ansi.WcWidth + } +} + // SetBackspace sets whether to use backspace as a movement optimization. func (s *TerminalRenderer) SetBackspace(v bool) { if v { @@ -331,7 +358,7 @@ func (s *TerminalRenderer) PrependString(newbuf *RenderBuffer, str string) { lines := strings.Split(str, "\n") offset := 0 for _, line := range lines { - lineWidth := ansi.StringWidth(line) + lineWidth := s.method.StringWidth(line) if w > 0 && lineWidth > w { offset += (lineWidth / w) } @@ -487,7 +514,7 @@ func (s *TerminalRenderer) wrapCursor() { } func (s *TerminalRenderer) putAttrCell(newbuf *RenderBuffer, cell *Cell) { - if cell != nil && cell.IsZero() { + if cell != nil && cell.Width == 0 { // XXX: Zero width cells are special and should not be written to the // screen no matter what other attributes they have. // Zero width cells are used for wide characters that are split into @@ -515,13 +542,17 @@ func (s *TerminalRenderer) putAttrCell(newbuf *RenderBuffer, cell *Cell) { if s.cur.X >= newbuf.Width() { s.atPhantom = true } + + if cellWidth > 1 { + s.lineHadWide = true + } } // putCellLR draws a cell at the lower right corner of the screen. func (s *TerminalRenderer) putCellLR(newbuf *RenderBuffer, cell *Cell) { // Optimize for the lower right corner cell. curX := s.cur.X - if cell == nil || !cell.IsZero() { + if !cell.isWidePlaceholder() { _, _ = s.buf.WriteString(ansi.ResetModeAutoWrap) s.putAttrCell(newbuf, cell) // Writing to lower-right corner cell should not wrap. @@ -678,7 +709,7 @@ func (s *TerminalRenderer) putRange(newbuf *RenderBuffer, oldLine, newLine Line, var j, same int for j, same = start, 0; j <= end; j++ { oldCell, newCell := oldLine.At(j), newLine.At(j) - if same == 0 && oldCell != nil && oldCell.IsZero() && newCell.IsZero() { + if same == 0 && oldCell.isWidePlaceholder() && newCell.isWidePlaceholder() { continue } if cellEqual(oldCell, newCell) { @@ -785,6 +816,9 @@ func (s *TerminalRenderer) transformLine(newbuf *RenderBuffer, y int) { oldLine := s.curbuf.Line(y) newLine := newbuf.Line(y) + s.lineHadWide = false + defer s.reanchorWideLine(newbuf) + // Find the first changed cell in the line blank := newLine.At(0) @@ -926,7 +960,7 @@ func (s *TerminalRenderer) transformLine(newbuf *RenderBuffer, y int) { if n != 0 { for n > 0 { wide := newLine.At(n + 1) - if wide == nil || !wide.IsZero() { + if !wide.isWidePlaceholder() { break } n-- @@ -934,7 +968,7 @@ func (s *TerminalRenderer) transformLine(newbuf *RenderBuffer, y int) { } } else if n >= firstCell && newLine.At(n) != nil && newLine.At(n).Width > 1 { next := newLine.At(n + 1) - for next != nil && next.IsZero() { + for next.isWidePlaceholder() { n++ oLastCell++ next = newLine.At(n + 1) @@ -975,6 +1009,22 @@ func (s *TerminalRenderer) transformLine(newbuf *RenderBuffer, y int) { } } +// reanchorWideLine re-anchors the cursor with a single absolute horizontal +// move after a line that contained a wide cell. This is a best-effort fallback +// that bounds cursor desync to one line on terminals whose width model +// disagrees with ours. When the terminal negotiated Unicode grapheme width +// (mode 2027) the models agree, so no re-anchor is needed. +func (s *TerminalRenderer) reanchorWideLine(newbuf *RenderBuffer) { + if !s.lineHadWide || s.flags.Contains(tGraphemeWidth) { + return + } + s.lineHadWide = false + if s.atPhantom || s.cur.X < 0 || s.cur.X >= newbuf.Width() { + return + } + _, _ = s.buf.WriteString(ansi.CursorHorizontalAbsolute(s.cur.X + 1)) +} + // deleteCells deletes the count cells at the current cursor position and moves // the rest of the line to the left. This is equivalent to [ansi.DCH]. func (s *TerminalRenderer) deleteCells(count int) { diff --git a/vendor/github.com/charmbracelet/ultraviolet/terminal_screen.go b/vendor/github.com/charmbracelet/ultraviolet/terminal_screen.go index 9fdc32816e..4078ce3e8b 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/terminal_screen.go +++ b/vendor/github.com/charmbracelet/ultraviolet/terminal_screen.go @@ -7,6 +7,7 @@ import ( "log" "os" "strings" + "sync" "github.com/charmbracelet/colorprofile" "github.com/charmbracelet/x/ansi" @@ -37,6 +38,16 @@ type TerminalScreen struct { windowTitle string syncUpdates bool // mode 2026 resetTabs bool // DECST8C - reset terminal tabs on start + + // mu serializes access to the render buffer, output buffer, and + // width-method state so the terminal event loop (which negotiates + // grapheme-cluster width) cannot race with the application's own + // Render/Flush goroutine. + mu sync.Mutex + // widthMethodOverride is set when the application explicitly calls + // [TerminalScreen.SetWidthMethod]. An explicit override suppresses the + // automatic mode-2027 width-method negotiation. + widthMethodOverride bool } var _ Screen = (*TerminalScreen)(nil) @@ -130,9 +141,53 @@ func (s *TerminalScreen) WidthMethod() WidthMethod { return s.win.WidthMethod() } -// SetWidthMethod sets the width method for the terminal screen. +// SetWidthMethod sets the width method for the terminal screen. This is an +// override that propagates to the window/buffer and the renderer so that all +// width measurements use the same method. Calling this marks the width method +// as explicitly overridden, which disables automatic mode-2027 negotiation. func (s *TerminalScreen) SetWidthMethod(method ansi.Method) { + s.mu.Lock() + defer s.mu.Unlock() + s.widthMethodOverride = true + s.setWidthMethod(method) +} + +// setWidthMethod propagates the width method to the window/buffer and the +// renderer. Callers must hold s.mu. +func (s *TerminalScreen) setWidthMethod(method ansi.Method) { s.win.SetWidthMethod(method) + s.rend.SetWidthMethod(method) +} + +// requestGraphemeWidth queues a DECRQM request for Unicode core mode (DEC mode +// 2027) so the terminal reports whether it measures cell width using grapheme +// clustering. The response arrives as a [ModeReportEvent]. +func (s *TerminalScreen) requestGraphemeWidth() { + s.mu.Lock() + defer s.mu.Unlock() + s.buf.WriteString(ansi.RequestMode(ansi.ModeUnicodeCore)) +} + +// enableGraphemeWidth enables Unicode core mode (DEC mode 2027) on the terminal +// and switches the screen's width method to [ansi.GraphemeWidth] so wide-glyph +// measurement matches the terminal. The change propagates to the +// window/buffer and renderer. +// +// If the application has explicitly set a width method via +// [TerminalScreen.SetWidthMethod], the explicit choice is preserved and this is +// a no-op. The change is committed to the underlying writer through the +// screen's normal locked write path so it cannot race with Render/Flush. +func (s *TerminalScreen) enableGraphemeWidth() { + s.mu.Lock() + if s.widthMethodOverride { + s.mu.Unlock() + return + } + s.buf.WriteString(ansi.SetMode(ansi.ModeUnicodeCore)) + s.setWidthMethod(ansi.GraphemeWidth) + s.rend.SetGraphemeWidth(true) + s.mu.Unlock() + _ = s.Flush() } // SetColorProfile sets the color profile for the terminal screen. @@ -173,6 +228,8 @@ func (s *TerminalScreen) Display(d Drawable) error { // The changes can be committed to the underlying writer by calling the // [TerminalScreen.Flush] method. func (s *TerminalScreen) Render() { + s.mu.Lock() + defer s.mu.Unlock() for y := 0; y < s.win.Height(); y++ { for x := 0; x < s.win.Width(); { cell := s.win.CellAt(x, y) @@ -194,6 +251,8 @@ func (s *TerminalScreen) Render() { // Flush writes any pending output to the underlying writer. func (s *TerminalScreen) Flush() error { + s.mu.Lock() + defer s.mu.Unlock() if s.cursor != nil && !s.cursor.Hidden && s.cursor.X >= 0 && s.cursor.Y >= 0 { s.rend.MoveTo(s.cursor.X, s.cursor.Y) } else if !s.altScreen { diff --git a/vendor/github.com/gokrazy/updater/updater.go b/vendor/github.com/gokrazy/updater/updater.go index 9be0d04d47..2221c39363 100644 --- a/vendor/github.com/gokrazy/updater/updater.go +++ b/vendor/github.com/gokrazy/updater/updater.go @@ -16,7 +16,6 @@ import ( "log" "net/http" "net/url" - "slices" "strings" ) @@ -76,7 +75,12 @@ const ( // Supports returns whether the target is known to support the specified update // protocol feature. func (t *Target) Supports(feature ProtocolFeature) bool { - return slices.Contains(t.supports, string(feature)) + for _, f := range t.supports { + if f == string(feature) { + return true + } + } + return false } // StreamTo streams from the specified io.Reader to the specified destination: @@ -118,7 +122,7 @@ func (t *Target) StreamTo(ctx context.Context, dest string, r io.Reader) error { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("unexpected HTTP status code: got %v, want %v (body %q)", resp.Status, want, string(body)) } - remoteHash, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + remoteHash, err := io.ReadAll(resp.Body) if err != nil { return err } @@ -162,7 +166,7 @@ func (t *Target) Put(ctx context.Context, dest string, r io.Reader) error { // Switch changes the active root partition from the currently running root // partition to the currently inactive root partition. func (t *Target) Switch(ctx context.Context) error { - req, err := http.NewRequestWithContext(ctx, "POST", t.baseURL+"update/switch", http.NoBody) + req, err := http.NewRequestWithContext(ctx, "POST", t.baseURL+"update/switch", nil) if err != nil { return err } @@ -181,7 +185,7 @@ func (t *Target) Switch(ctx context.Context) error { // Testboot marks the inactive root partition to be tested upon the next boot, // and made active if the test boot succeeds. func (t *Target) Testboot(ctx context.Context) error { - req, err := http.NewRequestWithContext(ctx, "POST", t.baseURL+"update/testboot", http.NoBody) + req, err := http.NewRequestWithContext(ctx, "POST", t.baseURL+"update/testboot", nil) if err != nil { return err } @@ -245,7 +249,7 @@ func (t *Target) Reboot(ctx context.Context, opts ...RebootOption) error { url += "?" + strings.Join(params, "&") } - req, err := http.NewRequestWithContext(ctx, "POST", url, http.NoBody) + req, err := http.NewRequestWithContext(ctx, "POST", url, nil) if err != nil { return err } @@ -335,7 +339,7 @@ func (t *Target) InstalledEEPROM() EEPROMVersion { } func (t *Target) requestFeatures(ctx context.Context) error { - req, err := http.NewRequestWithContext(ctx, "GET", t.baseURL+"update/features", http.NoBody) + req, err := http.NewRequestWithContext(ctx, "GET", t.baseURL+"update/features", nil) if err != nil { return err } @@ -357,7 +361,7 @@ func (t *Target) requestFeatures(ctx context.Context) error { return fmt.Errorf("unexpected HTTP status code: got %d, want %d (body %q)", got, want, string(body)) } - body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + body, err := io.ReadAll(resp.Body) if err != nil { return err } @@ -399,7 +403,7 @@ type EEPROMVersion struct { } func (t *Target) getEEPROMFromStatus(ctx context.Context) (*EEPROMVersion, error) { - req, err := http.NewRequestWithContext(ctx, "GET", t.baseURL, http.NoBody) + req, err := http.NewRequestWithContext(ctx, "GET", t.baseURL, nil) if err != nil { return nil, err } diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md index fb023f2cf2..0e9f170d01 100644 --- a/vendor/github.com/klauspost/compress/README.md +++ b/vendor/github.com/klauspost/compress/README.md @@ -27,6 +27,18 @@ Use the links above for more information on each. # changelog +* Jul 1st, 2026 [1.19.0](https://github.com/klauspost/compress/releases/tag/v1.19.0) + * zstd: Add true concurrent stream encodingin https://github.com/klauspost/compress/pull/1136 + * zstd: arm64 decoder asm by @lizthegrey in https://github.com/klauspost/compress/pull/1160 + * flate: Add inflate checkpoints in https://github.com/klauspost/compress/pull/1154 + * zstd: avoid unused BuildDict encoder allocation by @snissn in https://github.com/klauspost/compress/pull/1147 + * snappy/s2: Limit length of varint in `decodedLen` by @eustas in https://github.com/klauspost/compress/pull/1148 + * gzhttp: match qvalue parameter case-insensitively (RFC 7231) by @z9z in https://github.com/klauspost/compress/pull/1149 + * zip: add NameDecoder callback for legacy encoding rewrite by @SAY-5 in https://github.com/klauspost/compress/pull/1150 + * huff0: Allow building tables from histogram in https://github.com/klauspost/compress/pull/1155 + * huff0: Allow building table from oversized histogram in https://github.com/klauspost/compress/pull/1156 + * s2sx: Clean symlink targets in https://github.com/klauspost/compress/pull/1163 + * Feb 9th, 2026 [1.18.4](https://github.com/klauspost/compress/releases/tag/v1.18.4) * gzhttp: Add zstandard to server handler wrapper https://github.com/klauspost/compress/pull/1121 * zstd: Add ResetWithOptions to encoder/decoder https://github.com/klauspost/compress/pull/1122 diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s b/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s index 661761fb21..77ee3913f0 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_arm64.s @@ -28,7 +28,10 @@ TEXT ·buildDtable_asm(SB), $0-24 init_main_loop: ADD R8<<1, R1, R15 MOVH (R15), R9 - CMN $1, R9 + AND $0xffff, R9, R15 + MOVD $-1, R16 + AND $0xffff, R16, R16 + CMP R16, R15 BNE do_not_update_high_threshold ADD R7<<3, R5, R15 MOVB R8, 1(R15) @@ -126,9 +129,13 @@ build_table_main_table: RET build_table_check1_ok: - TST R1, R1 + AND $0xff, R1, R15 + AND $0xff, R1, R16 + TST R16, R15 BNE build_table_check2_ok - CMP R6, R7 + AND $0xffff, R7, R15 + AND $0xffff, R6, R16 + CMP R16, R15 BNE build_table_check2_ok MOVD ctx+8(FP), R0 MOVD R7, 24(R0) diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s index 75b19d732a..a468e5fc2c 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_arm64.s @@ -670,9 +670,9 @@ error_overread: MOVD R16, ret+24(FP) RET -// skipped sequenceDecs_decode_bmi2 (BMI2 not available on arm64) +// skipped sequenceDecs_decode_bmi2 (generic twin preferred on arm64) -// skipped sequenceDecs_decode_56_bmi2 (BMI2 not available on arm64) +// skipped sequenceDecs_decode_56_bmi2 (generic twin preferred on arm64) // func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool // Requires: SSE @@ -1966,7 +1966,7 @@ error_not_enough_space: MOVD R16, ret+24(FP) RET -// skipped sequenceDecs_decodeSync_bmi2 (BMI2 not available on arm64) +// skipped sequenceDecs_decodeSync_bmi2 (generic twin preferred on arm64) // func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int // Requires: CMOV, SSE @@ -2702,4 +2702,4 @@ error_not_enough_space: MOVD R16, ret+24(FP) RET -// skipped sequenceDecs_decodeSync_safe_bmi2 (BMI2 not available on arm64) +// skipped sequenceDecs_decodeSync_safe_bmi2 (generic twin preferred on arm64) diff --git a/vendor/github.com/klauspost/compress/zstd/snappy.go b/vendor/github.com/klauspost/compress/zstd/snappy.go index 336c288930..36c56f36d7 100644 --- a/vendor/github.com/klauspost/compress/zstd/snappy.go +++ b/vendor/github.com/klauspost/compress/zstd/snappy.go @@ -334,9 +334,10 @@ func decodeSnappy(blk *blockEnc, src []byte) error { return errUnsupportedLiteralLength } - //if length > snappyMaxBlockSize-d || uint32(length) > len(src)-s { - // return ErrSnappyCorrupt - //} + if length > len(src)-s { + println("length > len(src)-s", length, len(src)-s) + return ErrSnappyCorrupt + } blk.literals = append(blk.literals, src[s:s+length]...) //println(length, "litLen") diff --git a/vendor/github.com/mdlayher/netlink/.golangci.yml b/vendor/github.com/mdlayher/netlink/.golangci.yml new file mode 100644 index 0000000000..7237e2714d --- /dev/null +++ b/vendor/github.com/mdlayher/netlink/.golangci.yml @@ -0,0 +1,21 @@ +version: "2" +linters: + enable: + # - errorlint + - misspell + - modernize + - revive + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - errcheck + path: _test.go +formatters: + exclusions: + generated: lax diff --git a/vendor/github.com/mdlayher/netlink/CHANGELOG.md b/vendor/github.com/mdlayher/netlink/CHANGELOG.md index 64589d14f0..8888318691 100644 --- a/vendor/github.com/mdlayher/netlink/CHANGELOG.md +++ b/vendor/github.com/mdlayher/netlink/CHANGELOG.md @@ -1,6 +1,78 @@ # CHANGELOG -## 1.9.0 +## v1.11.2 + +- [Bug Fix]: [#291](https://github.com/mdlayher/netlink/pull/291) fixed a bug + where `netlink.Conn.Receive` would block concurrent calls to + `netlink.Conn.Send` when blocking in `recvmsg`. +- [Improvement]: [#289](https://github.com/mdlayher/netlink/pull/289) updated + `golang.org/x/net` and `golang.org/x/sys` dependencies. + +## v1.11.1 + +- [Bug Fix]: [#283](https://github.com/mdlayher/netlink/pull/283) fixed a bug + where `netlink.Conn.Receive` would reject valid netlink messages whose header + length is not aligned. This is common with nfqueue, nflog and conntrack events. +- [Bug Fix]: [#284](https://github.com/mdlayher/netlink/pull/284) fixed a bug + where `netlink.Message.Data` could be silently overwritten by subsequent + `netlink.Conn.Receive` calls when `netlink.Config.MessageBufferSize` is enabled, + due to pooled buffer reuse. +- [Improvement]: [#282](https://github.com/mdlayher/netlink/pull/282) improved + error handling by usage of `errors` package. + +## v1.11.0 + +**This is the first release of package netlink that only supports Go 1.25+.** + +- [Bug Fix]: [#280](https://github.com/mdlayher/netlink/pull/280) fixed a + critical bug where `netlink.Conn.Receive` and `netlink.Conn.ReceiveIter` would + panic if the received message was unaligned. +- [Improvement]: [#277](https://github.com/mdlayher/netlink/pull/277) added + big-endian test fixtures for nlenc and deprecated endian helpers in favor of + binary.NativeEndian. +- [Improvement]: [#276](https://github.com/mdlayher/netlink/pull/276) fixed + skipping of tests on big-endian hosts. +- [Improvement]: [#273](https://github.com/mdlayher/netlink/pull/273) added + golangci-lint to the CI pipeline and fixed all existing lint issues. +- [Improvement]: [#272](https://github.com/mdlayher/netlink/pull/272) updated + dependencies and Go version to 1.25. + +## v1.10.0 + +**Users of this version should upgrade to v1.11.0 as this version contains a +critical bug.** + +- [New API]: [#270](https://github.com/mdlayher/netlink/pull/270) added + `MessageBufferSize` option to `netlink.Config` for configuring the size of the + copy buffer used for receiving messages. This can improve performance in + high-throughput applications by reducing the number of syscalls needed to + receive messages. +- [Improvement]: [#219](https://github.com/mdlayher/netlink/pull/219) added + debug logging inspired by libmnl. This is now the new default when setting + `NLDEBUG` in the environment. +- [New API]: [#258](https://github.com/mdlayher/netlink/pull/258) added + `netlink.Conn.ReceiveIter` for iterating over responses without collecting + them into a slice. It also optimized `netlink.Conn.Receive` to use this new + API internally so that less memory is used. +- [Improvement]: [#269](https://github.com/mdlayher/netlink/pull/269) made it so + `nltest.Conn.Receive` can be used to test that multi-part messages are drained + properly. +- [Improvement]: [#266](https://github.com/mdlayher/netlink/pull/266) optimized + the initial parsing of netlink messages in `netlink.Socket.Receive` by adding + an iterator for parsing messages directly from the receive buffer. +- [Improvement]: [#267](https://github.com/mdlayher/netlink/pull/267) added + integration test benchmarks for multi-part dumps. +- [Improvement]: [#215](https://github.com/mdlayher/netlink/pull/215) optimized + the internal peek/allocate logic in `netlink.Socket.Receive`. Messages are + no longer being copied during peeking and the buffer is allocated to the exact + size of the upcoming message. +- [Bug Fix]: [#265](https://github.com/mdlayher/netlink/pull/265) fixed a bug + where concurrent calls to `netlink.Conn.Receive` could race with each other + when handling multi-part messages. Calls to `Receive` are now serialized. +- [Improvement]: [#264](https://github.com/mdlayher/netlink/pull/264) added + handling for truncated messages in `netlink.Socket.Receive`. + +## v1.9.0 **This is the first release of package netlink that only supports Go 1.24+.** @@ -14,7 +86,7 @@ - [Improvement]: [#228](https://github.com/mdlayher/netlink/pull/228) fixed skipping of specific tests on big-endian hosts. -## 1.8.0 +## v1.8.0 - [Improvement]: Updated dependencies, test with Go 1.23 to 1.25. - [Improvement]: Use Go 1.21's binary.NativeEndian (#220) diff --git a/vendor/github.com/mdlayher/netlink/align.go b/vendor/github.com/mdlayher/netlink/align.go index 20892c7016..4060df0403 100644 --- a/vendor/github.com/mdlayher/netlink/align.go +++ b/vendor/github.com/mdlayher/netlink/align.go @@ -8,14 +8,14 @@ import "unsafe" // #define NLMSG_ALIGNTO 4U const nlmsgAlignTo = 4 -// #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) -func nlmsgAlign(len int) int { - return ((len) + nlmsgAlignTo - 1) & ^(nlmsgAlignTo - 1) +// #define NLMSG_ALIGN(length) ( ((length)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) +func nlmsgAlign(length int) int { + return ((length) + nlmsgAlignTo - 1) & ^(nlmsgAlignTo - 1) } -// #define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN) -func nlmsgLength(len int) int { - return len + nlmsgHeaderLen +// #define NLMSG_LENGTH(length) ((length) + NLMSG_HDRLEN) +func nlmsgLength(length int) int { + return length + nlmsgHeaderLen } // #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) @@ -24,9 +24,9 @@ var nlmsgHeaderLen = nlmsgAlign(int(unsafe.Sizeof(Header{}))) // #define NLA_ALIGNTO 4 const nlaAlignTo = 4 -// #define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) -func nlaAlign(len int) int { - return ((len) + nlaAlignTo - 1) & ^(nlaAlignTo - 1) +// #define NLA_ALIGN(length) (((length) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1)) +func nlaAlign(length int) int { + return ((length) + nlaAlignTo - 1) & ^(nlaAlignTo - 1) } // Because this package's Attribute type contains a byte slice, unsafe.Sizeof diff --git a/vendor/github.com/mdlayher/netlink/attribute.go b/vendor/github.com/mdlayher/netlink/attribute.go index 1c81c323ce..ebc0b20055 100644 --- a/vendor/github.com/mdlayher/netlink/attribute.go +++ b/vendor/github.com/mdlayher/netlink/attribute.go @@ -34,8 +34,8 @@ func (a *Attribute) marshal(b []byte) (int, error) { return 0, errInvalidAttribute } - nlenc.PutUint16(b[0:2], a.Length) - nlenc.PutUint16(b[2:4], a.Type) + binary.NativeEndian.PutUint16(b[0:], a.Length) + binary.NativeEndian.PutUint16(b[2:], a.Type) n := copy(b[nlaHeaderLen:], a.Data) return nlaHeaderLen + nlaAlign(n), nil @@ -47,8 +47,8 @@ func (a *Attribute) unmarshal(b []byte) error { return errInvalidAttribute } - a.Length = nlenc.Uint16(b[0:2]) - a.Type = nlenc.Uint16(b[2:4]) + a.Length = binary.NativeEndian.Uint16(b[0:]) + a.Type = binary.NativeEndian.Uint16(b[2:]) if int(a.Length) > len(b) { return errInvalidAttribute @@ -243,7 +243,7 @@ func (ad *AttributeDecoder) available() (int, error) { } // Extract the length of the attribute. - l := int(nlenc.Uint16(ad.b[i : i+2])) + l := int(binary.NativeEndian.Uint16(ad.b[i:])) // Ignore zero-length attributes. if l != 0 { diff --git a/vendor/github.com/mdlayher/netlink/conn.go b/vendor/github.com/mdlayher/netlink/conn.go index a88efee92e..123081ed0a 100644 --- a/vendor/github.com/mdlayher/netlink/conn.go +++ b/vendor/github.com/mdlayher/netlink/conn.go @@ -1,6 +1,7 @@ package netlink import ( + "iter" "math/rand" "sync" "sync/atomic" @@ -31,6 +32,12 @@ type Conn struct { // transaction within Execute. mu sync.RWMutex + // receiveMu serializes concurrent Receive and ReceiveIter calls to prevent + // races in multi-part message handling and the peek/allocate logic in + // conn_linux.go. It is separate from mu so that Send can proceed + // concurrently with Receive. + receiveMu sync.Mutex + // sock is the operating system-specific implementation of // a netlink sockets connection. sock Socket @@ -53,6 +60,7 @@ type Socket interface { Send(m Message) error SendMessages(m []Message) error Receive() ([]Message, error) + ReceiveIter() iter.Seq2[Message, error] } // Dial dials a connection to netlink, using the specified netlink family. @@ -228,84 +236,130 @@ func (c *Conn) Receive() ([]Message, error) { c.mu.RLock() defer c.mu.RUnlock() + // Serialize concurrent Receive calls. See receiveMu for details. + c.receiveMu.Lock() + defer c.receiveMu.Unlock() + return c.lockedReceive() } +// ReceiveIter returns an iterator which can be used to receive messages from +// netlink. Just like Receive, multi-part messages are handled transparently and +// netlink errors are returned as errors from the iterator. +// +// If the iteration is stopped before all messages have been read and the +// response is multi-part, the remaining messages will be discarded. +func (c *Conn) ReceiveIter() iter.Seq2[Message, error] { + return func(yield func(Message, error) bool) { + // Wait for any concurrent calls to Execute to finish before proceeding. + c.mu.RLock() + defer c.mu.RUnlock() + + // Serialize concurrent ReceiveIter calls. See receiveMu for details. + c.receiveMu.Lock() + defer c.receiveMu.Unlock() + + for msg, err := range c.lockedReceiveIter() { + if err != nil { + c.debug(func(d *debugger) { + d.debugf(1, "recv: err: %v", err) + }) + yield(Message{}, err) + return + } + + c.debug(func(d *debugger) { + d.debugf(1, "recv: %+v", msg) + }) + if !yield(msg, nil) { + return + } + } + } +} + // lockedReceive implements Receive, but must be called with c.mu acquired for reading. // We rely on the kernel to deal with concurrent reads and writes to the netlink // socket itself. func (c *Conn) lockedReceive() ([]Message, error) { - msgs, err := c.receive() - if err != nil { - c.debug(func(d *debugger) { - d.debugf(1, "recv: err: %v", err) - }) - - return nil, err - } + var msgs []Message - c.debug(func(d *debugger) { - for _, m := range msgs { - d.debugf(1, "recv: %+v", m) + for m, err := range c.lockedReceiveIter() { + if err != nil { + c.debug(func(d *debugger) { + d.debugf(1, "recv: err: %v", err) + }) + return nil, err } - }) - // When using nltest, it's possible for zero messages to be returned by receive. - if len(msgs) == 0 { - return msgs, nil - } + c.debug(func(d *debugger) { + d.debugf(1, "recv: %+v", m) + }) - // Trim the final message with multi-part done indicator if - // present. - if m := msgs[len(msgs)-1]; m.Header.Flags&Multi != 0 && m.Header.Type == Done { - return msgs[:len(msgs)-1], nil + msgs = append(msgs, m) } return msgs, nil } -// receive is the internal implementation of Conn.Receive, which can be called -// recursively to handle multi-part messages. -func (c *Conn) receive() ([]Message, error) { - // NB: All non-nil errors returned from this function *must* be of type - // OpError in order to maintain the appropriate contract with callers of - // this package. - // - // This contract also applies to functions called within this function, - // such as checkMessage. - - var res []Message - for { - msgs, err := c.sock.Receive() - if err != nil { - return nil, newOpError("receive", err) - } - - // If this message is multi-part, we will need to continue looping to - // drain all the messages from the socket. - var multi bool - - for _, m := range msgs { - if err := checkMessage(m); err != nil { - return nil, err +// lockedReceiveIter returns an iterator which can be used to receive messages +// from netlink, but must be called with c.mu acquired for the duration of the +// iteration. +func (c *Conn) lockedReceiveIter() iter.Seq2[Message, error] { + return func(yield func(Message, error) bool) { + // NB: All non-nil errors returned from this function *must* be of type + // OpError in order to maintain the appropriate contract with callers of + // this package. + // + // This contract also applies to functions called within this function, + // such as checkMessage. + + var more, stopped bool + // send is a helper function to prevent yielding messages after the user + // has stopped iterating + var send = func(m Message, err error) { + if stopped { + return } - - // Does this message indicate a multi-part message? - if m.Header.Flags&Multi == 0 { - // No, check the next messages. - continue + if !yield(m, err) { + stopped = true } - - // Does this message indicate the last message in a series of - // multi-part messages from a single read? - multi = m.Header.Type != Done } - res = append(res, msgs...) + for { + for m, err := range c.sock.ReceiveIter() { + if err != nil { + send(Message{}, newOpError("receive", err)) + return + } + + if err := checkMessage(m); err != nil { + send(Message{}, err) + return + } + + // Exit early if we encounter a multi-part done message. + // This should be safe to do since messages of type Done should always + // be the last message in a datagram. + if m.Header.Type == Done && m.Header.Flags&Multi != 0 { + return + } + + if m.Header.Flags&Multi != 0 { + more = true + } + + send(m, nil) + if stopped && !more { + // The user has stopped iterating and there are no more messages + // to read. + return + } + } - if !multi { - // No more messages coming. - return res, nil + if !more { + return + } } } } @@ -631,4 +685,21 @@ type Config struct { // When possible, setting Strict to true is recommended for applications // running on modern Linux kernels. Strict bool + + // MessageBufferSize specifies a fixed buffer size for receiving netlink + // messages. When set, the connection will reuse a single pre-allocated + // buffer of this size instead of peeking at each message to determine + // the exact size needed. + // + // This is useful for high-throughput applications where the overhead of + // peeking at each message is undesirable and the maximum message size + // is known in advance. + // + // If set to 0 (the default), the connection will peek at the upcoming + // message before allocating a buffer for it. + // + // Note: this is not the same as the kernel socket receive buffer which + // can be configured using SetReadBuffer. MessageBufferSize only controls + // the userspace buffer passed to recvmsg. + MessageBufferSize int } diff --git a/vendor/github.com/mdlayher/netlink/conn_linux.go b/vendor/github.com/mdlayher/netlink/conn_linux.go index 1eab74af5f..c9618f553a 100644 --- a/vendor/github.com/mdlayher/netlink/conn_linux.go +++ b/vendor/github.com/mdlayher/netlink/conn_linux.go @@ -1,11 +1,12 @@ //go:build linux -// +build linux package netlink import ( "context" + "iter" "os" + "sync" "syscall" "time" "unsafe" @@ -19,7 +20,8 @@ var _ Socket = &conn{} // A conn is the Linux implementation of a netlink sockets connection. type conn struct { - s *socket.Conn + s *socket.Conn + pool *sync.Pool } // dial is the entry point for Dial. dial opens a netlink socket using @@ -71,6 +73,16 @@ func newConn(s *socket.Conn, config *Config) (*conn, uint32, error) { } c := &conn{s: s} + + if config.MessageBufferSize > 0 { + c.pool = &sync.Pool{ + New: func() any { + b := make([]byte, config.MessageBufferSize) + return &b + }, + } + } + if config.Strict { // The caller has requested the strict option set. Historically we have // recommended checking for ENOPROTOOPT if the kernel does not support @@ -121,48 +133,89 @@ func (c *conn) Send(m Message) error { // Receive receives one or more Messages from netlink. func (c *conn) Receive() ([]Message, error) { - b := make([]byte, os.Getpagesize()) - for { - // Peek at the buffer to see how many bytes are available. - // - // TODO(mdlayher): deal with OOB message data if available, such as - // when PacketInfo ConnOption is true. - n, _, _, _, err := c.s.Recvmsg(context.Background(), b, nil, unix.MSG_PEEK) + var msgs []Message + for msg, err := range c.ReceiveIter() { if err != nil { return nil, err } + msgs = append(msgs, msg) + } - // Break when we can read all messages - if n < len(b) { - break - } + return msgs, nil +} - // Double in size if not enough bytes - b = make([]byte, len(b)*2) +// getBuffer returns the buffer to use for receiving messages and a function to +// release it back to the pool if applicable. If the pool is not configured, a +// new buffer is allocated by peeking the size of the next message to be +// received. The buffer size is aligned to the next multiple of the alignment of a netlink +// message, to avoid panic when parsing messages from the buffer. +func (c *conn) getBuffer() ([]byte, func(), error) { + if c.pool != nil { + bp := c.pool.Get().(*[]byte) + return *bp, func() { c.pool.Put(bp) }, nil } - // Read out all available messages - n, _, _, _, err := c.s.Recvmsg(context.Background(), b, nil, 0) + n, _, _, _, err := c.s.Recvmsg(context.Background(), nil, nil, unix.MSG_PEEK|unix.MSG_TRUNC) if err != nil { - return nil, err + return nil, nil, err } - raw, err := syscall.ParseNetlinkMessage(b[:nlmsgAlign(n)]) - if err != nil { - return nil, err + return make([]byte, nlmsgAlign(n)), func() {}, nil +} + +// ownedBuffer trims b to the aligned size of the received datagram and, when +// using pooled buffers, copies it to memory owned by the caller. +func (c *conn) ownedBuffer(b []byte, n int) []byte { + aligned := nlmsgAlign(n) + if c.pool == nil { + return b[:aligned] } - msgs := make([]Message, 0, len(raw)) - for _, r := range raw { - m := Message{ - Header: sysToHeader(r.Header), - Data: r.Data, + // A pooled buffer may not have an aligned length. Copy the received bytes + // to an aligned buffer and let the zero-value tail bytes act as padding. + out := make([]byte, aligned) + copy(out, b[:n]) + return out +} + +// ReceiveIter returns an iterator over Messages received from netlink. +func (c *conn) ReceiveIter() iter.Seq2[Message, error] { + return func(yield func(Message, error) bool) { + b, release, err := c.getBuffer() + if err != nil { + yield(Message{}, err) + return } + defer release() - msgs = append(msgs, m) - } + // Read out all available messages + // TODO(mdlayher): deal with OOB message data if available, such as + // when PacketInfo ConnOption is true. + n, _, flags, _, err := c.s.Recvmsg(context.Background(), b, nil, 0) + if err != nil { + yield(Message{}, err) + return + } - return msgs, nil + if flags&unix.MSG_TRUNC != 0 { + // Our buffer was too small to read the entire message, + // this should not happen since we peeked above, but if it does, + // return an error. + yield(Message{}, errMessageTruncated) + return + } + + for msg, err := range parseMessagesIter(c.ownedBuffer(b, n)) { + if err != nil { + yield(Message{}, err) + return + } + + if !yield(msg, nil) { + return + } + } + } } // Close closes the connection. diff --git a/vendor/github.com/mdlayher/netlink/conn_others.go b/vendor/github.com/mdlayher/netlink/conn_others.go index 4c5e739b9e..5eb24c06fe 100644 --- a/vendor/github.com/mdlayher/netlink/conn_others.go +++ b/vendor/github.com/mdlayher/netlink/conn_others.go @@ -5,6 +5,7 @@ package netlink import ( "fmt" + "iter" "runtime" ) @@ -28,3 +29,8 @@ func (c *conn) Send(_ Message) error { return errUnimplemented } func (c *conn) SendMessages(_ []Message) error { return errUnimplemented } func (c *conn) Receive() ([]Message, error) { return nil, errUnimplemented } func (c *conn) Close() error { return errUnimplemented } +func (c *conn) ReceiveIter() iter.Seq2[Message, error] { + return func(yield func(Message, error) bool) { + yield(Message{}, errUnimplemented) + } +} diff --git a/vendor/github.com/mdlayher/netlink/debug.go b/vendor/github.com/mdlayher/netlink/debug.go index d39d66c58a..40ad2de776 100644 --- a/vendor/github.com/mdlayher/netlink/debug.go +++ b/vendor/github.com/mdlayher/netlink/debug.go @@ -4,7 +4,6 @@ import ( "fmt" "log" "os" - "strconv" "strings" ) @@ -23,47 +22,12 @@ func init() { // A debugger is used to provide debugging information about a netlink connection. type debugger struct { - Log *log.Logger - Level int + Log *log.Logger + Level int + Format string } -// newDebugger creates a debugger by parsing key=value arguments. -func newDebugger(args []string) *debugger { - d := &debugger{ - Log: log.New(os.Stderr, "nl: ", 0), - Level: 1, - } - - for _, a := range args { - kv := strings.Split(a, "=") - if len(kv) != 2 { - // Ignore malformed pairs and assume callers wants defaults. - continue - } - - switch kv[0] { - // Select the log level for the debugger. - case "level": - level, err := strconv.Atoi(kv[1]) - if err != nil { - panicf("netlink: invalid NLDEBUG level: %q", a) - } - - d.Level = level - } - } - - return d -} - -// debugf prints debugging information at the specified level, if d.Level is -// high enough to print the message. -func (d *debugger) debugf(level int, format string, v ...interface{}) { - if d.Level >= level { - d.Log.Printf(format, v...) - } -} - -func panicf(format string, a ...interface{}) { +// panicf is a helper to panic with formatted text. +func panicf(format string, a ...any) { panic(fmt.Sprintf(format, a...)) } diff --git a/vendor/github.com/mdlayher/netlink/debug_linux.go b/vendor/github.com/mdlayher/netlink/debug_linux.go new file mode 100644 index 0000000000..5dd7b2659c --- /dev/null +++ b/vendor/github.com/mdlayher/netlink/debug_linux.go @@ -0,0 +1,196 @@ +//go:build linux + +package netlink + +import ( + "encoding/binary" + "fmt" + "io" + "log" + "os" + "strconv" + "strings" + "syscall" + "unsafe" + + "golang.org/x/sys/unix" +) + +// newDebugger creates a debugger by parsing key=value arguments. +func newDebugger(args []string) *debugger { + d := &debugger{ + Log: log.New(os.Stderr, "nl: ", 0), + Level: 1, + Format: "mnl", + } + for _, a := range args { + kv := strings.Split(a, "=") + if len(kv) != 2 { + continue + } + switch kv[0] { + case "level": + level, err := strconv.Atoi(kv[1]) + if err != nil { + panicf("netlink: invalid NLDEBUG level: %q", a) + } + d.Level = level + case "format": + d.Format = kv[1] + } + } + return d +} + +// debugf prints debugging information at the specified level, if d.Level is high enough to print the message. +func (d *debugger) debugf(level int, format string, v ...any) { + if d.Level < level { + return + } + switch d.Format { + case "mnl": + colorize := true + _, err := unix.IoctlGetWinsize(int(os.Stdout.Fd()), unix.TIOCGWINSZ) + if err != nil { + colorize = false + } + for _, iface := range v { + if msg, ok := iface.(Message); ok { + nlmsgFprintf(d.Log.Writer(), msg, colorize) + } else { + d.Log.Printf(format, v...) + } + } + default: + d.Log.Printf(format, v...) + } +} + +// nlmsgFprintfHeader prints the netlink message header to fd. +func nlmsgFprintfHeader(fd io.Writer, nlh Header) { + fmt.Fprintf(fd, "----------------\t------------------\n") + fmt.Fprintf(fd, "| %010d |\t| message length |\n", nlh.Length) + fmt.Fprintf(fd, "| %05d | %s%s%s%s |\t| type | flags |\n", + nlh.Type, + ternary(nlh.Flags&Request != 0, "R", "-"), + ternary(nlh.Flags&Multi != 0, "M", "-"), + ternary(nlh.Flags&Acknowledge != 0, "A", "-"), + ternary(nlh.Flags&Echo != 0, "E", "-"), + ) + fmt.Fprintf(fd, "| %010d |\t| sequence number|\n", nlh.Sequence) + fmt.Fprintf(fd, "| %010d |\t| port ID |\n", nlh.PID) + fmt.Fprintf(fd, "----------------\t------------------\n") +} + +// nlmsgFprintf prints a single Message for netlink errors and attributes. +func nlmsgFprintf(fd io.Writer, m Message, colorize bool) { + var hasHeader bool + nlmsgFprintfHeader(fd, m.Header) + switch { + case m.Header.Type == Error: + hasHeader = true + case m.Header.Type == Done && m.Header.Flags&Multi != 0: + if len(m.Data) == 0 { + return + } + default: + // Neither, nothing to do. + } + // Errno occupies 4 bytes. + const endErrno = 4 + if len(m.Data) < endErrno { + return + } + + c := int32(binary.NativeEndian.Uint32(m.Data[:endErrno])) + if c != 0 { + b := m.Data[0:4] + fmt.Fprintf(fd, "| %.2x %.2x %.2x %.2x |\t", + 0xff&b[0], 0xff&b[1], + 0xff&b[2], 0xff&b[3]) + fmt.Fprintf(fd, "| extra header |\n") + } + + // Flags indicate an extended acknowledgement. The type/flags combination + // checked above determines the offset where the TLVs occur. + var off int + if hasHeader { + // There is an nlmsghdr preceding the TLVs. + if len(m.Data) < endErrno+nlmsgHeaderLen { + return + } + // The TLVs should be at the offset indicated by the nlmsghdr.length, + // plus the offset where the header began. But make sure the calculated + // offset is still in-bounds. + h := *(*Header)(unsafe.Pointer(&m.Data[endErrno : endErrno+nlmsgHeaderLen][0])) + off = endErrno + int(h.Length) + if len(m.Data) < off { + return + } + } else { + // There is no nlmsghdr preceding the TLVs, parse them directly. + off = endErrno + } + + data := m.Data[off:] + for i := 0; i < len(data); { + // Make sure there's at least a header's worth of data to read on each iteration. + if len(data[i:]) < nlaHeaderLen { + break + } + // Extract the length of the attribute. + l := int(binary.NativeEndian.Uint16(data[i:])) + // extract the type + t := binary.NativeEndian.Uint16(data[i+2:]) + // print attribute header + if colorize { + fmt.Fprintf(fd, "|\033[1;31m%05d|\033[1;32m%s%s|\033[1;34m%05d\033[0m|\t", + l, + ternary(t&syscall.NLA_F_NESTED != 0, "N", "-"), + ternary(t&syscall.NLA_F_NET_BYTEORDER != 0, "B", "-"), + t&attrTypeMask) + fmt.Fprintf(fd, "|len |flags| type|\n") + } else { + fmt.Fprintf(fd, "|%05d|%s%s|%05d|\t", + l, + ternary(t&syscall.NLA_F_NESTED != 0, "N", "-"), + ternary(t&syscall.NLA_F_NET_BYTEORDER != 0, "B", "-"), + t&attrTypeMask) + fmt.Fprintf(fd, "|len |flags| type|\n") + } + + nextAttr := i + nlaAlign(l) + i += nlaHeaderLen + + // Ignore zero-length attributes. + if l == 0 { + continue + } + // If nested check the next attribute + if t&syscall.NLA_F_NESTED != 0 { + continue + } + // Print the remaining attributes bytes + for ; i < nextAttr; i += 4 { + fmt.Fprintf(fd, "| %.2x %.2x %.2x %.2x |\t", + 0xff&data[i], 0xff&data[i+1], + 0xff&data[i+2], 0xff&data[i+3]) + fmt.Fprintf(fd, "| data |") + fmt.Fprintf(fd, "\t %s %s %s %s\n", + ternary(strconv.IsPrint(rune(data[i])), string(data[i]), " "), + ternary(strconv.IsPrint(rune(data[i+1])), string(data[i+1]), " "), + ternary(strconv.IsPrint(rune(data[i+2])), string(data[i+2]), " "), + ternary(strconv.IsPrint(rune(data[i+3])), string(data[i+3]), " "), + ) + } + } + fmt.Fprintf(fd, "----------------\t------------------\n") +} + +// ternary returns iftrue if cond is true, else iffalse. +func ternary(cond bool, iftrue string, iffalse string) string { + if cond { + return iftrue + } + return iffalse +} diff --git a/vendor/github.com/mdlayher/netlink/debug_others.go b/vendor/github.com/mdlayher/netlink/debug_others.go new file mode 100644 index 0000000000..8732c639b9 --- /dev/null +++ b/vendor/github.com/mdlayher/netlink/debug_others.go @@ -0,0 +1,40 @@ +//go:build !linux + +package netlink + +import ( + "log" + "os" + "strconv" + "strings" +) + +// newDebugger creates a debugger by parsing key=value arguments. +func newDebugger(args []string) *debugger { + d := &debugger{ + Log: log.New(os.Stderr, "nl: ", 0), + Level: 1, + } + for _, a := range args { + kv := strings.Split(a, "=") + if len(kv) != 2 { + continue + } + switch kv[0] { + case "level": + level, err := strconv.Atoi(kv[1]) + if err != nil { + panicf("netlink: invalid NLDEBUG level: %q", a) + } + d.Level = level + } + } + return d +} + +// debugf prints debugging information at the specified level, if d.Level is high enough to print the message. +func (d *debugger) debugf(level int, format string, v ...interface{}) { + if d.Level >= level { + d.Log.Printf(format, v...) + } +} diff --git a/vendor/github.com/mdlayher/netlink/doc.go b/vendor/github.com/mdlayher/netlink/doc.go index 98c744a5d8..f0c51c7be6 100644 --- a/vendor/github.com/mdlayher/netlink/doc.go +++ b/vendor/github.com/mdlayher/netlink/doc.go @@ -27,7 +27,10 @@ // // $ NLDEBUG=level=1 ./nlctl // +// $ NLDEBUG=level=1,format=mnl ./nlctl +// // Available key/value debugger options include: // // level=N: specify the debugging level (only "1" is currently supported) +// format=mnl: specify the same format used by libmnl (nft --debug=all) package netlink diff --git a/vendor/github.com/mdlayher/netlink/errors.go b/vendor/github.com/mdlayher/netlink/errors.go index e1fe0ab349..0f1b468b19 100644 --- a/vendor/github.com/mdlayher/netlink/errors.go +++ b/vendor/github.com/mdlayher/netlink/errors.go @@ -20,6 +20,10 @@ var ( var errNotSupported = errors.New("operation not supported") +// errMessageTruncated is returned when a received message was truncated +// because the receive buffer was too small. +var errMessageTruncated = errors.New("message truncated") + // notSupported provides a concise constructor for "not supported" errors. func notSupported(op string) error { return newOpError(op, errNotSupported) @@ -95,11 +99,11 @@ func (e *OpError) Error() string { } var sb strings.Builder - _, _ = sb.WriteString(fmt.Sprintf("netlink %s: %v", e.Op, e.Err)) + _, _ = fmt.Fprintf(&sb, "netlink %s: %v", e.Op, e.Err) if e.Message != "" || e.Offset != 0 { - _, _ = sb.WriteString(fmt.Sprintf(", offset: %d, message: %q", - e.Offset, e.Message)) + _, _ = fmt.Fprintf(&sb, ", offset: %d, message: %q", + e.Offset, e.Message) } return sb.String() @@ -120,7 +124,8 @@ type timeout interface { // Timeout reports whether the error was caused by an I/O timeout. func (e *OpError) Timeout() bool { - if ne, ok := e.Err.(*os.SyscallError); ok { + ne := &os.SyscallError{} + if errors.As(e.Err, &ne) { t, ok := ne.Err.(timeout) return ok && t.Timeout() } @@ -134,7 +139,8 @@ type temporary interface { // Temporary reports whether an operation may succeed if retried. func (e *OpError) Temporary() bool { - if ne, ok := e.Err.(*os.SyscallError); ok { + ne := &os.SyscallError{} + if errors.As(e.Err, &ne) { t, ok := ne.Err.(temporary) return ok && t.Temporary() } diff --git a/vendor/github.com/mdlayher/netlink/message.go b/vendor/github.com/mdlayher/netlink/message.go index 6cfefd59c8..9ec4501c41 100644 --- a/vendor/github.com/mdlayher/netlink/message.go +++ b/vendor/github.com/mdlayher/netlink/message.go @@ -1,11 +1,11 @@ package netlink import ( + "encoding/binary" "errors" "fmt" + "iter" "unsafe" - - "github.com/mdlayher/netlink/nlenc" ) // Flags which may apply to netlink attribute types when communicating with @@ -211,11 +211,11 @@ func (m Message) MarshalBinary() ([]byte, error) { b := make([]byte, ml) - nlenc.PutUint32(b[0:4], m.Header.Length) - nlenc.PutUint16(b[4:6], uint16(m.Header.Type)) - nlenc.PutUint16(b[6:8], uint16(m.Header.Flags)) - nlenc.PutUint32(b[8:12], m.Header.Sequence) - nlenc.PutUint32(b[12:16], m.Header.PID) + binary.NativeEndian.PutUint32(b[0:], m.Header.Length) + binary.NativeEndian.PutUint16(b[4:], uint16(m.Header.Type)) + binary.NativeEndian.PutUint16(b[6:], uint16(m.Header.Flags)) + binary.NativeEndian.PutUint32(b[8:], m.Header.Sequence) + binary.NativeEndian.PutUint32(b[12:], m.Header.PID) copy(b[16:], m.Data) return b, nil @@ -231,16 +231,16 @@ func (m *Message) UnmarshalBinary(b []byte) error { } // Don't allow misleading length - m.Header.Length = nlenc.Uint32(b[0:4]) - if int(m.Header.Length) != len(b) { + m.Header.Length = binary.NativeEndian.Uint32(b[0:]) + if int(m.Header.Length) < nlmsgHeaderLen || int(m.Header.Length) > len(b) { return errShortMessage } - m.Header.Type = HeaderType(nlenc.Uint16(b[4:6])) - m.Header.Flags = HeaderFlags(nlenc.Uint16(b[6:8])) - m.Header.Sequence = nlenc.Uint32(b[8:12]) - m.Header.PID = nlenc.Uint32(b[12:16]) - m.Data = b[16:] + m.Header.Type = HeaderType(binary.NativeEndian.Uint16(b[4:])) + m.Header.Flags = HeaderFlags(binary.NativeEndian.Uint16(b[6:])) + m.Header.Sequence = binary.NativeEndian.Uint32(b[8:]) + m.Header.PID = binary.NativeEndian.Uint32(b[12:]) + m.Data = b[nlmsgHeaderLen:m.Header.Length] return nil } @@ -282,7 +282,7 @@ func checkMessage(m Message) error { return newOpError("receive", errShortErrorMessage) } - c := nlenc.Int32(m.Data[:endErrno]) + c := int32(binary.NativeEndian.Uint32(m.Data[:endErrno])) if c == 0 { // 0 indicates no error. return nil @@ -346,3 +346,41 @@ func checkMessage(m Message) error { // the info we have. return oerr } + +// parseMessagesIter returns an iterator over netlink messages in b. +// Each iteration yields a Message and any error encountered during parsing. +// The iterator stops on the first error or when all messages are parsed. +// +// If b is less that NLMSG_HDRLEN bytes, no error or messages will be returned. +// The same applies for any trailing bytes whose length is less than +// NLMSG_HDRLEN. +func parseMessagesIter(b []byte) iter.Seq2[Message, error] { + return func(yield func(Message, error) bool) { + for len(b) >= nlmsgHeaderLen { + length := binary.NativeEndian.Uint32(b[0:]) + if int(length) < nlmsgHeaderLen { + yield(Message{}, errIncorrectMessageLength) + return + } + + alength := nlmsgAlign(int(length)) + if alength > len(b) { + yield(Message{}, errShortMessage) + return + } + + var message Message + if err := message.UnmarshalBinary(b[:alength]); err != nil { + yield(Message{}, err) + return + } + + // Return if the consumer has stopped iterating. + if !yield(message, nil) { + return + } + + b = b[alength:] + } + } +} diff --git a/vendor/github.com/mdlayher/netlink/nlenc/doc.go b/vendor/github.com/mdlayher/netlink/nlenc/doc.go index 990d12e64f..947d10f890 100644 --- a/vendor/github.com/mdlayher/netlink/nlenc/doc.go +++ b/vendor/github.com/mdlayher/netlink/nlenc/doc.go @@ -7,6 +7,8 @@ import ( ) // NativeEndian returns the native byte order of this system. +// +// Deprecated: Use [binary.NativeEndian] instead. func NativeEndian() binary.ByteOrder { // TODO(mdlayher): consider deprecating and removing this function for v2. return binary.NativeEndian diff --git a/vendor/github.com/mdlayher/netlink/nlenc/int.go b/vendor/github.com/mdlayher/netlink/nlenc/int.go index d56b018dec..3bd99d7415 100644 --- a/vendor/github.com/mdlayher/netlink/nlenc/int.go +++ b/vendor/github.com/mdlayher/netlink/nlenc/int.go @@ -1,12 +1,14 @@ package nlenc import ( + "encoding/binary" "fmt" - "unsafe" ) // PutUint8 encodes a uint8 into b. // If b is not exactly 1 byte in length, PutUint8 will panic. +// +// Deprecated: Use inline "b[n] = v" instead. func PutUint8(b []byte, v uint8) { if l := len(b); l != 1 { panic(fmt.Sprintf("PutUint8: unexpected byte slice length: %d", l)) @@ -17,46 +19,56 @@ func PutUint8(b []byte, v uint8) { // PutUint16 encodes a uint16 into b using the host machine's native endianness. // If b is not exactly 2 bytes in length, PutUint16 will panic. +// +// Deprecated: Use [binary.NativeEndian.PutUint16] instead. func PutUint16(b []byte, v uint16) { if l := len(b); l != 2 { panic(fmt.Sprintf("PutUint16: unexpected byte slice length: %d", l)) } - *(*uint16)(unsafe.Pointer(&b[0])) = v + binary.NativeEndian.PutUint16(b, v) } // PutUint32 encodes a uint32 into b using the host machine's native endianness. // If b is not exactly 4 bytes in length, PutUint32 will panic. +// +// Deprecated: Use [binary.NativeEndian.PutUint32] instead. func PutUint32(b []byte, v uint32) { if l := len(b); l != 4 { panic(fmt.Sprintf("PutUint32: unexpected byte slice length: %d", l)) } - *(*uint32)(unsafe.Pointer(&b[0])) = v + binary.NativeEndian.PutUint32(b, v) } // PutUint64 encodes a uint64 into b using the host machine's native endianness. // If b is not exactly 8 bytes in length, PutUint64 will panic. +// +// Deprecated: Use [binary.NativeEndian.PutUint64] instead. func PutUint64(b []byte, v uint64) { if l := len(b); l != 8 { panic(fmt.Sprintf("PutUint64: unexpected byte slice length: %d", l)) } - *(*uint64)(unsafe.Pointer(&b[0])) = v + binary.NativeEndian.PutUint64(b, v) } // PutInt32 encodes a int32 into b using the host machine's native endianness. // If b is not exactly 4 bytes in length, PutInt32 will panic. +// +// Deprecated: Use [binary.NativeEndian.PutUint32] instead (with a typecast). func PutInt32(b []byte, v int32) { if l := len(b); l != 4 { panic(fmt.Sprintf("PutInt32: unexpected byte slice length: %d", l)) } - *(*int32)(unsafe.Pointer(&b[0])) = v + binary.NativeEndian.PutUint32(b, uint32(v)) } // Uint8 decodes a uint8 from b. // If b is not exactly 1 byte in length, Uint8 will panic. +// +// Deprecated: Use inline "b[n]" instead. func Uint8(b []byte) uint8 { if l := len(b); l != 1 { panic(fmt.Sprintf("Uint8: unexpected byte slice length: %d", l)) @@ -67,50 +79,58 @@ func Uint8(b []byte) uint8 { // Uint16 decodes a uint16 from b using the host machine's native endianness. // If b is not exactly 2 bytes in length, Uint16 will panic. +// +// Deprecated: Use [binary.NativeEndian.Uint16] instead. func Uint16(b []byte) uint16 { if l := len(b); l != 2 { panic(fmt.Sprintf("Uint16: unexpected byte slice length: %d", l)) } - return *(*uint16)(unsafe.Pointer(&b[0])) + return binary.NativeEndian.Uint16(b) } // Uint32 decodes a uint32 from b using the host machine's native endianness. // If b is not exactly 4 bytes in length, Uint32 will panic. +// +// Deprecated: Use [binary.NativeEndian.Uint32] instead. func Uint32(b []byte) uint32 { if l := len(b); l != 4 { panic(fmt.Sprintf("Uint32: unexpected byte slice length: %d", l)) } - return *(*uint32)(unsafe.Pointer(&b[0])) + return binary.NativeEndian.Uint32(b) } // Uint64 decodes a uint64 from b using the host machine's native endianness. // If b is not exactly 8 bytes in length, Uint64 will panic. +// +// Deprecated: Use [binary.NativeEndian.Uint64] instead. func Uint64(b []byte) uint64 { if l := len(b); l != 8 { panic(fmt.Sprintf("Uint64: unexpected byte slice length: %d", l)) } - return *(*uint64)(unsafe.Pointer(&b[0])) + return binary.NativeEndian.Uint64(b) } // Int32 decodes an int32 from b using the host machine's native endianness. // If b is not exactly 4 bytes in length, Int32 will panic. +// +// Deprecated: Use [binary.NativeEndian.Uint32] instead (with a typecast). func Int32(b []byte) int32 { if l := len(b); l != 4 { panic(fmt.Sprintf("Int32: unexpected byte slice length: %d", l)) } - return *(*int32)(unsafe.Pointer(&b[0])) + return int32(binary.NativeEndian.Uint32(b)) } // Uint8Bytes encodes a uint8 into a newly-allocated byte slice. It is a // shortcut for allocating a new byte slice and filling it using PutUint8. +// +// Deprecated: Use inline "[]byte{v}" instead. func Uint8Bytes(v uint8) []byte { - b := make([]byte, 1) - PutUint8(b, v) - return b + return []byte{v} } // Uint16Bytes encodes a uint16 into a newly-allocated byte slice using the @@ -118,7 +138,7 @@ func Uint8Bytes(v uint8) []byte { // byte slice and filling it using PutUint16. func Uint16Bytes(v uint16) []byte { b := make([]byte, 2) - PutUint16(b, v) + binary.NativeEndian.PutUint16(b, v) return b } @@ -127,7 +147,7 @@ func Uint16Bytes(v uint16) []byte { // byte slice and filling it using PutUint32. func Uint32Bytes(v uint32) []byte { b := make([]byte, 4) - PutUint32(b, v) + binary.NativeEndian.PutUint32(b, v) return b } @@ -136,7 +156,7 @@ func Uint32Bytes(v uint32) []byte { // byte slice and filling it using PutUint64. func Uint64Bytes(v uint64) []byte { b := make([]byte, 8) - PutUint64(b, v) + binary.NativeEndian.PutUint64(b, v) return b } @@ -145,6 +165,6 @@ func Uint64Bytes(v uint64) []byte { // byte slice and filling it using PutInt32. func Int32Bytes(v int32) []byte { b := make([]byte, 4) - PutInt32(b, v) + binary.NativeEndian.PutUint32(b, uint32(v)) return b } diff --git a/vendor/github.com/mdlayher/netlink/nltest/errors_unix.go b/vendor/github.com/mdlayher/netlink/nltest/errors_unix.go index f54403bb08..8b638da757 100644 --- a/vendor/github.com/mdlayher/netlink/nltest/errors_unix.go +++ b/vendor/github.com/mdlayher/netlink/nltest/errors_unix.go @@ -1,11 +1,15 @@ //go:build !plan9 && !windows -// +build !plan9,!windows package nltest -import "golang.org/x/sys/unix" +import ( + "errors" + + "golang.org/x/sys/unix" +) func isSyscallError(err error) bool { - _, ok := err.(unix.Errno) + var errno unix.Errno + ok := errors.As(err, &errno) return ok } diff --git a/vendor/github.com/mdlayher/netlink/nltest/nltest.go b/vendor/github.com/mdlayher/netlink/nltest/nltest.go index 2065bab02a..143e4ca2f4 100644 --- a/vendor/github.com/mdlayher/netlink/nltest/nltest.go +++ b/vendor/github.com/mdlayher/netlink/nltest/nltest.go @@ -2,8 +2,10 @@ package nltest import ( + "errors" "fmt" "io" + "iter" "os" "github.com/mdlayher/netlink" @@ -149,59 +151,99 @@ func (c *socket) Send(m netlink.Message) error { } func (c *socket) Receive() ([]netlink.Message, error) { - // No messages set by Send means that we are emulating a - // multicast response or an error occurred. - if len(c.msgs) == 0 { - switch c.err { - case nil: - // No error, simulate multicast, but also return EOF to simulate - // no replies if needed. - msgs, err := c.fn(nil) - if err == io.EOF { - err = nil + var msgs []netlink.Message + for msg, err := range c.ReceiveIter() { + if err != nil { + return nil, err + } + msgs = append(msgs, msg) + } + + return msgs, nil +} + +func (c *socket) ReceiveIter() iter.Seq2[netlink.Message, error] { + return func(yield func(netlink.Message, error) bool) { + // No messages set by Send means that we are emulating a + // multicast response or an error occurred. + if len(c.msgs) == 0 { + switch { + case c.err == nil: + msgs, err := c.fn(nil) + if errors.Is(err, io.EOF) { + return + } + if err != nil { + yield(netlink.Message{}, err) + return + } + for _, m := range msgs { + if !yield(m, nil) { + return + } + } + return + case errors.Is(c.err, io.EOF): + return + } + + // If the error is a system call error, wrap it in os.NewSyscallError + // to simulate what the Linux netlink.Conn does. + if isSyscallError(c.err) { + err := c.err + c.err = nil + yield(netlink.Message{}, os.NewSyscallError("recvmsg", err)) + return } - return msgs, err - case io.EOF: - // EOF, simulate no replies in multi-part message. - return nil, nil + // Some generic error occurred and should be passed to the caller. + err := c.err + c.err = nil + yield(netlink.Message{}, err) + return } - // If the error is a system call error, wrap it in os.NewSyscallError - // to simulate what the Linux netlink.Conn does. - if isSyscallError(c.err) { - return nil, os.NewSyscallError("recvmsg", c.err) + // Detect multi-part messages. + var multi bool + for _, m := range c.msgs { + if m.Header.Flags&netlink.Multi != 0 && m.Header.Type != netlink.Done { + multi = true + } } - // Some generic error occurred and should be passed to the caller. - return nil, c.err - } + // When a multi-part message is detected, the messages are returned in + // batches of half the total messages, so that multiple calls to Receive or + // ReceiveIter from netlink.Conn are needed to drain all messages. + if multi { + batchSize := (len(c.msgs) + 1) / 2 + batch := c.msgs[:batchSize] + c.msgs = c.msgs[batchSize:] + + for _, m := range batch { + if !yield(m, nil) { + return + } + } - // Detect multi-part messages. - var multi bool - for _, m := range c.msgs { - if m.Header.Flags&netlink.Multi != 0 && m.Header.Type != netlink.Done { - multi = true + return } - } - // When a multi-part message is detected, return all messages except for the - // final "multi-part done", so that a second call to Receive from netlink.Conn - // will drain that message. - if multi { - last := c.msgs[len(c.msgs)-1] - ret := c.msgs[:len(c.msgs)-1] - c.msgs = []netlink.Message{last} - - return ret, c.err - } + msgs, err := c.msgs, c.err + c.msgs, c.err = nil, nil - msgs, err := c.msgs, c.err - c.msgs, c.err = nil, nil + if err != nil { + yield(netlink.Message{}, err) + return + } - return msgs, err + for _, m := range msgs { + if !yield(m, nil) { + return + } + } + } } -func panicf(format string, a ...interface{}) { +func panicf(format string, a ...any) { panic(fmt.Sprintf(format, a...)) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go index 368625c6a8..c28af5ce2b 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go @@ -372,12 +372,15 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO return false } - // Build metric name filter set from query params (if any) + // Build metric name filter set from query params (if any). The URL + // can be nil on hand-constructed requests. var metricFilter map[string]struct{} - if metricNames := req.URL.Query()["name[]"]; len(metricNames) > 0 { - metricFilter = make(map[string]struct{}, len(metricNames)) - for _, name := range metricNames { - metricFilter[name] = struct{}{} + if req.URL != nil { + if metricNames := req.URL.Query()["name[]"]; len(metricNames) > 0 { + metricFilter = make(map[string]struct{}, len(metricNames)) + for _, name := range metricNames { + metricFilter[name] = struct{}{} + } } } diff --git a/vendor/golang.org/x/tools/cmd/goimports/goimports.go b/vendor/golang.org/x/tools/cmd/goimports/goimports.go index f7dec9bef7..e796905a91 100644 --- a/vendor/golang.org/x/tools/cmd/goimports/goimports.go +++ b/vendor/golang.org/x/tools/cmd/goimports/goimports.go @@ -19,6 +19,7 @@ import ( "runtime" "runtime/pprof" "strings" + "testing" "golang.org/x/telemetry/counter" "golang.org/x/tools/internal/gocommand" @@ -199,7 +200,8 @@ func walkDir(path string) { } func main() { - // is anyone using this command? + // Measure how many people still use goimports. + // (See https://go.dev/issue/78671 for one.) counter.Open() counter.Inc("tools/cmd:goimports") runtime.GOMAXPROCS(runtime.NumCPU()) @@ -208,7 +210,9 @@ func main() { // so that it can use defer and have them // run before the exit. gofmtMain() - os.Exit(exitCode) + if !testing.Testing() { + os.Exit(exitCode) + } } // parseFlags parses command line flags and returns the paths to process. diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go index 0d6d0bced0..9c7401c9ba 100644 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -30,6 +30,7 @@ import ( "slices" "strconv" "strings" + "sync" "golang.org/x/tools/internal/typesinternal" ) @@ -126,7 +127,8 @@ func For(obj types.Object) (Path, error) { // An Encoder amortizes the cost of encoding the paths of multiple objects. // The zero value of an Encoder is ready to use. type Encoder struct { - pkgIndex map[*types.Package]*pkgIndex + pkgIndexMu sync.Mutex + pkgIndex map[*types.Package]*pkgIndex } // A traversal encapsulates the state of a single traversal of the object/type graph. @@ -191,6 +193,8 @@ type pkgIndex struct { // For returns the path to an object relative to its package, // or an error if the object is not accessible from the package's Scope. // +// For is safe for concurrent use. +// // The For function guarantees to return a path only for the following objects: // - package-level types // - exported package-level non-types @@ -320,6 +324,9 @@ func (enc *Encoder) For(obj types.Object) (Path, error) { panic(obj) } + enc.pkgIndexMu.Lock() + defer enc.pkgIndexMu.Unlock() + // 4. Search the object/type graph for the path to // the var (field/param/result) or method. ix, ok := enc.pkgIndex[pkg] diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go index b99ea6c914..6aa1e27e3a 100644 --- a/vendor/golang.org/x/tools/internal/imports/fix.go +++ b/vendor/golang.org/x/tools/internal/imports/fix.go @@ -32,6 +32,7 @@ import ( "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/gopathwalk" + "golang.org/x/tools/internal/modindex" "golang.org/x/tools/internal/stdlib" ) @@ -320,6 +321,7 @@ func (p *pass) importIdentifier(imp *ImportInfo) string { // load reads in everything necessary to run a pass, and reports whether the // file already has all the imports it needs. It fills in p.missingRefs with the // file's missing symbols, if any, or removes unused imports if not. +// This is called 3(!) times: self, otherFiles, loadRealPackageNames func (p *pass) load(ctx context.Context) ([]*ImportFix, bool) { p.knownPackages = map[string]*PackageInfo{} p.missingRefs = References{} @@ -577,6 +579,17 @@ func getFixes(ctx context.Context, fset *token.FileSet, f *ast.File, filename st } func getFixesWithSource(ctx context.Context, fset *token.FileSet, f *ast.File, filename string, goroot string, logf func(string, ...any), source Source) ([]*ImportFix, error) { + // If there is an Index for the GOMODCACHE, remember that, and later make it so that the + // directory walk doesn't go into the module cache, since we already have all the information + var ix *modindex.Index + src, ok := source.(*ProcessEnvSource) + if ok { + var err error + if ix, err = modindex.Read(src.env.Env["GOMODCACHE"]); err != nil { + ix = nil // don't use it if there was an error + } + } + // This logic is defensively duplicated from getFixes. abs, err := filepath.Abs(filename) if err != nil { @@ -635,6 +648,20 @@ func getFixesWithSource(ctx context.Context, fset *token.FileSet, f *ast.File, f } p.loadRealPackageNames = true p.otherFiles = otherFiles + if ix != nil { + src, ok := p.source.(*ProcessEnvSource) + if ok { + // For safety, clone the env so that we don't modify the caller's env. + env := *src.env + env.Env = maps.Clone(src.env.Env) + src.env = &env + // avoid looking in the module cache, as we have the index instead: + // This makes a later call to newModuleresolver (from + // LoadPackageNames) produce a resolver that will not look + // in the module cache + src.env.Env["GOMODCACHE"] = "" + } + } if fixes, done := p.load(ctx); done { return fixes, nil } @@ -649,7 +676,7 @@ func getFixesWithSource(ctx context.Context, fset *token.FileSet, f *ast.File, f // Go look for candidates in $GOPATH, etc. We don't necessarily load // the real exports of sibling imports, so keep assuming their contents. - if err := addExternalCandidates(ctx, p, p.missingRefs, filename); err != nil { + if err := addExternalCandidates(ctx, p, p.missingRefs, filename, ix); err != nil { return nil, err } @@ -1184,7 +1211,7 @@ type scanCallback struct { exportsLoaded func(pkg *pkg, exports []stdlib.Symbol) } -func addExternalCandidates(ctx context.Context, pass *pass, refs References, filename string) error { +func addExternalCandidates(ctx context.Context, pass *pass, refs References, filename string, ix *modindex.Index) error { ctx, done := event.Start(ctx, "imports.addExternalCandidates") defer done() @@ -1193,6 +1220,24 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs References, fil return err } + // Add candidates from the module cache. + if ix != nil { + for k, v := range refs { + for n := range v { + cands := ix.Lookup(k, n, false) + for _, cand := range cands { + x := &Result{ + &ImportInfo{ImportPath: cand.ImportPath}, + &PackageInfo{Name: cand.PkgName, + Exports: map[string]bool{cand.Name: true}, + }, + } + results = append(results, x) + } + } + } + } + for _, result := range results { if result == nil { continue diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go index 76fae6a74b..a05faf9716 100644 --- a/vendor/golang.org/x/tools/internal/imports/mod.go +++ b/vendor/golang.org/x/tools/internal/imports/mod.go @@ -166,10 +166,7 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe } } - r.moduleCacheDir = gomodcacheForEnv(goenv) - if r.moduleCacheDir == "" { - return nil, fmt.Errorf("cannot resolve GOMODCACHE") - } + r.moduleCacheDir = goenv["GOMODCACHE"] sort.Slice(r.modsByModPath, func(i, j int) bool { count := func(x int) int { @@ -238,26 +235,6 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe return r, nil } -// gomodcacheForEnv returns the GOMODCACHE value to use based on the given env -// map, which must have GOMODCACHE and GOPATH populated. -// -// TODO(rfindley): this is defensive refactoring. -// 1. Is this even relevant anymore? Can't we just read GOMODCACHE. -// 2. Use this to separate module cache scanning from other scanning. -func gomodcacheForEnv(goenv map[string]string) string { - if gmc := goenv["GOMODCACHE"]; gmc != "" { - // golang/go#67156: ensure that the module cache is clean, since it is - // assumed as a prefix to directories scanned by gopathwalk, which are - // themselves clean. - return filepath.Clean(gmc) - } - gopaths := filepath.SplitList(goenv["GOPATH"]) - if len(gopaths) == 0 { - return "" - } - return filepath.Join(gopaths[0], "/pkg/mod") -} - func (r *ModuleResolver) initAllMods() error { stdout, err := r.env.invokeGo(context.TODO(), "list", "-m", "-e", "-json", "...") if err != nil { diff --git a/vendor/golang.org/x/tools/internal/imports/source_env.go b/vendor/golang.org/x/tools/internal/imports/source_env.go index ec996c3ccf..272ae80610 100644 --- a/vendor/golang.org/x/tools/internal/imports/source_env.go +++ b/vendor/golang.org/x/tools/internal/imports/source_env.go @@ -53,7 +53,7 @@ func (s *ProcessEnvSource) ResolveReferences(ctx context.Context, filename strin found := make(map[string][]pkgDistance) callback := &scanCallback{ rootFound: func(gopathwalk.Root) bool { - return true // We want everything. + return true }, dirFound: func(pkg *pkg) bool { return pkgIsCandidate(filename, refs, pkg) diff --git a/vendor/golang.org/x/tools/internal/modindex/directories.go b/vendor/golang.org/x/tools/internal/modindex/directories.go new file mode 100644 index 0000000000..9a963744b5 --- /dev/null +++ b/vendor/golang.org/x/tools/internal/modindex/directories.go @@ -0,0 +1,131 @@ +// Copyright 2024 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 modindex + +import ( + "fmt" + "log" + "os" + "path/filepath" + "regexp" + "strings" + "sync" + "time" + + "golang.org/x/mod/semver" + "golang.org/x/tools/internal/gopathwalk" +) + +type directory struct { + path string // relative to GOMODCACHE + importPath string + version string // semantic version +} + +// bestDirByImportPath returns the best directory for each import +// path, where "best" means most recent semantic version. These import +// paths are inferred from the GOMODCACHE-relative dir names in dirs. +func bestDirByImportPath(dirs []string) (map[string]directory, error) { + dirsByPath := make(map[string]directory) + for _, dir := range dirs { + importPath, version, err := dirToImportPathVersion(dir) + if err != nil { + return nil, err + } + new := directory{ + path: dir, + importPath: importPath, + version: version, + } + if old, ok := dirsByPath[importPath]; !ok || compareDirectory(new, old) < 0 { + dirsByPath[importPath] = new + } + } + return dirsByPath, nil +} + +// compareDirectory defines an ordering of path@version directories, +// by descending version, then by ascending path. +func compareDirectory(x, y directory) int { + if sign := -semver.Compare(x.version, y.version); sign != 0 { + return sign // latest first + } + return strings.Compare(string(x.path), string(y.path)) +} + +// modCacheRegexp splits a relpathpath into module, module version, and package. +var modCacheRegexp = regexp.MustCompile(`(.*)@([^/\\]*)(.*)`) + +// dirToImportPathVersion computes import path and semantic version +// from a GOMODCACHE-relative directory name. +func dirToImportPathVersion(dir string) (string, string, error) { + m := modCacheRegexp.FindStringSubmatch(string(dir)) + // m[1] is the module path + // m[2] is the version major.minor.patch(-
 1 && flds[1][1] == 'D',
+			}
+			if px.Type == Func {
+				n, err := strconv.Atoi(flds[2])
+				if err != nil {
+					continue // should never happen
+				}
+				px.Results = int16(n)
+				if len(flds) >= 4 {
+					sig := strings.Split(flds[3], " ")
+					for i := range sig {
+						// $ cannot otherwise occur. removing the spaces
+						// almost works, but for chan struct{}, e.g.
+						sig[i] = strings.Replace(sig[i], "$", " ", -1)
+					}
+					px.Sig = toFields(sig)
+				}
+			}
+			ans = append(ans, px)
+		}
+	}
+	return ans
+}
+
+func toFields(sig []string) []Field {
+	ans := make([]Field, len(sig)/2)
+	for i := range ans {
+		ans[i] = Field{Arg: sig[2*i], Type: sig[2*i+1]}
+	}
+	return ans
+}
+
+// benchmarks show this is measurably better than strings.Split
+// split into first 4 fields separated by single space
+func fastSplit(x string) []string {
+	ans := make([]string, 0, 4)
+	nxt := 0
+	start := 0
+	for i := 0; i < len(x); i++ {
+		if x[i] != ' ' {
+			continue
+		}
+		ans = append(ans, x[start:i])
+		nxt++
+		start = i + 1
+		if nxt >= 3 {
+			break
+		}
+	}
+	ans = append(ans, x[start:])
+	return ans
+}
+
+func asLexType(c byte) LexType {
+	switch c {
+	case 'C':
+		return Const
+	case 'V':
+		return Var
+	case 'T':
+		return Type
+	case 'F':
+		return Func
+	}
+	return -1
+}
diff --git a/vendor/golang.org/x/tools/internal/modindex/modindex.go b/vendor/golang.org/x/tools/internal/modindex/modindex.go
new file mode 100644
index 0000000000..16a7cabb94
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/modindex/modindex.go
@@ -0,0 +1,121 @@
+// Copyright 2024 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 modindex contains code for building and searching an
+// [Index] of the Go module cache.
+package modindex
+
+// The directory containing the index, returned by
+// [IndexDir], contains a file index-name- that contains the name
+// of the current index. We believe writing that short file is atomic.
+// [Read] reads that file to get the file name of the index.
+// WriteIndex writes an index with a unique name and then
+// writes that name into a new version of index-name-.
+// ( stands for the CurrentVersion of the index format.)
+
+import (
+	"maps"
+	"os"
+	"path/filepath"
+	"slices"
+	"strings"
+	"time"
+
+	"golang.org/x/mod/semver"
+)
+
+// Update updates the index for the specified Go
+// module cache directory, creating it as needed.
+// On success it returns the current index.
+func Update(gomodcache string) (*Index, error) {
+	prev, err := Read(gomodcache)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return nil, err
+		}
+		prev = nil
+	}
+	return update(gomodcache, prev)
+}
+
+// update builds, writes, and returns the current index.
+//
+// If old is nil, the new index is built from all of GOMODCACHE;
+// otherwise it is built from the old index plus cache updates
+// since the previous index's time.
+func update(gomodcache string, old *Index) (*Index, error) {
+	gomodcache, err := filepath.Abs(gomodcache)
+	if err != nil {
+		return nil, err
+	}
+	new, changed, err := build(gomodcache, old)
+	if err != nil {
+		return nil, err
+	}
+	if old == nil || changed {
+		if err := write(gomodcache, new); err != nil {
+			return nil, err
+		}
+	}
+	return new, nil
+}
+
+// build returns a new index for the specified Go module cache (an
+// absolute path).
+//
+// If an old index is provided, only directories more recent than it
+// that it are scanned; older directories are provided by the old
+// Index.
+//
+// The boolean result indicates whether new entries were found.
+func build(gomodcache string, old *Index) (*Index, bool, error) {
+	// Set the time window.
+	var start time.Time // = dawn of time
+	if old != nil {
+		// -1s to accommodate skew between (fine-grained) time.Now
+		// and (coarse) file system's mtime clock.
+		start = old.ValidAt.Add(-1 * time.Second)
+	}
+	now := time.Now()
+	end := now.Add(24 * time.Hour) // safely in the future
+
+	// Enumerate GOMODCACHE package directories.
+	// Choose the best (latest) package for each import path.
+	pkgDirs := findDirs(gomodcache, start, end)
+	dirByPath, err := bestDirByImportPath(pkgDirs)
+	if err != nil {
+		return nil, false, err
+	}
+
+	// For each import path it might occur only in
+	// dirByPath, only in old, or in both.
+	// If both, use the semantically later one.
+	var entries []Entry
+	if old != nil {
+		for _, entry := range old.Entries {
+			dir, ok := dirByPath[entry.ImportPath]
+			if !ok || semver.Compare(dir.version, entry.Version) <= 0 {
+				// New dir is missing or not more recent; use old entry.
+				entries = append(entries, entry)
+				delete(dirByPath, entry.ImportPath)
+			}
+		}
+	}
+
+	// Extract symbol information for all the new directories.
+	newEntries := extractSymbols(gomodcache, maps.Values(dirByPath))
+	entries = append(entries, newEntries...)
+	slices.SortFunc(entries, func(x, y Entry) int {
+		if n := strings.Compare(x.PkgName, y.PkgName); n != 0 {
+			return n
+		}
+		return strings.Compare(x.ImportPath, y.ImportPath)
+	})
+
+	return &Index{
+		GOMODCACHE: gomodcache,
+		ValidAt:    now, // time before the directories were scanned
+		Entries:    entries,
+	}, len(newEntries) > 0, nil
+}
diff --git a/vendor/golang.org/x/tools/internal/modindex/symbols.go b/vendor/golang.org/x/tools/internal/modindex/symbols.go
new file mode 100644
index 0000000000..8e9702d84b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/modindex/symbols.go
@@ -0,0 +1,244 @@
+// Copyright 2024 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 modindex
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"iter"
+	"os"
+	"path/filepath"
+	"runtime"
+	"slices"
+	"strings"
+	"sync"
+
+	"golang.org/x/sync/errgroup"
+)
+
+// The name of a symbol contains information about the symbol:
+//  T for types, TD if the type is deprecated
+//  C for consts, CD if the const is deprecated
+//  V for vars, VD if the var is deprecated
+// and for funcs:  F  ( )*
+// any spaces in  are replaced by $s so that the fields
+// of the name are space separated. F is replaced by FD if the func
+// is deprecated.
+type symbol struct {
+	pkg  string // name of the symbols's package
+	name string // declared name
+	kind string // T, C, V, or F, followed by D if deprecated
+	sig  string // signature information, for F
+}
+
+// extractSymbols returns a (new, unordered) array of Entries, one for
+// each provided package directory, describing its exported symbols.
+func extractSymbols(cwd string, dirs iter.Seq[directory]) []Entry {
+	var (
+		mu      sync.Mutex
+		entries []Entry
+	)
+
+	var g errgroup.Group
+	g.SetLimit(max(2, runtime.GOMAXPROCS(0)/2))
+	for dir := range dirs {
+		g.Go(func() error {
+			thedir := filepath.Join(cwd, string(dir.path))
+			mode := parser.SkipObjectResolution | parser.ParseComments
+
+			// Parse all Go files in dir and extract symbols.
+			dirents, err := os.ReadDir(thedir)
+			if err != nil {
+				return nil // log this someday?
+			}
+			var syms []symbol
+			for _, dirent := range dirents {
+				if !strings.HasSuffix(dirent.Name(), ".go") ||
+					strings.HasSuffix(dirent.Name(), "_test.go") {
+					continue
+				}
+				fname := filepath.Join(thedir, dirent.Name())
+				tr, err := parser.ParseFile(token.NewFileSet(), fname, nil, mode)
+				if err != nil {
+					continue // ignore errors, someday log them?
+				}
+				syms = append(syms, getFileExports(tr)...)
+			}
+
+			// Create an entry for the package.
+			pkg, names := processSyms(syms)
+			if pkg != "" {
+				mu.Lock()
+				defer mu.Unlock()
+				entries = append(entries, Entry{
+					PkgName:    pkg,
+					Dir:        dir.path,
+					ImportPath: dir.importPath,
+					Version:    dir.version,
+					Names:      names,
+				})
+			}
+
+			return nil
+		})
+	}
+	g.Wait() // ignore error
+
+	return entries
+}
+
+func getFileExports(f *ast.File) []symbol {
+	pkg := f.Name.Name
+	if pkg == "main" || pkg == "" {
+		return nil
+	}
+	var ans []symbol
+	// should we look for //go:build ignore?
+	for _, decl := range f.Decls {
+		switch decl := decl.(type) {
+		case *ast.FuncDecl:
+			if decl.Recv != nil {
+				// ignore methods, as we are completing package selections
+				continue
+			}
+			name := decl.Name.Name
+			dtype := decl.Type
+			// not looking at dtype.TypeParams. That is, treating
+			// generic functions just like non-generic ones.
+			sig := dtype.Params
+			kind := "F"
+			if isDeprecated(decl.Doc) {
+				kind += "D"
+			}
+			result := []string{fmt.Sprintf("%d", dtype.Results.NumFields())}
+			for _, x := range sig.List {
+				// This code creates a string representing the type.
+				// TODO(pjw): it may be fragile:
+				// 1. x.Type could be nil, perhaps in ill-formed code
+				// 2. ExprString might someday change incompatibly to
+				//    include struct tags, which can be arbitrary strings
+				if x.Type == nil {
+					// Can this happen without a parse error? (Files with parse
+					// errors are ignored in getSymbols)
+					continue // maybe report this someday
+				}
+				tp := types.ExprString(x.Type)
+				if len(tp) == 0 {
+					// Can this happen?
+					continue // maybe report this someday
+				}
+				// This is only safe if ExprString never returns anything with a $
+				// The only place a $ can occur seems to be in a struct tag, which
+				// can be an arbitrary string literal, and ExprString does not presently
+				// print struct tags. So for this to happen the type of a formal parameter
+				// has to be a explicit struct, e.g. foo(x struct{a int "$"}) and ExprString
+				// would have to show the struct tag. Even testing for this case seems
+				// a waste of effort, but let's remember the possibility
+				if strings.Contains(tp, "$") {
+					continue
+				}
+				tp = strings.Replace(tp, " ", "$", -1)
+				if len(x.Names) == 0 {
+					result = append(result, "_")
+					result = append(result, tp)
+				} else {
+					for _, y := range x.Names {
+						result = append(result, y.Name)
+						result = append(result, tp)
+					}
+				}
+			}
+			sigs := strings.Join(result, " ")
+			if s := newsym(pkg, name, kind, sigs); s != nil {
+				ans = append(ans, *s)
+			}
+		case *ast.GenDecl:
+			depr := isDeprecated(decl.Doc)
+			switch decl.Tok {
+			case token.CONST, token.VAR:
+				tp := "V"
+				if decl.Tok == token.CONST {
+					tp = "C"
+				}
+				if depr {
+					tp += "D"
+				}
+				for _, sp := range decl.Specs {
+					for _, x := range sp.(*ast.ValueSpec).Names {
+						if s := newsym(pkg, x.Name, tp, ""); s != nil {
+							ans = append(ans, *s)
+						}
+					}
+				}
+			case token.TYPE:
+				tp := "T"
+				if depr {
+					tp += "D"
+				}
+				for _, sp := range decl.Specs {
+					if s := newsym(pkg, sp.(*ast.TypeSpec).Name.Name, tp, ""); s != nil {
+						ans = append(ans, *s)
+					}
+				}
+			}
+		}
+	}
+	return ans
+}
+
+func newsym(pkg, name, kind, sig string) *symbol {
+	if len(name) == 0 || !ast.IsExported(name) {
+		return nil
+	}
+	sym := symbol{pkg: pkg, name: name, kind: kind, sig: sig}
+	return &sym
+}
+
+func isDeprecated(doc *ast.CommentGroup) bool {
+	if doc == nil {
+		return false
+	}
+	// go.dev/wiki/Deprecated Paragraph starting 'Deprecated:'
+	// This code fails for /* Deprecated: */, but it's the code from
+	// gopls/internal/analysis/deprecated
+	for line := range strings.SplitSeq(doc.Text(), "\n\n") {
+		if strings.HasPrefix(line, "Deprecated:") {
+			return true
+		}
+	}
+	return false
+}
+
+// return the package name and the value for the symbols.
+// if there are multiple packages, choose one arbitrarily
+// the returned slice is sorted lexicographically
+func processSyms(syms []symbol) (string, []string) {
+	if len(syms) == 0 {
+		return "", nil
+	}
+	slices.SortFunc(syms, func(l, r symbol) int {
+		return strings.Compare(l.name, r.name)
+	})
+	pkg := syms[0].pkg
+	var names []string
+	for _, s := range syms {
+		if s.pkg != pkg {
+			// Symbols came from two files in same dir
+			// with different package declarations.
+			continue
+		}
+		var nx string
+		if s.sig != "" {
+			nx = fmt.Sprintf("%s %s %s", s.name, s.kind, s.sig)
+		} else {
+			nx = fmt.Sprintf("%s %s", s.name, s.kind)
+		}
+		names = append(names, nx)
+	}
+	return pkg, names
+}
diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go
index 0f73c719cd..b049e5f977 100644
--- a/vendor/golang.org/x/tools/internal/stdlib/deps.go
+++ b/vendor/golang.org/x/tools/internal/stdlib/deps.go
@@ -12,386 +12,387 @@ type pkginfo struct {
 }
 
 var deps = [...]pkginfo{
-	{"archive/tar", "\x03{\x03F>\x01\n\x01&\x01\x01\x02\x05\b\x02\x01\x02\x02\r"},
-	{"archive/zip", "\x02\x04j\x0e\x03\x12\x022>\x01-\x05\x01\x0f\x03\x02\x0f\x04"},
-	{"bufio", "\x03{\x87\x01F\x15"},
-	{"bytes", "~*]\x03\fJ\x02\x02"},
+	{"archive/tar", "\x03|\x03F>\x01\n\x01&\x01\x01\x02\x05\b\x02\x01\x02\x02\r"},
+	{"archive/zip", "\x02\x04k\x0e\x03\x12\x022>\x01-\x05\x01\x0f\x03\x02\x0f\x04"},
+	{"bufio", "\x03|\x87\x01F\x15"},
+	{"bytes", "\x7f*]\x03\fJ\x02\x02"},
 	{"cmp", ""},
-	{"compress/bzip2", "\x02\x02\x81\x02C"},
-	{"compress/flate", "\x02|\x03\x84\x01\f\x034\x02\x03"},
-	{"compress/gzip", "\x02\x04j\x0e\x03\x14pW"},
-	{"compress/lzw", "\x02|\x03\x84\x01"},
-	{"compress/zlib", "\x02\x04j\x0e\x03\x12\x01q"},
-	{"container/heap", "\xc9\x02"},
+	{"compress/bzip2", "\x02\x02\x82\x02C"},
+	{"compress/flate", "\x02}\x03\x84\x01\f\x034\x02\x03"},
+	{"compress/gzip", "\x02\x04k\x0e\x03\x14pW"},
+	{"compress/lzw", "\x02}\x03\x84\x01"},
+	{"compress/zlib", "\x02\x04k\x0e\x03\x12\x01q"},
+	{"container/heap", "\xca\x02"},
 	{"container/list", ""},
 	{"container/ring", ""},
-	{"context", "~]r\x01\x0e"},
-	{"crypto", "\x93\x01rE"},
-	{"crypto/aes", "\x10\v\n\xa5\x02"},
-	{"crypto/cipher", "\x03\"\x01\x01 \x13$+\\"},
-	{"crypto/des", "\x10\x17 7+\xa1\x01\x03"},
-	{"crypto/dsa", "G\x034\x87\x01\r"},
-	{"crypto/ecdh", "\x03\v\r\x11\x04\x17\x03\x10$\x87\x01"},
-	{"crypto/ecdsa", "\x0e\x05\x03\x05\x01\x11\b\v\x06\x01\x03\x0f\x01$\x87\x01\r\x05O\x01"},
-	{"crypto/ed25519", "\x0e \x12\a\x03\t\a$I>E"},
-	{"crypto/elliptic", "5I\x87\x01\r;"},
-	{"crypto/fips140", "$\x05\x9e\x01\x9b\x01"},
-	{"crypto/hkdf", "1\x15\x017\x15"},
-	{"crypto/hmac", "\x1b\x17\x14\x01\x139"},
-	{"crypto/hpke", "\x03\v\x02\x03\x04\x01\r\x01\x05\x1f\x06\a\x01\x01%\x03\x12\x16\x9f\x01\x1d"},
-	{"crypto/internal/boring", "\x0e\x02\x0eu"},
-	{"crypto/internal/boring/bbig", "\x1b\xf7\x01P"},
-	{"crypto/internal/boring/bcache", "\xce\x02\x14"},
+	{"context", "\x7f]r\x01\x0e"},
+	{"crypto", "\x94\x01rE"},
+	{"crypto/aes", "\x10\v\v\xa5\x02"},
+	{"crypto/cipher", "\x03#\x01\x01 \x13$+\\"},
+	{"crypto/des", "\x10\x18 7+\xa1\x01\x03"},
+	{"crypto/dsa", "H\x034\x87\x01\r"},
+	{"crypto/ecdh", "\x03\v\r\x12\x04\x17\x03\x10$\x87\x01"},
+	{"crypto/ecdsa", "\x0e\x05\x03\x05\x01\x12\b\v\x06\x01\x03\x0f\x01$\x87\x01\r\x05O\x01"},
+	{"crypto/ed25519", "\x0e!\x12\a\x03\t\a$I>E"},
+	{"crypto/elliptic", "6I\x87\x01\r;"},
+	{"crypto/fips140", "%\x05\x9e\x01\x9b\x01"},
+	{"crypto/hkdf", "2\x15\x017\x15"},
+	{"crypto/hmac", "\x1b\x18\x14\x01\x139"},
+	{"crypto/hpke", "\x03\v\x02\x03\x04\x01\x0e\x01\x05\x1f\x06\a\x01\x01%\x03\x12\x16\x9f\x01\x1d"},
+	{"crypto/internal/boring", "\x0e\x02\x0ev"},
+	{"crypto/internal/boring/bbig", "\x1b\xf8\x01P"},
+	{"crypto/internal/boring/bcache", "\xcf\x02\x14"},
 	{"crypto/internal/boring/sig", ""},
 	{"crypto/internal/constanttime", ""},
-	{"crypto/internal/cryptotest", "\x03\r\v\t%\x11\x1a\r\x12\x12!\x04\x06\n\x19\x01\x11\x11\x1d\x01\a\x03\x02\b\x02\x01\x05\f"},
-	{"crypto/internal/cryptotest/wycheproof", "\x0e\x12S\x01\f\x01r@\x05\x03\x15\x10"},
-	{"crypto/internal/entropy", "L"},
-	{"crypto/internal/entropy/v1.0.0", "E9\x96\x01:\x14"},
-	{"crypto/internal/fips140", "D:\xc2\x01\v\x17"},
-	{"crypto/internal/fips140/aes", "\x03!\x03\x02\x14\x05\x01\x01\x055\x96\x016"},
-	{"crypto/internal/fips140/aes/gcm", "$\x01\x02\x02\x02\x12\x05\x01\x065\x93\x01"},
-	{"crypto/internal/fips140/alias", "\xe2\x02"},
-	{"crypto/internal/fips140/bigmod", ")\x19\x01\x065\x96\x01"},
-	{"crypto/internal/fips140/check", "$\x0e\a\t\x02\xc1\x01]"},
-	{"crypto/internal/fips140/check/checktest", ")\x97\x02\""},
-	{"crypto/internal/fips140/drbg", "\x03 \x01\x01\x04\x14\x05\n2\x87\x01\x0f9\x01"},
-	{"crypto/internal/fips140/ecdh", "\x03!\x05\x02\n\r<\x87\x01\x0f9"},
-	{"crypto/internal/fips140/ecdsa", "\x03!\x04\x01\x02\a\x03\x06C\x15r\x0f9"},
-	{"crypto/internal/fips140/ed25519", "\x03!\x05\x02\x04\fC\xcc\x01\x03"},
-	{"crypto/internal/fips140/edwards25519", "\x1f\n\a\x12<\x96\x019"},
-	{"crypto/internal/fips140/edwards25519/field", ")\x14\x05<\x96\x01"},
-	{"crypto/internal/fips140/hkdf", "\x03!\x05\t\aE\x15"},
-	{"crypto/internal/fips140/hmac", "\x03!\x15\x01\x01C\x15"},
-	{"crypto/internal/fips140/mldsa", "\x03\x1c\x05\x05\x02\x0e\x01\x03\x05<\x96\x019"},
-	{"crypto/internal/fips140/mlkem", "\x03!\x05\x02\x0f\x03\x05<\xcf\x01"},
-	{"crypto/internal/fips140/nistec", "\x1f\n\r\f<\x96\x01,\r\x15"},
-	{"crypto/internal/fips140/nistec/fiat", ")\x14A\x96\x01"},
-	{"crypto/internal/fips140/pbkdf2", "\x03!\x05\t\aE\x15"},
-	{"crypto/internal/fips140/rsa", "\x03\x1c\x05\x04\x01\x02\x0e\x01\x01\x02A\x15rH"},
-	{"crypto/internal/fips140/sha256", "\x03!\x1e\x01\x065\x15\x81\x01"},
-	{"crypto/internal/fips140/sha3", "\x03!\x19\x05\x01;\x96\x01N"},
-	{"crypto/internal/fips140/sha512", "\x03!\x1e\x01\x065\x15\x81\x01"},
-	{"crypto/internal/fips140/ssh", ")j"},
-	{"crypto/internal/fips140/subtle", "\x1f\b\x1b\xd2\x01"},
-	{"crypto/internal/fips140/tls12", "\x03!\x05\t\a\x02C\x15"},
-	{"crypto/internal/fips140/tls13", "\x03!\x05\b\b\t<\x15"},
-	{"crypto/internal/fips140cache", "\xc0\x02\r."},
+	{"crypto/internal/cryptotest", "\x03\r\v\n%\x11\x1a\r\x12\x12!\x04\x06\n\x19\x01\x11\x11\x1d\x01\a\x03\x02\b\x02\x01\x05\f"},
+	{"crypto/internal/cryptotest/wycheproof", "\x0e\x12T\x01\f\x01r@\x05\x03\x15\x10"},
+	{"crypto/internal/cryptotest/x509limbo", "u\n\x03\xba\x01\x03\x1e"},
+	{"crypto/internal/entropy", "M"},
+	{"crypto/internal/entropy/v1.0.0", "F9\x96\x01:\x14"},
+	{"crypto/internal/fips140", "E:\xc2\x01\v\x17"},
+	{"crypto/internal/fips140/aes", "\x03\"\x03\x02\x14\x05\x01\x01\x055\x96\x016"},
+	{"crypto/internal/fips140/aes/gcm", "%\x01\x02\x02\x02\x12\x05\x01\x065\x93\x01"},
+	{"crypto/internal/fips140/alias", "\xe3\x02"},
+	{"crypto/internal/fips140/bigmod", "*\x19\x01\x065\x96\x01"},
+	{"crypto/internal/fips140/check", "%\x0e\a\t\x02\xc1\x01]"},
+	{"crypto/internal/fips140/check/checktest", "*\x97\x02\""},
+	{"crypto/internal/fips140/drbg", "\x03!\x01\x01\x04\x14\x05\n2\x87\x01\x0f9\x01"},
+	{"crypto/internal/fips140/ecdh", "\x03\"\x05\x02\n\r<\x87\x01\x0f9"},
+	{"crypto/internal/fips140/ecdsa", "\x03\"\x04\x01\x02\a\x03\x06C\x15r\x0f9"},
+	{"crypto/internal/fips140/ed25519", "\x03\"\x05\x02\x04\fC\xcc\x01\x03"},
+	{"crypto/internal/fips140/edwards25519", "\x1f\v\a\x12<\x96\x019"},
+	{"crypto/internal/fips140/edwards25519/field", "*\x14\x05<\x96\x01"},
+	{"crypto/internal/fips140/hkdf", "\x03\"\x05\t\aE\x15"},
+	{"crypto/internal/fips140/hmac", "\x03\"\x15\x01\x01C\x15"},
+	{"crypto/internal/fips140/mldsa", "\x03\x1c\x06\x05\x02\x0e\x01\x03\x05<\x96\x019"},
+	{"crypto/internal/fips140/mlkem", "\x03\"\x05\x02\x0f\x03\x05<\xcf\x01"},
+	{"crypto/internal/fips140/nistec", "\x1f\v\r\f<\x96\x01,\r\x15"},
+	{"crypto/internal/fips140/nistec/fiat", "*\x14A\x96\x01"},
+	{"crypto/internal/fips140/pbkdf2", "\x03\"\x05\t\aE\x15"},
+	{"crypto/internal/fips140/rsa", "\x03\x1c\x06\x04\x01\x02\x0e\x01\x01\x02A\x15rH"},
+	{"crypto/internal/fips140/sha256", "\x03\"\x1e\x01\x065\x15\x81\x01"},
+	{"crypto/internal/fips140/sha3", "\x03\"\x19\x05\x01;\x96\x01N"},
+	{"crypto/internal/fips140/sha512", "\x03\"\x1e\x01\x065\x15\x81\x01"},
+	{"crypto/internal/fips140/ssh", "*j"},
+	{"crypto/internal/fips140/subtle", "\x1f\t\x1b\xd2\x01"},
+	{"crypto/internal/fips140/tls12", "\x03\"\x05\t\a\x02C\x15"},
+	{"crypto/internal/fips140/tls13", "\x03\"\x05\b\b\t<\x15"},
+	{"crypto/internal/fips140cache", "\xc1\x02\r."},
 	{"crypto/internal/fips140deps", ""},
-	{"crypto/internal/fips140deps/byteorder", "\xa9\x01"},
-	{"crypto/internal/fips140deps/cpu", "\xbe\x01\b"},
-	{"crypto/internal/fips140deps/godebug", "\xc7\x01"},
-	{"crypto/internal/fips140deps/time", "\xe2\x02"},
-	{"crypto/internal/fips140hash", ":\x1e;\xcf\x01"},
-	{"crypto/internal/fips140only", "\x17\x14\x0e\x01\x01Xr"},
+	{"crypto/internal/fips140deps/byteorder", "\xaa\x01"},
+	{"crypto/internal/fips140deps/cpu", "\xbf\x01\b"},
+	{"crypto/internal/fips140deps/godebug", "\xc8\x01"},
+	{"crypto/internal/fips140deps/time", "\xe3\x02"},
+	{"crypto/internal/fips140hash", ";\x1e;\xcf\x01"},
+	{"crypto/internal/fips140only", "\x17\x15\x0e\x01\x01Xr"},
 	{"crypto/internal/fips140test", ""},
-	{"crypto/internal/impl", "\xcb\x02"},
-	{"crypto/internal/rand", "\x1b\x10 |>]"},
-	{"crypto/internal/randutil", "\x85\x02\x12"},
-	{"crypto/internal/sysrand", "~r!\"\r\r\x01\x01\r\x06"},
-	{"crypto/internal/sysrand/internal/seccomp", "~"},
-	{"crypto/md5", "\x0e97\x15\x16k"},
-	{"crypto/mldsa", "\x0e%K\x87\x01"},
-	{"crypto/mlkem", "\x0e&"},
-	{"crypto/mlkem/mlkemtest", "4\x13\t."},
-	{"crypto/pbkdf2", "7\x0f\x017\x15"},
-	{"crypto/rand", "\x1b\x10\x1c\x034\x87\x01\rP"},
-	{"crypto/rc4", "' 7\xcc\x01"},
-	{"crypto/rsa", "\x0e\r\x01\f\x10\x0e\x01\x03\t\a$\x03\x124>\f\x01"},
-	{"crypto/sha1", "\x0e\r,\x025\x15\x16\x15V"},
-	{"crypto/sha256", "\x0e\r\x1eZ"},
-	{"crypto/sha3", "\x0e,Y\xcf\x01"},
-	{"crypto/sha512", "\x0e\r X"},
-	{"crypto/subtle", "\x1f\x1e\xa9\x01|"},
-	{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x01\x01\x01\x01\x01\n\x01\x18\x01\x0f\x01\x01\x03\x01\x01\x01\x01\x02\x01\x02\x01\x1f\x02\x03\x12\x16\x15\t>\x16\x18\r\b\x01\x01\x01\x02\x01\x0e\x06\x03\x01\x15"},
-	{"crypto/tls/internal/fips140tls", "\x17\xb7\x02"},
-	{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x01\x017\x01\x06\x01\x01\x02\x05\x0f\x06\t\x02\x03F\x03;\x01\x02\b\x01\x01\x02\a\x12\x05\x01\x06\a\b\x02\x01\x02\x0f\x02\x01\x01\x02\x04\x01"},
-	{"crypto/x509/pkix", "m\x06\x0e\x91\x019\x11"},
-	{"database/sql", "\x03\nS\x01\x1d\x03\x84\x01\v\a$\x05\b\x02\x03\x01\x0e\x02\x02\x02\x01"},
-	{"database/sql/driver", "\rT\x1d\x03\xba\x01\x0f\x12\a"},
+	{"crypto/internal/impl", "\xcc\x02"},
+	{"crypto/internal/rand", "\x1b\x11 |>]"},
+	{"crypto/internal/randutil", "\x86\x02\x12"},
+	{"crypto/internal/sysrand", "\x7fr!\"\r\r\x01\x01\r\x06"},
+	{"crypto/internal/sysrand/internal/seccomp", "\x7f"},
+	{"crypto/md5", "\x0e:7\x15\x16k"},
+	{"crypto/mldsa", "\x0e&K\x87\x01"},
+	{"crypto/mlkem", "\x0e'"},
+	{"crypto/mlkem/mlkemtest", "5\x13\t."},
+	{"crypto/pbkdf2", "8\x0f\x017\x15"},
+	{"crypto/rand", "\x1b\x11\x1c\x034\x87\x01\rP"},
+	{"crypto/rc4", "( 7\xcc\x01"},
+	{"crypto/rsa", "\x0e\r\x01\r\x10\x0e\x01\x03\t\a$\x03\x124>\f\x01"},
+	{"crypto/sha1", "\x0e\r-\x025\x15\x16\x15V"},
+	{"crypto/sha256", "\x0e\r\x1fZ"},
+	{"crypto/sha3", "\x0e-Y\xcf\x01"},
+	{"crypto/sha512", "\x0e\r!X"},
+	{"crypto/subtle", "\x1f\x1f\xa9\x01|"},
+	{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x01\x01\x01\x01\x01\v\x01\x18\x01\x0f\x01\x01\x03\x01\x01\x01\x01\x02\x01\x02\x01\x1f\x02\x03\x12\x16\x15\t>\x16\x18\r\b\x01\x01\x01\x02\x01\x0e\x06\x03\x01\x15"},
+	{"crypto/tls/internal/fips140tls", "\x17\xb8\x02"},
+	{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x01\x018\x01\x06\x01\x01\x02\x05\x0f\x06\t\x02\x03F\x03;\x01\x02\b\x01\x01\x02\a\x12\x05\x01\x06\a\b\x02\x01\x02\x0f\x02\x01\x01\x02\x04\x01"},
+	{"crypto/x509/pkix", "n\x06\x0e\x91\x019\x11"},
+	{"database/sql", "\x03\nT\x01\x1d\x03\x84\x01\v\a$\x05\b\x02\x03\x01\x0e\x02\x02\x02\x01"},
+	{"database/sql/driver", "\rU\x1d\x03\xba\x01\x0f\x12\a"},
 	{"database/sql/internal", ""},
-	{"debug/buildinfo", "\x03a\x02\x01\x01\b\x0e\x03h\x1a\x02\x01-\x0f "},
-	{"debug/dwarf", "\x03m\x0e\x03\x84\x013\x11\x01\x01"},
-	{"debug/elf", "\x03\x06Z\r\x0e\x03h\x1b\x01\f\"\x17\x01\x17"},
-	{"debug/gosym", "\x03m\x11#\xa5\x01\x01\x01\x02"},
-	{"debug/macho", "\x03\x06Z\r\x11h\x1c.\x17\x01"},
-	{"debug/pe", "\x03\x06Z\r\x0e\x03h\x1c.\x17\x01\x17"},
-	{"debug/plan9obj", "p\x0e\x03h\x1c."},
-	{"embed", "~*D\x19\x01V"},
+	{"debug/buildinfo", "\x03b\x02\x01\x01\b\x0e\x03h\x1a\x02\x01-\x0f "},
+	{"debug/dwarf", "\x03n\x0e\x03\x84\x013\x11\x01\x01"},
+	{"debug/elf", "\x03\x06[\r\x0e\x03h\x1b\x01\f\"\x17\x01\x17"},
+	{"debug/gosym", "\x03n\x11#\xa5\x01\x01\x01\x02"},
+	{"debug/macho", "\x03\x06[\r\x11h\x1c.\x17\x01"},
+	{"debug/pe", "\x03\x06[\r\x0e\x03h\x1c.\x17\x01\x17"},
+	{"debug/plan9obj", "q\x0e\x03h\x1c."},
+	{"embed", "\x7f*D\x19\x01V"},
 	{"embed/internal/embedtest", ""},
 	{"encoding", ""},
-	{"encoding/ascii85", "\x85\x02E"},
-	{"encoding/asn1", "\x03{\x03h(\x01)\r\x02\x01\x11\x03\x01"},
-	{"encoding/base32", "\x85\x02C\x02"},
-	{"encoding/base64", "\xa9\x01\\C\x02"},
-	{"encoding/binary", "~\x87\x01\f*\r\x05"},
-	{"encoding/csv", "\x02\x01{\x03\x84\x01F\x13\x02"},
-	{"encoding/gob", "\x02i\x05\x0e\x03h\x1c\v\x01\x03\x1f\b\x12\x01\x10\x02"},
-	{"encoding/hex", "~\x03\x84\x01C\x03"},
-	{"encoding/json", "\x03\x01g\n\x01\x01\x02\x01\x01\x03\x03\x84\x016\x0f\x01"},
-	{"encoding/json/internal", "~"},
-	{"encoding/json/internal/jsonflags", "u"},
-	{"encoding/json/internal/jsonopts", "u\x01"},
-	{"encoding/json/internal/jsontest", "\x03f\x15\x03\x83\x01\x01\x012\b\b\x03\x02\x0f"},
-	{"encoding/json/internal/jsonwire", "\x04r\b\x87\x01\f7\x02\x01\x13\x01\x01"},
-	{"encoding/json/jsontext", "\x03r\x01\x01\x02\x05\x87\x01\x03\t\x034\x02\x01\x02\x13"},
-	{"encoding/json/v2", "\x03\x01g\x03\x01\x01\x03\x02\x01\x01\x02\x01\x04\x03\x84\x01\f\x03'\r\x02\x01\x02\x0f\x02\x02"},
-	{"encoding/pem", "\x03l\x0f\x87\x01C\x03"},
-	{"encoding/xml", "\x02\x01h\x13\x03\x84\x016\x05\n\x01\x02\x11\x02"},
-	{"errors", "\xdb\x01\x87\x01"},
-	{"expvar", "tSB\b\v\x17\r\b\x02\x03\x01\x12"},
-	{"flag", "k\x13\x03\x84\x01.\b\x05\b\x02\x01\x11"},
-	{"fmt", "~E)\x19\f\"\b\r\x02\x03\x13"},
-	{"go/ast", "\x03\x01}\x0e\x01u\x03+\b\r\x02\x01\x13\x02"},
-	{"go/build", "\x02\x01{\x03\x01\x02\x02\a\x02\x01\x17 \x04\x02\t\x1c\x13\x01-\x01\x04\x01\a\b\x02\x01\x13\x02\x02"},
-	{"go/build/constraint", "~\xcc\x01\x01\x13\x02"},
-	{"go/constant", "\x81\x01\x0f\x81\x01\x01\x026\x01\x02\x13"},
-	{"go/doc", "\x04}\x01\x05\t>73\x10\x02\x01\x13\x02"},
-	{"go/doc/comment", "\x03~\xc7\x01\x01\x01\x01\x13\x02"},
-	{"go/format", "\x03~\x01\v\x01\x02uF"},
-	{"go/importer", "\x83\x01\a\x01\x01\x04\x01t;"},
-	{"go/internal/gccgoimporter", "\x02\x01a\x1a\x03\x04\v\x01r\x02.\x01\x05\x11\x01\r\b"},
-	{"go/internal/gcimporter", "\x02\x7f\x0f\x010\x140.\x15\x03\x02"},
-	{"go/internal/srcimporter", "\x81\x01\x01\x01\n\x03\x01t.\x01\x05\x12\x02\x15"},
-	{"go/parser", "\x03{\x03\x01\x02\v\x01u\x01-\x06\x12"},
-	{"go/printer", "\x81\x01\x01\x02\x03\tu\f\"\x15\x02\x01\x02\f\x05\x02"},
-	{"go/scanner", "\x03~\x0fu4\x10\x01\x14\x02"},
-	{"go/token", "\x04}\x87\x01@\x02\x03\x01\x10\x02"},
-	{"go/types", "\x03\x01\x06t\x03\x01\x03\b\x03\x02\x0654\x04\x03\t\"\x06\a\b\x01\x01\x01\x02\x01\x10\x02\x02"},
-	{"go/version", "\xcc\x01\x7f"},
-	{"hash", "\x85\x02"},
-	{"hash/adler32", "~\x15\x16"},
-	{"hash/crc32", "~\x15\x16\x15\x8f\x01\x01\x14"},
-	{"hash/crc64", "~\x15\x16\xa4\x01"},
-	{"hash/fnv", "~\x15\x16k"},
-	{"hash/maphash", "\x93\x01\x11>\x80\x01"},
-	{"html", "\xcb\x02\x02\x13"},
-	{"html/template", "\x03q\r\x18.>\x01\n#\x05\x01\x02\x03\n\x02\x01\x02\r\x01\x03\x02"},
-	{"image", "\x02|\x1ei\x0f6\x03\x01"},
+	{"encoding/ascii85", "\x86\x02E"},
+	{"encoding/asn1", "\x03|\x03h(\x01)\r\x02\x01\x11\x03\x01"},
+	{"encoding/base32", "\x86\x02C\x02"},
+	{"encoding/base64", "\xaa\x01\\C\x02"},
+	{"encoding/binary", "\x7f\x87\x01\f*\r\x05"},
+	{"encoding/csv", "\x02\x01|\x03\x84\x01F\x13\x02"},
+	{"encoding/gob", "\x02j\x05\x0e\x03h\x1c\v\x01\x03\x1f\b\x12\x01\x10\x02"},
+	{"encoding/hex", "\x7f\x03\x84\x01C\x03"},
+	{"encoding/json", "\x03\x01h\n\x01\x01\x02\x01\x01\x03\x03\x84\x016\x0f\x01"},
+	{"encoding/json/internal", "\x7f"},
+	{"encoding/json/internal/jsonflags", "v"},
+	{"encoding/json/internal/jsonopts", "v\x01"},
+	{"encoding/json/internal/jsontest", "\x03g\x15\x03\x83\x01\x01\x012\b\b\x03\x02\x0f"},
+	{"encoding/json/internal/jsonwire", "\x04s\b\x87\x01\f7\x02\x01\x13\x01\x01"},
+	{"encoding/json/jsontext", "\x03s\x01\x01\x02\x05\x87\x01\x03\t\x034\x02\x01\x02\x13"},
+	{"encoding/json/v2", "\x03\x01h\x03\x01\x01\x03\x02\x01\x01\x02\x01\x04\x03\x84\x01\f\x03'\r\x02\x01\x02\x0f\x02\x02"},
+	{"encoding/pem", "\x03m\x0f\x87\x01C\x03"},
+	{"encoding/xml", "\x02\x01i\x13\x03\x84\x016\x05\n\x01\x02\x11\x02"},
+	{"errors", "\xdc\x01\x87\x01"},
+	{"expvar", "uSB\b\v\x17\r\b\x02\x03\x01\x12"},
+	{"flag", "l\x13\x03\x84\x01.\b\x05\b\x02\x01\x11"},
+	{"fmt", "\x7fE)\x19\f\"\b\r\x02\x03\x13"},
+	{"go/ast", "\x03\x01~\x0e\x01u\x03+\b\r\x02\x01\x13\x02"},
+	{"go/build", "\x02\x01|\x03\x01\x02\x02\a\x02\x01\x17 \x04\x02\t\x1c\x13\x01-\x01\x04\x01\a\b\x02\x01\x13\x02\x02"},
+	{"go/build/constraint", "\x7f\xcc\x01\x01\x13\x02"},
+	{"go/constant", "\x82\x01\x0f\x81\x01\x01\x026\x01\x02\x13"},
+	{"go/doc", "\x04~\x01\x05\t>73\x10\x02\x01\x13\x02"},
+	{"go/doc/comment", "\x03\x7f\xc7\x01\x01\x01\x01\x13\x02"},
+	{"go/format", "\x03\x7f\x01\v\x01\x02uF"},
+	{"go/importer", "\x84\x01\a\x01\x01\x04\x01t;"},
+	{"go/internal/gccgoimporter", "\x02\x01b\x1a\x03\x04\v\x01r\x02.\x01\x05\x11\x01\r\b"},
+	{"go/internal/gcimporter", "\x02\x80\x01\x0f\x010\x140.\x15\x03\x02"},
+	{"go/internal/srcimporter", "\x82\x01\x01\x01\n\x03\x01t.\x01\x05\x12\x02\x15"},
+	{"go/parser", "\x03|\x03\x01\x02\v\x01u\x01-\x06\x12"},
+	{"go/printer", "\x82\x01\x01\x02\x03\tu\f\"\x15\x02\x01\x02\f\x05\x02"},
+	{"go/scanner", "\x03\x7f\x0fu4\x10\x01\x14\x02"},
+	{"go/token", "\x04~\x87\x01@\x02\x03\x01\x10\x02"},
+	{"go/types", "\x03\x01\x06u\x03\x01\x03\b\x03\x02\x0654\x04\x03\t\"\x06\a\b\x01\x01\x01\x02\x01\x10\x02\x02"},
+	{"go/version", "\xcd\x01\x7f"},
+	{"hash", "\x86\x02"},
+	{"hash/adler32", "\x7f\x15\x16"},
+	{"hash/crc32", "\x7f\x15\x16\x15\x8f\x01\x01\x14"},
+	{"hash/crc64", "\x7f\x15\x16\xa4\x01"},
+	{"hash/fnv", "\x7f\x15\x16k"},
+	{"hash/maphash", "\x94\x01\x11>\x80\x01"},
+	{"html", "\xcc\x02\x02\x13"},
+	{"html/template", "\x03r\r\x18.>\x01\n#\x05\x01\x02\x03\n\x02\x01\x02\r\x01\x03\x02"},
+	{"image", "\x02}\x1ei\x0f6\x03\x01"},
 	{"image/color", ""},
-	{"image/color/palette", "\x9c\x01"},
-	{"image/draw", "\x9b\x01\x01\x04"},
-	{"image/gif", "\x02\x01\x05v\x03\x1a\x01\x01\x01\v\\\x0f"},
-	{"image/internal/imageutil", "\x9b\x01"},
-	{"image/jpeg", "\x02|\x1d\x01\x04e"},
-	{"image/png", "\x02\ag\x11\x12\x02\x06\x01iE"},
-	{"index/suffixarray", "\x03m\x0e\x87\x01\f-\n\x01"},
-	{"internal/abi", "\xc6\x01\x9c\x01"},
-	{"internal/asan", "\xe2\x02"},
-	{"internal/bisect", "\xc0\x02\r\x01"},
-	{"internal/buildcfg", "\x81\x01Hj\x06\x02\x05\n\x01"},
-	{"internal/bytealg", "\xbe\x01\xa4\x01"},
+	{"image/color/palette", "\x9d\x01"},
+	{"image/draw", "\x9c\x01\x01\x04"},
+	{"image/gif", "\x02\x01\x05w\x03\x1a\x01\x01\x01\v\\\x0f"},
+	{"image/internal/imageutil", "\x9c\x01"},
+	{"image/jpeg", "\x02}\x1d\x01\x04e"},
+	{"image/png", "\x02\ah\x11\x12\x02\x06\x01iE"},
+	{"index/suffixarray", "\x03n\x0e\x87\x01\f-\n\x01"},
+	{"internal/abi", "\xc7\x01\x9c\x01"},
+	{"internal/asan", "\xe3\x02"},
+	{"internal/bisect", "\xc1\x02\r\x01"},
+	{"internal/buildcfg", "\x82\x01Hj\x06\x02\x05\n\x01"},
+	{"internal/bytealg", "\xbf\x01\xa4\x01"},
 	{"internal/byteorder", ""},
 	{"internal/cfg", ""},
-	{"internal/cgrouptest", "\x81\x01\\V\x06\x0f\x02\x01\x04\x01"},
-	{"internal/chacha8rand", "\xa9\x01\x15\b\x9c\x01"},
+	{"internal/cgrouptest", "\x82\x01\\V\x06\x0f\x02\x01\x04\x01"},
+	{"internal/chacha8rand", "\xaa\x01\x15\b\x9c\x01"},
 	{"internal/copyright", ""},
 	{"internal/coverage", ""},
 	{"internal/coverage/calloc", ""},
-	{"internal/coverage/cfile", "t\r\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01$\x02'.\x06\a\n\x01\x03\x0e\x06"},
-	{"internal/coverage/cformat", "\x04}-\x04S\v8\x01\x02\x0e"},
-	{"internal/coverage/cmerge", "\x81\x01-c"},
-	{"internal/coverage/decodecounter", "p\x11-\v\x02J.\x17\x18"},
-	{"internal/coverage/decodemeta", "\x02n\x11\x16\x17\v\x02J."},
-	{"internal/coverage/encodecounter", "\x02n\x11-\f\x01\x02H\v#\x15"},
-	{"internal/coverage/encodemeta", "\x02\x01m\x11\x12\x04\x17\r\x02H./"},
-	{"internal/coverage/pods", "\x04}-\x85\x01\x06\x05\n\x02\x01"},
-	{"internal/coverage/rtcov", "\xe2\x02"},
-	{"internal/coverage/slicereader", "p\x11\x84\x01]"},
-	{"internal/coverage/slicewriter", "\x81\x01\x84\x01"},
-	{"internal/coverage/stringtab", "\x81\x018\x04H"},
+	{"internal/coverage/cfile", "u\r\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01$\x02'.\x06\a\n\x01\x03\x0e\x06"},
+	{"internal/coverage/cformat", "\x04~-\x04S\v8\x01\x02\x0e"},
+	{"internal/coverage/cmerge", "\x82\x01-c"},
+	{"internal/coverage/decodecounter", "q\x11-\v\x02J.\x17\x18"},
+	{"internal/coverage/decodemeta", "\x02o\x11\x16\x17\v\x02J."},
+	{"internal/coverage/encodecounter", "\x02o\x11-\f\x01\x02H\v#\x15"},
+	{"internal/coverage/encodemeta", "\x02\x01n\x11\x12\x04\x17\r\x02H./"},
+	{"internal/coverage/pods", "\x04~-\x85\x01\x06\x05\n\x02\x01"},
+	{"internal/coverage/rtcov", "\xe3\x02"},
+	{"internal/coverage/slicereader", "q\x11\x84\x01]"},
+	{"internal/coverage/slicewriter", "\x82\x01\x84\x01"},
+	{"internal/coverage/stringtab", "\x82\x018\x04H"},
 	{"internal/coverage/test", ""},
 	{"internal/coverage/uleb128", ""},
-	{"internal/cpu", "\xe2\x02"},
-	{"internal/dag", "\x04}\xc7\x01\x03"},
-	{"internal/diff", "\x03~\xc8\x01\x02"},
-	{"internal/exportdata", "\x02\x01{\x03\x02f\x1c.\x01\x05\x11\x01\x02"},
-	{"internal/filepathlite", "~*D\x1aB"},
-	{"internal/fmtsort", "\x04\xb7\x02\r"},
-	{"internal/fuzz", "\x03\nJ\x19\x04\n\x03\x01\v\x037>\f\x03\x1f\x01\x05\x02\x05\n\x01\x02\x01\x01\r\x04\x02"},
+	{"internal/cpu", "\xe3\x02"},
+	{"internal/dag", "\x04~\xc7\x01\x03"},
+	{"internal/diff", "\x03\x7f\xc8\x01\x02"},
+	{"internal/exportdata", "\x02\x01|\x03\x02f\x1c.\x01\x05\x11\x01\x02"},
+	{"internal/filepathlite", "\x7f*D\x1aB"},
+	{"internal/fmtsort", "\x04\xb8\x02\r"},
+	{"internal/fuzz", "\x03\nK\x19\x04\n\x03\x01\v\x037>\f\x03\x1f\x01\x05\x02\x05\n\x01\x02\x01\x01\r\x04\x02"},
 	{"internal/gate", "\r"},
 	{"internal/goarch", ""},
-	{"internal/godebug", "\xa6\x01\"\x85\x01\x01\x14"},
+	{"internal/godebug", "\xa7\x01\"\x85\x01\x01\x14"},
 	{"internal/godebugs", ""},
 	{"internal/goexperiment", ""},
 	{"internal/goos", ""},
-	{"internal/goroot", "\xb3\x02\x01\x05\x12\x02"},
+	{"internal/goroot", "\xb4\x02\x01\x05\x12\x02"},
 	{"internal/gover", "\x04"},
 	{"internal/goversion", ""},
-	{"internal/lazyregexp", "\xb3\x02\v\r\x02"},
-	{"internal/lazytemplate", "\x85\x02.\x18\x02\r"},
-	{"internal/msan", "\xe2\x02"},
-	{"internal/nettest", "\x03\nqG@\f\n\x12\x06\x15\x05\x0f"},
+	{"internal/lazyregexp", "\xb4\x02\v\r\x02"},
+	{"internal/lazytemplate", "\x86\x02.\x18\x02\r"},
+	{"internal/msan", "\xe3\x02"},
+	{"internal/nettest", "\x03\nrG@\f\n\x12\x06\x15\x05\x0f"},
 	{"internal/nettrace", ""},
-	{"internal/obscuretestdata", "o\x96\x01."},
-	{"internal/oserror", "~"},
-	{"internal/pkgbits", "\x03T\x19\x0e\x03\x04\vu\r!\r\n\x01"},
+	{"internal/obscuretestdata", "p\x96\x01."},
+	{"internal/oserror", "\x7f"},
+	{"internal/pkgbits", "\x03U\x19\x0e\x03\x04\vu\r!\r\n\x01"},
 	{"internal/platform", ""},
-	{"internal/poll", "~m\x05\x15;\r\x01\x01\r\x06"},
-	{"internal/profile", "\x03\x04w\x03\x84\x019\n\x01\x01\x01\x11"},
+	{"internal/poll", "\x7fm\x05\x15;\r\x01\x01\r\x06"},
+	{"internal/profile", "\x03\x04x\x03\x84\x019\n\x01\x01\x01\x11"},
 	{"internal/profilerecord", ""},
-	{"internal/race", "\xa4\x01\xbe\x01"},
-	{"internal/reflectlite", "\xa4\x01\"<>\""},
-	{"internal/runtime/atomic", "\xc6\x01\x9c\x01"},
-	{"internal/runtime/cgroup", "\xa8\x01?\x04w"},
-	{"internal/runtime/exithook", "\xdc\x01\x86\x01"},
-	{"internal/runtime/gc", "\xc6\x01"},
-	{"internal/runtime/gc/internal/gen", "\nf\x11\x17m\x04\v\x1f\b\x10\x02"},
-	{"internal/runtime/gc/scan", "\xbe\x01\b\x19\a|"},
-	{"internal/runtime/maps", "\xa4\x01\x01\x04\x15\b\x03\a\n\t\x03.N"},
-	{"internal/runtime/math", "\xc6\x01"},
+	{"internal/race", "\xa5\x01\xbe\x01"},
+	{"internal/reflectlite", "\xa5\x01\"<>\""},
+	{"internal/runtime/atomic", "\xc7\x01\x9c\x01"},
+	{"internal/runtime/cgroup", "\xa9\x01?\x04w"},
+	{"internal/runtime/exithook", "\xdd\x01\x86\x01"},
+	{"internal/runtime/gc", "\xc7\x01"},
+	{"internal/runtime/gc/internal/gen", "\ng\x11\x17m\x04\v\x1f\b\x10\x02"},
+	{"internal/runtime/gc/scan", "\xbf\x01\b\x19\a|"},
+	{"internal/runtime/maps", "\xa5\x01\x01\x04\x15\b\x03\a\n\t\x03.N"},
+	{"internal/runtime/math", "\xc7\x01"},
 	{"internal/runtime/pprof/label", ""},
 	{"internal/runtime/startlinetest", ""},
-	{"internal/runtime/sys", "\xc6\x01\x04"},
-	{"internal/runtime/syscall/linux", "\xc6\x01\x9c\x01"},
+	{"internal/runtime/sys", "\xc7\x01\x04"},
+	{"internal/runtime/syscall/linux", "\xc7\x01\x9c\x01"},
 	{"internal/runtime/wasitest", ""},
-	{"internal/saferio", "\x85\x02]"},
-	{"internal/singleflight", "\xcd\x02"},
-	{"internal/strconv", "\x94\x02N"},
-	{"internal/stringslite", "\xa8\x01\xba\x01"},
-	{"internal/sync", "\xa4\x01\"\x14t\x14"},
-	{"internal/synctest", "\xa4\x01\xbe\x01"},
-	{"internal/syscall/execenv", "\xcf\x02"},
-	{"internal/syscall/unix", "\xeb\x01U\x0e\x01\x13"},
-	{"internal/sysinfo", "\x02\x01\xbb\x01G.\x18\x02"},
+	{"internal/saferio", "\x86\x02]"},
+	{"internal/singleflight", "\xce\x02"},
+	{"internal/strconv", "\x95\x02N"},
+	{"internal/stringslite", "\xa9\x01\xba\x01"},
+	{"internal/sync", "\xa5\x01\"\x14t\x14"},
+	{"internal/synctest", "\xa5\x01\xbe\x01"},
+	{"internal/syscall/execenv", "\xd0\x02"},
+	{"internal/syscall/unix", "\xec\x01U\x0e\x01\x13"},
+	{"internal/sysinfo", "\x02\x01\xbc\x01G.\x18\x02"},
 	{"internal/syslist", ""},
-	{"internal/testenv", "\x03\nq\x02\x01)\x1c\x100-\x01\x05\a\n\x01\x02\x02\x01\f"},
-	{"internal/testhash", "\x03\x90\x01r\x11:\f"},
-	{"internal/testlog", "\xcd\x02\x01\x14"},
-	{"internal/testpty", "~\x03\xb2\x01"},
-	{"internal/trace", "\x02\x01\x01\x06f\x0e\x03x\x03\x03\x06\x03\t-\n\x01\x01\x01\x11\x06"},
-	{"internal/trace/internal/testgen", "\x03m\x11v\x03\x02\x03\x013\v\r\x11"},
-	{"internal/trace/internal/tracev1", "\x03\x01l\x0e\x03~\x06\f7\x01"},
-	{"internal/trace/raw", "\x02n\x11{\x03\x06E\x01\x13"},
-	{"internal/trace/testtrace", "\x02\x01{\x03r\x04\x03\x05\x01\x05.\v\x02\b\x02\x01\x05"},
+	{"internal/testenv", "\x03\nr\x02\x01)\x1c\x100-\x01\x05\a\n\x01\x02\x02\x01\f"},
+	{"internal/testhash", "\x03\x91\x01r\x11:\f"},
+	{"internal/testlog", "\xce\x02\x01\x14"},
+	{"internal/testpty", "\x7f\x03\xb2\x01"},
+	{"internal/trace", "\x02\x01\x01\x06g\x0e\x03x\x03\x03\x06\x03\t-\n\x01\x01\x01\x11\x06"},
+	{"internal/trace/internal/testgen", "\x03n\x11v\x03\x02\x03\x013\v\r\x11"},
+	{"internal/trace/internal/tracev1", "\x03\x01m\x0e\x03~\x06\f7\x01"},
+	{"internal/trace/raw", "\x02o\x11{\x03\x06E\x01\x13"},
+	{"internal/trace/testtrace", "\x02\x01|\x03r\x04\x03\x05\x01\x05.\v\x02\b\x02\x01\x05"},
 	{"internal/trace/tracev2", ""},
-	{"internal/trace/traceviewer", "\x02g\v\r\x19>\x1f\a\a\x04\b\v\x17\x01\x05\a\n\x01\x02\x0f"},
+	{"internal/trace/traceviewer", "\x02h\v\r\x19>\x1f\a\a\x04\b\v\x17\x01\x05\a\n\x01\x02\x0f"},
 	{"internal/trace/traceviewer/format", ""},
-	{"internal/trace/version", "\x81\x01{\t"},
-	{"internal/txtar", "\x03~\xb2\x01\x18"},
-	{"internal/types/errors", "\xca\x02"},
-	{"internal/unsafeheader", "\xe2\x02"},
-	{"internal/xcoff", "c\r\x0e\x03h\x1c.\x17\x01"},
-	{"internal/zstd", "p\x0e\x03\x84\x01\x0f"},
-	{"io", "~\xcf\x01"},
-	{"io/fs", "~*,13\x10\x14\x04"},
-	{"io/ioutil", "\x85\x02\x01-\x15\x03"},
-	{"iter", "\xda\x01f\""},
-	{"log", "\x81\x01\x84\x01\x05)\r\r\x01\x0e"},
+	{"internal/trace/version", "\x82\x01{\t"},
+	{"internal/txtar", "\x03\x7f\xb2\x01\x18"},
+	{"internal/types/errors", "\xcb\x02"},
+	{"internal/unsafeheader", "\xe3\x02"},
+	{"internal/xcoff", "d\r\x0e\x03h\x1c.\x17\x01"},
+	{"internal/zstd", "q\x0e\x03\x84\x01\x0f"},
+	{"io", "\x7f\xcf\x01"},
+	{"io/fs", "\x7f*,13\x10\x14\x04"},
+	{"io/ioutil", "\x86\x02\x01-\x15\x03"},
+	{"iter", "\xdb\x01f\""},
+	{"log", "\x82\x01\x84\x01\x05)\r\r\x01\x0e"},
 	{"log/internal", ""},
-	{"log/slog", "\x03\n^\t\n\x03H<\x04\x01\x02\x02\x03*\x05\b\x02\x01\x02\x01\x0e\x02\x02\x02"},
+	{"log/slog", "\x03\n_\t\n\x03H<\x04\x01\x02\x02\x03*\x05\b\x02\x01\x02\x01\x0e\x02\x02\x02"},
 	{"log/slog/internal", ""},
-	{"log/slog/internal/benchmarks", "\rq\x03\x84\x01\x06\x03<\x12"},
-	{"log/slog/internal/buffer", "\xcd\x02"},
-	{"log/syslog", "~\x03\x88\x01\x12\x18\x18\x02\x0f"},
-	{"maps", "\x88\x02Z"},
-	{"math", "\xbe\x01VN"},
-	{"math/big", "\x03{\x03(\x15G\f\x03\x022\x02\x01\x02\x15"},
-	{"math/big/internal/asmgen", "\x03\x01}\x93\x014\x03"},
-	{"math/bits", "\xe2\x02"},
-	{"math/cmplx", "\x91\x02\x03"},
-	{"math/rand", "\xc7\x01J<\x01\x14"},
-	{"math/rand/v2", "~+\x03e\x03N"},
-	{"mime", "\x02\x01l\x0f\x03\x84\x01\v#\x15\x03\x02\x11\x02"},
-	{"mime/multipart", "\x02\x01P+\x03F>\v\x01\a\x02\x17\x02\x06\x0f\x02\x01\x17"},
-	{"mime/quotedprintable", "\x02\x01~\x84\x01"},
-	{"net", "\x04\tq*\x1f\v\x05\x13\x01\x01\x04\x15\x01'\x06\r\b\x05\x01\x01\r\x06\t"},
-	{"net/http", "\x02\x01\x03\x01\x04\x02N\x14\x0f\x03F>\x01\x03\a\x01\x06\x01\x01\x02\x06\x02\x01\x01\f\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\x0e\x02\x02\x02\n\x01\x03"},
-	{"net/http/cgi", "\x02Y#\x03\x84\x01\x04\a\v\x01\x15\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x11\x10"},
-	{"net/http/cookiejar", "\x04z\x03\x9a\x01\x01\b\t\x05\x16\x03\x02\x0f\x04"},
-	{"net/http/fcgi", "\x02\x01\nc\x0e\x03\x84\x01\x16\x01\x01\x16\x18\x02\x0f"},
-	{"net/http/httptest", "\x02\x01\nN\x02#\x01P4\x04\x12\x01\f\t\x02\r\n\x01\x02\x03\f\x06\n"},
-	{"net/http/httptrace", "\rNwI\x16+"},
-	{"net/http/httputil", "\x02\x01\nq\x03F>\x04\x0f\x03\x01\x05\x02\x01\r\x01\x19\x02\x01\x0e\x10"},
-	{"net/http/internal", "\x02\x01m\x0e\x03\x84\x01"},
-	{"net/http/internal/ascii", "\xcb\x02\x13"},
-	{"net/http/internal/http2", "\x02\x01\x03\x01\x06F\b\x15\x0e\x03\x84\x01\x01\x03\b\x03\x02\x03\x02\x06\x02\x03\x01\n\x01\x01\b\x05\b\x02\x01\x02\x01\x0e\x10\x02\x02"},
-	{"net/http/internal/httpcommon", "\rq\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"},
-	{"net/http/internal/httpsfv", "\xc8\x02\x02\x01\x11\x04"},
-	{"net/http/internal/testcert", "\xcb\x02"},
-	{"net/http/pprof", "\x02\x01\nt\x18.\x11-\x04\x13\x16\x01\r\x04\x03\x01\x02\x01\x11"},
+	{"log/slog/internal/benchmarks", "\rr\x03\x84\x01\x06\x03<\x12"},
+	{"log/slog/internal/buffer", "\xce\x02"},
+	{"log/syslog", "\x7f\x03\x88\x01\x12\x18\x18\x02\x0f"},
+	{"maps", "\x89\x02Z"},
+	{"math", "\xbf\x01VN"},
+	{"math/big", "\x03|\x03(\x15G\f\x03\x022\x02\x01\x02\x15"},
+	{"math/big/internal/asmgen", "\x03\x01~\x93\x014\x03"},
+	{"math/bits", "\xe3\x02"},
+	{"math/cmplx", "\x92\x02\x03"},
+	{"math/rand", "\xc8\x01J<\x01\x14"},
+	{"math/rand/v2", "\x7f+\x03e\x03N"},
+	{"mime", "\x02\x01m\x0f\x03\x84\x01\v#\x15\x03\x02\x11\x02"},
+	{"mime/multipart", "\x02\x01Q+\x03F>\v\x01\a\x02\x17\x02\x06\x0f\x02\x01\x17"},
+	{"mime/quotedprintable", "\x02\x01\x7f\x84\x01"},
+	{"net", "\x04\tr*\x1f\v\x05\x13\x01\x01\x04\x15\x01'\x06\r\b\x05\x01\x01\r\x06\t"},
+	{"net/http", "\x02\x01\x03\x01\x04\x02O\x14\x0f\x03F>\x01\x03\a\x01\x06\x01\x01\x02\x06\x02\x01\x01\f\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\x0e\x02\x02\x02\n\x01\x03"},
+	{"net/http/cgi", "\x02Z#\x03\x84\x01\x04\a\v\x01\x15\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x11\x10"},
+	{"net/http/cookiejar", "\x04{\x03\x9a\x01\x01\b\t\x05\x16\x03\x02\x0f\x04"},
+	{"net/http/fcgi", "\x02\x01\nd\x0e\x03\x84\x01\x16\x01\x01\x16\x18\x02\x0f"},
+	{"net/http/httptest", "\x02\x01\nO\x02#\x01P4\x04\x12\x01\f\t\x02\r\n\x01\x02\x03\f\x06\n"},
+	{"net/http/httptrace", "\rOwI\x16+"},
+	{"net/http/httputil", "\x02\x01\nr\x03F>\x04\x0f\x03\x01\x05\x02\x01\r\x01\x19\x02\x0f\x10"},
+	{"net/http/internal", "\x02\x01n\x0e\x03\x84\x01"},
+	{"net/http/internal/ascii", "\xcc\x02\x13"},
+	{"net/http/internal/http2", "\x02\x01\x03\x01\x06G\b\x15\x0e\x03\x84\x01\x01\x03\b\x03\x02\x03\x02\x06\x02\x03\x01\n\x01\x01\b\x05\b\x02\x01\x02\x01\x0e\x10\x02\x02"},
+	{"net/http/internal/httpcommon", "\rr\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"},
+	{"net/http/internal/httpsfv", "\xc9\x02\x02\x01\x11\x04"},
+	{"net/http/internal/testcert", "\xcc\x02"},
+	{"net/http/pprof", "\x02\x01\nu\x18.\x11-\x04\x13\x16\x01\r\x04\x03\x01\x02\x01\x11"},
 	{"net/internal/cgotest", ""},
-	{"net/internal/socktest", "\x81\x01\xcc\x01\x02"},
-	{"net/mail", "\x02|\x03\x84\x01\x04\x0f\x03\x16\x1a\x02\x0f\x04"},
-	{"net/netip", "\x04z*\x01h\x036\x17"},
-	{"net/rpc", "\x02p\f\x03\x0f\nk\x04\x12\x01\x1f\r\x03\x02"},
-	{"net/rpc/jsonrpc", "t\n\x03\x84\x01\x16\x13\x1f"},
-	{"net/smtp", "\x195\r\x14\x0f\x03\x84\x01\x16\x16\x1a"},
-	{"net/textproto", "\x02\x01{\x03\x84\x01\f\n/\x01\x02\x15"},
-	{"net/url", "~\x03Ff\v\x10\x02\x01\x17"},
-	{"os", "~*\x01\x19\x04\x11\x14\x01\x03\x01\x05\x10\x01:\b\x05\x01\x01\r\x06"},
-	{"os/exec", "\x03\nqI(\x01\x15\x01-\x06\a\n\x01\x03\x01\r"},
-	{"os/exec/internal/fdtest", "\xcf\x02"},
-	{"os/signal", "\r\xa6\x02\x15\x05\x02"},
-	{"os/user", "\x02\x01{\x03\x84\x01.\r\n\x01\x02"},
-	{"path", "~*\xb8\x01"},
-	{"path/filepath", "~*\x1aD-\r\b\x03\x04\x11"},
-	{"plugin", "~"},
-	{"reflect", "~&\x04\x1e\x03\x11\b\x04\x05\x17\x06\t/\n\x03\x11\x02\x02"},
+	{"net/internal/socktest", "\x82\x01\xcc\x01\x02"},
+	{"net/mail", "\x02}\x03\x84\x01\x04\x0f\x03\x16\x1a\x02\x0f\x04"},
+	{"net/netip", "\x04{*\x01h\x036\x17"},
+	{"net/rpc", "\x02q\f\x03\x0f\nk\x04\x12\x01\x1f\r\x03\x02"},
+	{"net/rpc/jsonrpc", "u\n\x03\x84\x01\x16\x13\x1f"},
+	{"net/smtp", "\x196\r\x14\x0f\x03\x84\x01\x16\x16\x1a"},
+	{"net/textproto", "\x02\x01|\x03\x84\x01\f\n/\x01\x02\x15"},
+	{"net/url", "\x7f\x03Ff\v\x10\x02\x01\x17"},
+	{"os", "\x7f*\x01\x19\x04\x11\x14\x01\x03\x01\x05\x10\x01:\b\x05\x01\x01\r\x06"},
+	{"os/exec", "\x03\nrI(\x01\x15\x01-\x06\a\n\x01\x03\x01\r"},
+	{"os/exec/internal/fdtest", "\xd0\x02"},
+	{"os/signal", "\r\xa7\x02\x15\x05\x02"},
+	{"os/user", "\x02\x01|\x03\x84\x01.\r\n\x01\x02"},
+	{"path", "\x7f*\xb8\x01"},
+	{"path/filepath", "\x7f*\x1aD-\r\b\x03\x04\x11"},
+	{"plugin", "\x7f"},
+	{"reflect", "\x7f&\x04\x1e\x03\x11\b\x04\x05\x17\x06\t/\n\x03\x11\x02\x02"},
 	{"reflect/internal/example1", ""},
 	{"reflect/internal/example2", ""},
-	{"regexp", "\x03\x82\x02\x037\t\x02\x01\x02\x11\x02"},
-	{"regexp/syntax", "\xc8\x02\x01\x01\x01\x02\x11\x02"},
-	{"runtime", "\xa4\x01\x04\x01\x03\f\x06\b\x02\x01\x01\x0f\x03\x01\x01\x01\x02\x01\x01\x01\x02\x01\x04\x01\x10\x18N"},
-	{"runtime/coverage", "\xb0\x01U"},
-	{"runtime/debug", "\x81\x01V\\\r\b\x02\x01\x11\x06"},
-	{"runtime/metrics", "\xc8\x01I/\""},
-	{"runtime/pprof", "\x02\x01\x01\x03\x06c\x0e\x03#5\v!\f\"\r\b\x01\x01\x01\x02\x02\n\x03\x06"},
-	{"runtime/race", "\xc6\x02"},
+	{"regexp", "\x03\x83\x02\x037\t\x02\x01\x02\x11\x02"},
+	{"regexp/syntax", "\xc9\x02\x01\x01\x01\x02\x11\x02"},
+	{"runtime", "\xa5\x01\x04\x01\x03\f\x06\b\x02\x01\x01\x0f\x03\x01\x01\x01\x02\x01\x01\x01\x02\x01\x04\x01\x10\x18N"},
+	{"runtime/coverage", "\xb1\x01U"},
+	{"runtime/debug", "\x82\x01V\\\r\b\x02\x01\x11\x06"},
+	{"runtime/metrics", "\xc9\x01I/\""},
+	{"runtime/pprof", "\x02\x01\x01\x03\x06d\x0e\x03#5\v!\f\"\r\b\x01\x01\x01\x02\x02\n\x03\x06"},
+	{"runtime/race", "\xc7\x02"},
 	{"runtime/race/internal/amd64v1", ""},
-	{"runtime/trace", "\rq\x03{\t;\b\x05\x01\x0e\x06"},
-	{"slices", "\x04\x84\x02\fN"},
-	{"sort", "\xdb\x0194"},
-	{"strconv", "~*C\x01t"},
-	{"strings", "~&\x04D\x19\x03\f9\x11\x02\x02"},
+	{"runtime/trace", "\rr\x03{\t;\b\x05\x01\x0e\x06"},
+	{"slices", "\x04\x85\x02\fN"},
+	{"sort", "\xdc\x0194"},
+	{"strconv", "\x7f*C\x01t"},
+	{"strings", "\x7f&\x04D\x19\x03\f9\x11\x02\x02"},
 	{"structs", ""},
-	{"sync", "\xda\x01\x02\x11\x01R\x0e\x14"},
-	{"sync/atomic", "\xe2\x02"},
-	{"syscall", "~'\x03\x01\x1d\n\x04\x06\r\x04U\b\x05\x01\x14"},
-	{"testing", "\x03\nq\x02\x01Y\x17\x14\f\x05\x1d\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\x0e\x02\x04"},
-	{"testing/cryptotest", "SV\\\x126\x03\x12"},
-	{"testing/fstest", "~\x03\x84\x01\x01\n(\x10\x03\t\b"},
-	{"testing/internal/testdeps", "\x02\v\xb7\x011\x10.\x03\x05\x03\x06\a\x02\x0f"},
-	{"testing/iotest", "\x03{\x03\x84\x01\x04"},
-	{"testing/quick", "\x80\x01\x01\x90\x01\x05%\x10\x11"},
-	{"testing/slogtest", "\rq\x03\x8a\x010\x05\x10\f"},
-	{"testing/synctest", "\xee\x01b\f\x06"},
-	{"text/scanner", "\x03~\x84\x01.+\x02"},
-	{"text/tabwriter", "\x81\x01\x84\x01["},
-	{"text/template", "~\x03BB\x01\n\"\x01\x05\x01\x02\x05\v\x02\x0e\x03\x02"},
-	{"text/template/parse", "\x03~\xbf\x01\n\x01\x13\x02"},
-	{"time", "~*D(,\r\x02\x13"},
-	{"time/tzdata", "~\xd1\x01\x13"},
+	{"sync", "\xdb\x01\x02\x11\x01R\x0e\x14"},
+	{"sync/atomic", "\xe3\x02"},
+	{"syscall", "\x7f'\x03\x01\x1d\n\x04\x06\r\x04U\b\x05\x01\x14"},
+	{"testing", "\x03\nr\x02\x01Y\x17\x14\f\x05\x1d\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\x0e\x02\x04"},
+	{"testing/cryptotest", "TV\\\x126\x03\x12"},
+	{"testing/fstest", "\x7f\x03\x84\x01\x01\n(\x10\x03\t\b"},
+	{"testing/internal/testdeps", "\x02\v\xb8\x011\x10.\x03\x05\x03\x06\a\x02\x0f"},
+	{"testing/iotest", "\x03|\x03\x84\x01\x04"},
+	{"testing/quick", "\x81\x01\x01\x90\x01\x05%\x10\x11"},
+	{"testing/slogtest", "\rr\x03\x8a\x010\x05\x10\f"},
+	{"testing/synctest", "\xef\x01b\f\x06"},
+	{"text/scanner", "\x03\x7f\x84\x01.+\x02"},
+	{"text/tabwriter", "\x82\x01\x84\x01["},
+	{"text/template", "\x7f\x03BB\x01\n\"\x01\x05\x01\x02\x05\v\x02\x0e\x03\x02"},
+	{"text/template/parse", "\x03\x7f\xbf\x01\n\x01\x13\x02"},
+	{"time", "\x7f*D(,\r\x02\x13"},
+	{"time/tzdata", "\x7f\xd1\x01\x13"},
 	{"unicode", ""},
 	{"unicode/utf16", ""},
 	{"unicode/utf8", ""},
-	{"unique", "\xa4\x01\"&\x01S\r\x01\x14\x19"},
+	{"unique", "\xa5\x01\"&\x01S\r\x01\x14\x19"},
 	{"unsafe", ""},
-	{"uuid", "\x03\x01O\x1d\x03\v\xcf\x01\x0f"},
-	{"vendor/golang.org/x/crypto/chacha20", "\x10`\x0e\x96\x01,)"},
-	{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10\aY\x0e\xe6\x01\x05\x01\f"},
-	{"vendor/golang.org/x/crypto/cryptobyte", "m\x11\x03\x91\x01)!\v"},
+	{"uuid", "\x03\x01P\x1d\x03\v\xcf\x01\x0f"},
+	{"vendor/golang.org/x/crypto/chacha20", "\x10a\x0e\x96\x01,)"},
+	{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10\aZ\x0e\xe6\x01\x05\x01\f"},
+	{"vendor/golang.org/x/crypto/cryptobyte", "n\x11\x03\x91\x01)!\v"},
 	{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
-	{"vendor/golang.org/x/crypto/hkdf", "\x18\x01e\x15r"},
-	{"vendor/golang.org/x/crypto/internal/alias", "\xe2\x02"},
-	{"vendor/golang.org/x/crypto/internal/poly1305", "Z\x16\xa4\x01"},
-	{"vendor/golang.org/x/net/dns/dnsmessage", "~\xca\x01"},
-	{"vendor/golang.org/x/net/http/httpguts", "\x9b\x02\x16\x1a\x15\x10"},
-	{"vendor/golang.org/x/net/http/httpproxy", "~\x03\x9a\x01\x12\x05\x01\x18\x15\x10"},
-	{"vendor/golang.org/x/net/http2/hpack", "\x03{\x03\x84\x01H"},
-	{"vendor/golang.org/x/net/http3", "\x9c\x02@\x06\x0f\x04"},
-	{"vendor/golang.org/x/net/idna", "\x81\x01\x90\x01:\x13\x02\x17\x02\x01"},
-	{"vendor/golang.org/x/net/internal/http3", "\rN#\x03\x84\x01\v\x04\a\x01\x05\x10\x01\x16\x02\x01\x02\x0f\x10\x02\x04\x03"},
-	{"vendor/golang.org/x/net/internal/httpcommon", "\rq\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"},
-	{"vendor/golang.org/x/net/internal/quic/quicwire", "p"},
-	{"vendor/golang.org/x/net/nettest", "\x03m\x0e\x03\x84\x01\x11\x05\x18\x01\f\n\x01\x02\x02\x01\f"},
-	{"vendor/golang.org/x/net/quic", "\x03\n\x01\x01\x01\t:\x04\x04\x15\x03\v\x03\x12r\x06\x06\x06\x04\x12\x06\x15\x02\x01\x02\x01\x01\r\x06\x02\x01\x01\x02\v"},
-	{"vendor/golang.org/x/sys/cpu", "\xb3\x02\r\n\x01\x17"},
-	{"vendor/golang.org/x/text/secure/bidirule", "~\xe2\x01\x18\x01"},
-	{"vendor/golang.org/x/text/transform", "\x03{\x87\x01["},
-	{"vendor/golang.org/x/text/unicode/bidi", "\x03\bv\x88\x01@\x17"},
-	{"vendor/golang.org/x/text/unicode/norm", "p\x11\x84\x01H\x13\x18"},
-	{"weak", "\xa4\x01\x9c\x01\""},
+	{"vendor/golang.org/x/crypto/hkdf", "\x18\x01f\x15r"},
+	{"vendor/golang.org/x/crypto/internal/alias", "\xe3\x02"},
+	{"vendor/golang.org/x/crypto/internal/poly1305", "[\x16\xa4\x01"},
+	{"vendor/golang.org/x/net/dns/dnsmessage", "\x7f\xca\x01"},
+	{"vendor/golang.org/x/net/http/httpguts", "\x9c\x02\x16\x1a\x15\x10"},
+	{"vendor/golang.org/x/net/http/httpproxy", "\x7f\x03\x9a\x01\x12\x05\x01\x18\x15\x10"},
+	{"vendor/golang.org/x/net/http2/hpack", "\x03|\x03\x84\x01H"},
+	{"vendor/golang.org/x/net/http3", "\x9d\x02@\x06\x0f\x04"},
+	{"vendor/golang.org/x/net/idna", "\x82\x01\x90\x01:\x13\x02\x17\x02\x01"},
+	{"vendor/golang.org/x/net/internal/http3", "\rO#\x03\x84\x01\v\x04\a\x01\x05\x10\x01\x16\x02\x01\x02\x0f\x10\x02\x04\x03"},
+	{"vendor/golang.org/x/net/internal/httpcommon", "\rr\x03\xa0\x01\x10\x01\x17\x01\x01\x02\x1f\x02"},
+	{"vendor/golang.org/x/net/internal/quic/quicwire", "q"},
+	{"vendor/golang.org/x/net/nettest", "\x03n\x0e\x03\x84\x01\x11\x05\x18\x01\f\n\x01\x02\x02\x01\f"},
+	{"vendor/golang.org/x/net/quic", "\x03\n\x01\x01\x01\t;\x04\x04\x15\x03\v\x03\x12r\x06\x06\x06\x04\x12\x06\x15\x02\x01\x02\x01\x01\r\x06\x02\x01\x01\x02\v"},
+	{"vendor/golang.org/x/sys/cpu", "\xb4\x02\r\n\x01\x17"},
+	{"vendor/golang.org/x/text/secure/bidirule", "\x7f\xe2\x01\x18\x01"},
+	{"vendor/golang.org/x/text/transform", "\x03|\x87\x01["},
+	{"vendor/golang.org/x/text/unicode/bidi", "\x03\bw\x88\x01@\x17"},
+	{"vendor/golang.org/x/text/unicode/norm", "q\x11\x84\x01H\x13\x18"},
+	{"weak", "\xa5\x01\x9c\x01\""},
 }
 
 // bootstrap is the list of bootstrap packages extracted from cmd/dist.
diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
index 2180c296ec..e11abf0455 100644
--- a/vendor/golang.org/x/tools/internal/stdlib/manifest.go
+++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
@@ -9153,6 +9153,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"CrossOriginProtection", Type, 25, ""},
 		{"DefaultClient", Var, 0, ""},
 		{"DefaultMaxHeaderBytes", Const, 0, ""},
+		{"DefaultMaxHeaderValueCount", Const, 27, ""},
 		{"DefaultMaxIdleConnsPerHost", Const, 0, ""},
 		{"DefaultServeMux", Var, 0, ""},
 		{"DefaultTransport", Var, 0, ""},
@@ -9317,6 +9318,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"Server.Handler", Field, 0, ""},
 		{"Server.IdleTimeout", Field, 8, ""},
 		{"Server.MaxHeaderBytes", Field, 0, ""},
+		{"Server.MaxHeaderValueCount", Field, 27, ""},
 		{"Server.Protocols", Field, 24, ""},
 		{"Server.ReadHeaderTimeout", Field, 8, ""},
 		{"Server.ReadTimeout", Field, 0, ""},
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 6e07b2579f..99061d270f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -5,10 +5,10 @@ charm.land/bubbles/v2/internal/runeutil
 charm.land/bubbles/v2/key
 charm.land/bubbles/v2/textinput
 charm.land/bubbles/v2/viewport
-# charm.land/bubbletea/v2 v2.0.7
+# charm.land/bubbletea/v2 v2.0.8
 ## explicit; go 1.25.0
 charm.land/bubbletea/v2
-# charm.land/lipgloss/v2 v2.0.4
+# charm.land/lipgloss/v2 v2.0.5
 ## explicit; go 1.25.0
 charm.land/lipgloss/v2
 # charm.land/log/v2 v2.0.0
@@ -46,7 +46,7 @@ github.com/charmbracelet/keygen
 # github.com/charmbracelet/ssh v0.0.0-20250826160808-ebfa259c7309
 ## explicit; go 1.23.0
 github.com/charmbracelet/ssh
-# github.com/charmbracelet/ultraviolet v0.0.0-20260525132238-948f4557a654
+# github.com/charmbracelet/ultraviolet v0.0.0-20260703014108-f5a850f9c2b7
 ## explicit; go 1.25.0
 github.com/charmbracelet/ultraviolet
 # github.com/charmbracelet/x/ansi v0.11.7
@@ -195,7 +195,7 @@ github.com/insomniacslk/dhcp/rfc1035label
 # github.com/josharian/native v1.1.0
 ## explicit; go 1.13
 github.com/josharian/native
-# github.com/klauspost/compress v1.19.0
+# github.com/klauspost/compress v1.19.1
 ## explicit; go 1.24
 github.com/klauspost/compress
 github.com/klauspost/compress/fse
@@ -220,8 +220,8 @@ github.com/mattn/go-runewidth
 # github.com/mdlayher/genetlink v1.4.0
 ## explicit; go 1.25.0
 github.com/mdlayher/genetlink
-# github.com/mdlayher/netlink v1.9.0
-## explicit; go 1.24.0
+# github.com/mdlayher/netlink v1.11.2
+## explicit; go 1.25.0
 github.com/mdlayher/netlink
 github.com/mdlayher/netlink/nlenc
 github.com/mdlayher/netlink/nltest
@@ -264,7 +264,7 @@ github.com/pierrec/lz4/v4/internal/xxh32
 # github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
 ## explicit
 github.com/pmezard/go-difflib/difflib
-# github.com/prometheus/client_golang v1.24.0
+# github.com/prometheus/client_golang v1.24.1
 ## explicit; go 1.25.0
 github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil
 github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header
@@ -276,7 +276,7 @@ github.com/prometheus/client_golang/prometheus/promhttp/internal
 # github.com/prometheus/client_model v0.6.2
 ## explicit; go 1.22.0
 github.com/prometheus/client_model/go
-# github.com/prometheus/common v0.70.0
+# github.com/prometheus/common v0.70.1
 ## explicit; go 1.25.0
 github.com/prometheus/common/expfmt
 github.com/prometheus/common/model
@@ -424,7 +424,7 @@ golang.org/x/sys/cpu
 golang.org/x/sys/plan9
 golang.org/x/sys/unix
 golang.org/x/sys/windows
-# golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57
+# golang.org/x/telemetry v0.0.0-20260708182218-49f421fb7959
 ## explicit; go 1.25.0
 golang.org/x/telemetry/counter
 golang.org/x/telemetry/internal/counter
@@ -439,7 +439,7 @@ golang.org/x/text/secure/bidirule
 golang.org/x/text/transform
 golang.org/x/text/unicode/bidi
 golang.org/x/text/unicode/norm
-# golang.org/x/tools v0.47.0
+# golang.org/x/tools v0.48.0
 ## explicit; go 1.25.0
 golang.org/x/tools/cmd/goimports
 golang.org/x/tools/go/ast/astutil
@@ -458,6 +458,7 @@ golang.org/x/tools/internal/gcimporter
 golang.org/x/tools/internal/gocommand
 golang.org/x/tools/internal/gopathwalk
 golang.org/x/tools/internal/imports
+golang.org/x/tools/internal/modindex
 golang.org/x/tools/internal/packagesinternal
 golang.org/x/tools/internal/pkgbits
 golang.org/x/tools/internal/stdlib