diff --git a/go.mod b/go.mod index 8133212be..3f97508cd 100644 --- a/go.mod +++ b/go.mod @@ -3,24 +3,24 @@ module github.com/containernetworking/plugins go 1.25.0 require ( - github.com/Microsoft/hcsshim v0.14.0 + github.com/Microsoft/hcsshim v0.14.1 github.com/alexflint/go-filemutex v1.3.0 - github.com/buger/jsonparser v1.1.2 + github.com/buger/jsonparser v1.2.0 github.com/containernetworking/cni v1.3.0 github.com/coreos/go-iptables v0.8.0 github.com/coreos/go-systemd/v22 v22.7.0 github.com/godbus/dbus/v5 v5.2.2 github.com/insomniacslk/dhcp v0.0.0-20240829085014-a3a4c1f04475 - github.com/mattn/go-shellwords v1.0.12 + github.com/mattn/go-shellwords v1.0.13 github.com/networkplumbing/go-nft v0.4.0 - github.com/onsi/ginkgo/v2 v2.28.1 - github.com/onsi/gomega v1.39.1 - github.com/opencontainers/selinux v1.13.1 + github.com/onsi/ginkgo/v2 v2.29.0 + github.com/onsi/gomega v1.40.0 + github.com/opencontainers/selinux v1.15.0 github.com/pkg/errors v0.9.1 github.com/safchain/ethtool v0.7.0 github.com/vishvananda/netlink v1.3.1 github.com/vishvananda/netns v0.0.5 - golang.org/x/sys v0.42.0 + golang.org/x/sys v0.43.0 sigs.k8s.io/knftables v0.0.21 ) @@ -38,7 +38,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect + github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect github.com/josharian/native v1.1.0 // indirect github.com/mdlayher/packet v1.1.2 // indirect github.com/mdlayher/socket v0.5.1 // indirect @@ -47,11 +47,11 @@ require ( github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect go.opencensus.io v0.24.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/mod v0.32.0 // indirect - golang.org/x/net v0.49.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/text v0.33.0 // indirect - golang.org/x/tools v0.41.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/tools v0.44.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/grpc v1.79.3 // indirect google.golang.org/protobuf v1.36.10 // indirect diff --git a/go.sum b/go.sum index 2d413eae3..5af0d8ecc 100644 --- a/go.sum +++ b/go.sum @@ -6,12 +6,12 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1 github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.14.0 h1:zM3pLAB7JYhkzASOnNQc7FlSP6emfsTj9dx2hr69f/s= -github.com/Microsoft/hcsshim v0.14.0/go.mod h1:hTKFGbnDtQb1wHiOWv4v0eN+7boSWAHyK/tNAaYZL0c= +github.com/Microsoft/hcsshim v0.14.1 h1:CMuB3fqQVfPdhyXhUqYdUmPUIOhJkmghCx3dJet8Cqs= +github.com/Microsoft/hcsshim v0.14.1/go.mod h1:VnzvPLyWUhxiPVsJ31P6XadxCcTogTguBFDy/1GR/OM= github.com/alexflint/go-filemutex v1.3.0 h1:LgE+nTUWnQCyRKbpoceKZsPQbs84LivvgwUymZXdOcM= github.com/alexflint/go-filemutex v1.3.0/go.mod h1:U0+VA/i30mGBlLCrFPGtTe9y6wGQfNAWPBTekHQ+c8A= -github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= -github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/buger/jsonparser v1.2.0 h1:4EFcvK1kD4jyj6YqNK6skK6w+y7FHHBR+XBCtxwu/6g= +github.com/buger/jsonparser v1.2.0/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -78,8 +78,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= -github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= +github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 h1:EwtI+Al+DeppwYX2oXJCETMO23COyaKGP6fHVpkpWpg= +github.com/google/pprof v0.0.0-20260402051712-545e8a4df936/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8= github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= @@ -99,8 +99,8 @@ github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffkt github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= -github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/mattn/go-shellwords v1.0.13 h1:DC0OMEpGjm6LfNFU4ckYcvbQKyp2vE8atyFGXNtDcf4= +github.com/mattn/go-shellwords v1.0.13/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= 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.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= @@ -109,12 +109,12 @@ github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3v github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= github.com/networkplumbing/go-nft v0.4.0 h1:kExVMwXW48DOAukkBwyI16h4uhE5lN9iMvQd52lpTyU= github.com/networkplumbing/go-nft v0.4.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs= -github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI= -github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE= -github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= -github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= -github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE= -github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg= +github.com/onsi/ginkgo/v2 v2.29.0 h1:rfh+ZFjgJhYWRoIqVf3Uwx/W20yLrcrE2h2GmYVRaag= +github.com/onsi/ginkgo/v2 v2.29.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= +github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc= +github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A= +github.com/opencontainers/selinux v1.15.0 h1:4Gs40e/R2FvM8PC1HPaPncLLaDor8Y2WDfk5gjU9o5M= +github.com/opencontainers/selinux v1.15.0/go.mod h1:LenyElirjUHszfxrjuFqC85HIeXZKumHcKMQtnaDlQQ= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -169,8 +169,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -181,8 +181,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -190,8 +190,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -203,13 +203,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc 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.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -219,8 +219,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/buger/jsonparser/.gitignore b/vendor/github.com/buger/jsonparser/.gitignore index 5598d8a56..af589f860 100644 --- a/vendor/github.com/buger/jsonparser/.gitignore +++ b/vendor/github.com/buger/jsonparser/.gitignore @@ -10,3 +10,9 @@ vendor/github.com/buger/goterm/ prof.cpu prof.mem +.proof/ +tests/ +PROOF_*.md +REQPROOF_*.md +proof-ux-log.md +PROOF_UNDER_MODELED_REQUIREMENTS_PROPOSAL.md diff --git a/vendor/github.com/buger/jsonparser/README.md b/vendor/github.com/buger/jsonparser/README.md index 0b2f1fb03..391edba1e 100644 --- a/vendor/github.com/buger/jsonparser/README.md +++ b/vendor/github.com/buger/jsonparser/README.md @@ -337,6 +337,25 @@ https://github.com/buger/jsonparser/blob/master/benchmark/benchmark_large_payloa Also last benchmark did not included `EachKey` test, because in this particular case we need to read lot of Array values, and using `ArrayEach` is more efficient. +## Formal Verification + + + +This project uses [ReqProof](https://reqproof.com) for formal requirements verification, achieving: + +- **92 formally specified requirements** covering all public API behavior including edge cases, malformed input, boundary values, and error propagation +- **100% MC/DC coverage** (Modified Condition/Decision Coverage) — every boolean decision in the code is independently proven exercised +- **Kind2 model checking** — mathematical proof that the specification is realizable and consistent +- **Z3 SMT proofs** — data-level properties verified for all possible inputs, not just test samples + +ReqProof found **2 real bugs** during the verification process ([see PR #281](https://github.com/buger/jsonparser/pull/281)): +1. `Delete` panic on truncated JSON input — bounds check missing after internal sentinel value +2. `ArrayEach` callback silently swallowing parse errors — the callback's `err` parameter was always nil + +It also identified and safely removed **7 dead code blocks** that MC/DC analysis proved unreachable from any input. + +The verification runs on every PR via [probelabs/proof-action](https://github.com/probelabs/proof-action). + ## Questions and support All bug-reports and suggestions should go though Github Issues. diff --git a/vendor/github.com/buger/jsonparser/bytes.go b/vendor/github.com/buger/jsonparser/bytes.go index 9d6e701f5..f5414b6f9 100644 --- a/vendor/github.com/buger/jsonparser/bytes.go +++ b/vendor/github.com/buger/jsonparser/bytes.go @@ -1,3 +1,4 @@ +// SYS-REQ-015, SYS-REQ-058, SYS-REQ-059, SYS-REQ-064: integer parsing internals package jsonparser const absMinInt64 = 1 << 63 diff --git a/vendor/github.com/buger/jsonparser/bytes_safe.go b/vendor/github.com/buger/jsonparser/bytes_safe.go index ff16a4a19..7aa73c42f 100644 --- a/vendor/github.com/buger/jsonparser/bytes_safe.go +++ b/vendor/github.com/buger/jsonparser/bytes_safe.go @@ -1,5 +1,6 @@ -// +build appengine appenginevm +// +build appengine appenginevm tinygo +// SYS-REQ-001, SYS-REQ-013, SYS-REQ-014: safe build-tag byte utilities package jsonparser import ( diff --git a/vendor/github.com/buger/jsonparser/bytes_unsafe.go b/vendor/github.com/buger/jsonparser/bytes_unsafe.go index 589fea87e..8a44d7205 100644 --- a/vendor/github.com/buger/jsonparser/bytes_unsafe.go +++ b/vendor/github.com/buger/jsonparser/bytes_unsafe.go @@ -1,5 +1,6 @@ -// +build !appengine,!appenginevm +// +build !appengine,!appenginevm, !tinygo +// SYS-REQ-001, SYS-REQ-013, SYS-REQ-014: unsafe build-tag byte utilities package jsonparser import ( diff --git a/vendor/github.com/buger/jsonparser/escape.go b/vendor/github.com/buger/jsonparser/escape.go index 49669b942..62be30d21 100644 --- a/vendor/github.com/buger/jsonparser/escape.go +++ b/vendor/github.com/buger/jsonparser/escape.go @@ -1,3 +1,4 @@ +// SYS-REQ-014, SYS-REQ-060, SYS-REQ-061, SYS-REQ-062, SYS-REQ-063: string escape and Unicode handling package jsonparser import ( @@ -63,8 +64,12 @@ func decodeUnicodeEscape(in []byte) (rune, int) { if r, ok := decodeSingleUnicodeEscape(in); !ok { // Invalid Unicode escape return utf8.RuneError, -1 - } else if r <= basicMultilingualPlaneOffset && !isUTF16EncodedRune(r) { - // Valid Unicode escape in Basic Multilingual Plane + } else if !isUTF16EncodedRune(r) { + // Valid Unicode escape in Basic Multilingual Plane. + // Note: a single \uXXXX escape produces r in [0, 0xFFFF], so r is always + // within the BMP. The former r <= basicMultilingualPlaneOffset guard was + // tautological and has been removed — the real discriminator is whether r + // falls in the UTF-16 surrogate range. return r, 6 } else if r2, ok := decodeSingleUnicodeEscape(in[6:]); !ok { // Note: previous decodeSingleUnicodeEscape success guarantees at least 6 bytes remain // UTF16 "high surrogate" without manditory valid following Unicode escape for the "low surrogate" @@ -145,7 +150,11 @@ func Unescape(in, out []byte) ([]byte, error) { in = in[firstBackslash:] buf := out[firstBackslash:] - for len(in) > 0 { + // The loop always exits via break: either on error (MalformedStringEscapeError) + // or after copying the final non-escaped tail. The former `for len(in) > 0` + // guard was structurally always true on re-entry since the else branch always + // leaves at least the backslash character in `in`. + for { // Unescape the next escaped character inLen, bufLen := unescapeToUTF8(in, buf) if inLen == -1 { diff --git a/vendor/github.com/buger/jsonparser/fuzz.go b/vendor/github.com/buger/jsonparser/fuzz.go index 854bd11b2..75bbedbf2 100644 --- a/vendor/github.com/buger/jsonparser/fuzz.go +++ b/vendor/github.com/buger/jsonparser/fuzz.go @@ -1,5 +1,6 @@ package jsonparser +// SYS-REQ-014 func FuzzParseString(data []byte) int { r, err := ParseString(data) if err != nil || r == "" { @@ -8,6 +9,7 @@ func FuzzParseString(data []byte) int { return 1 } +// SYS-REQ-008 func FuzzEachKey(data []byte) int { paths := [][]string{ {"name"}, @@ -27,11 +29,13 @@ func FuzzEachKey(data []byte) int { return 1 } +// SYS-REQ-010 func FuzzDelete(data []byte) int { Delete(data, "test") return 1 } +// SYS-REQ-009 func FuzzSet(data []byte) int { _, err := Set(data, []byte(`"new value"`), "test") if err != nil { @@ -40,6 +44,7 @@ func FuzzSet(data []byte) int { return 1 } +// SYS-REQ-007 func FuzzObjectEach(data []byte) int { _ = ObjectEach(data, func(key, value []byte, valueType ValueType, off int) error { return nil @@ -47,6 +52,7 @@ func FuzzObjectEach(data []byte) int { return 1 } +// SYS-REQ-013 func FuzzParseFloat(data []byte) int { _, err := ParseFloat(data) if err != nil { @@ -55,6 +61,7 @@ func FuzzParseFloat(data []byte) int { return 1 } +// SYS-REQ-015 func FuzzParseInt(data []byte) int { _, err := ParseInt(data) if err != nil { @@ -63,6 +70,7 @@ func FuzzParseInt(data []byte) int { return 1 } +// SYS-REQ-012 func FuzzParseBool(data []byte) int { _, err := ParseBoolean(data) if err != nil { @@ -71,11 +79,13 @@ func FuzzParseBool(data []byte) int { return 1 } +// SYS-REQ-001 func FuzzTokenStart(data []byte) int { _ = tokenStart(data) return 1 } +// SYS-REQ-002 func FuzzGetString(data []byte) int { _, err := GetString(data, "test") if err != nil { @@ -84,6 +94,7 @@ func FuzzGetString(data []byte) int { return 1 } +// SYS-REQ-004 func FuzzGetFloat(data []byte) int { _, err := GetFloat(data, "test") if err != nil { @@ -92,6 +103,7 @@ func FuzzGetFloat(data []byte) int { return 1 } +// SYS-REQ-003 func FuzzGetInt(data []byte) int { _, err := GetInt(data, "test") if err != nil { @@ -100,6 +112,7 @@ func FuzzGetInt(data []byte) int { return 1 } +// SYS-REQ-005 func FuzzGetBoolean(data []byte) int { _, err := GetBoolean(data, "test") if err != nil { @@ -108,6 +121,7 @@ func FuzzGetBoolean(data []byte) int { return 1 } +// SYS-REQ-011 func FuzzGetUnsafeString(data []byte) int { _, err := GetUnsafeString(data, "test") if err != nil { diff --git a/vendor/github.com/buger/jsonparser/parser.go b/vendor/github.com/buger/jsonparser/parser.go index 1a4e33722..d8df1678d 100644 --- a/vendor/github.com/buger/jsonparser/parser.go +++ b/vendor/github.com/buger/jsonparser/parser.go @@ -25,6 +25,7 @@ var ( // than this needs to be escaped, it will result in a heap allocation const unescapeStackBufSize = 64 +// SYS-REQ-044 func tokenEnd(data []byte) int { for i, c := range data { switch c { @@ -36,6 +37,7 @@ func tokenEnd(data []byte) int { return len(data) } +// SYS-REQ-001 func findTokenStart(data []byte, token byte) int { for i := len(data) - 1; i >= 0; i-- { switch data[i] { @@ -49,13 +51,16 @@ func findTokenStart(data []byte, token byte) int { return 0 } +// SYS-REQ-001, SYS-REQ-020, SYS-REQ-024 func findKeyStart(data []byte, key string) (int, error) { i := nextToken(data) if i == -1 { return i, KeyPathNotFoundError } ln := len(data) - if ln > 0 && (data[i] == '{' || data[i] == '[') { + // Note: nextToken returning non-negative (checked above) guarantees ln > 0, + // so the former ln > 0 guard was tautological and has been removed. + if data[i] == '{' || data[i] == '[' { i += 1 } var stackbuf [unescapeStackBufSize]byte // stack-allocated array for allocation-free unescaping of small strings @@ -117,6 +122,7 @@ func findKeyStart(data []byte, key string) (int, error) { return -1, KeyPathNotFoundError } +// SYS-REQ-001 func tokenStart(data []byte) int { for i := len(data) - 1; i >= 0; i-- { switch data[i] { @@ -128,6 +134,7 @@ func tokenStart(data []byte) int { return 0 } +// SYS-REQ-001 // Find position of next character which is not whitespace func nextToken(data []byte) int { for i, c := range data { @@ -142,6 +149,7 @@ func nextToken(data []byte) int { return -1 } +// SYS-REQ-001 // Find position of last character which is not whitespace func lastToken(data []byte) int { for i := len(data) - 1; i >= 0; i-- { @@ -156,6 +164,7 @@ func lastToken(data []byte) int { return -1 } +// SYS-REQ-045 // Tries to find the end of string // Support if string contains escaped quote symbols. func stringEnd(data []byte) (int, bool) { @@ -186,6 +195,7 @@ func stringEnd(data []byte) (int, bool) { return -1, escaped } +// SYS-REQ-046 // Find end of the data structure, array or object. // For array openSym and closeSym will be '[' and ']', for object '{' and '}' func blockEnd(data []byte, openSym byte, closeSym byte) int { @@ -217,6 +227,7 @@ func blockEnd(data []byte, openSym byte, closeSym byte) int { return -1 } +// SYS-REQ-001, SYS-REQ-020, SYS-REQ-021, SYS-REQ-022, SYS-REQ-023, SYS-REQ-047 func searchKeys(data []byte, keys ...string) int { keyLevel := 0 level := 0 @@ -313,7 +324,10 @@ func searchKeys(data []byte, keys ...string) int { // If we want to get array element by index if keyLevel == level && keys[level][0] == '[' { keyLen := len(keys[level]) - if keyLen < 3 || keys[level][0] != '[' || keys[level][keyLen-1] != ']' { + // Note: keys[level][0] == '[' is guaranteed by the outer if-guard, + // so the former middle term `keys[level][0] != '['` was always false + // (dead code) and has been removed. + if keyLen < 3 || keys[level][keyLen-1] != ']' { return -1 } aIdx, err := strconv.Atoi(keys[level][1 : keyLen-1]) @@ -363,6 +377,7 @@ func searchKeys(data []byte, keys ...string) int { return -1 } +// SYS-REQ-008 func sameTree(p1, p2 []string) bool { minLen := len(p1) if len(p2) < minLen { @@ -380,6 +395,7 @@ func sameTree(p1, p2 []string) bool { const stackArraySize = 128 +// SYS-REQ-008, SYS-REQ-085 func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]string) int { var x struct{} var level, pathsMatched, i int @@ -476,18 +492,17 @@ func EachKey(data []byte, cb func(int, []byte, ValueType, error), paths ...[]str if match == -1 { tokenOffset := nextToken(data[i+1:]) i += tokenOffset - - if data[i] == '{' { - blockSkip := blockEnd(data[i:], '{', '}') - i += blockSkip + 1 - } + // Note: i is now at the character BEFORE the value (the colon + // when tokenOffset==0, or the last whitespace character otherwise). + // The former `if data[i] == '{'` block-skip was structurally dead + // code because i never reaches the opening brace — the outer loop's + // i++ advances to it on the next iteration. Likewise, the former + // `if i < ln` guard was tautological since i remains within bounds. } - if i < ln { - switch data[i] { - case '{', '}', '[', '"': - i-- - } + switch data[i] { + case '{', '}', '[', '"': + i-- } } else { i-- @@ -587,6 +602,7 @@ const ( Unknown ) +// SYS-REQ-001 func (vt ValueType) String() string { switch vt { case NotExist: @@ -614,6 +630,7 @@ var ( nullLiteral = []byte("null") ) +// SYS-REQ-009 func createInsertComponent(keys []string, setValue []byte, comma, object bool) []byte { isIndex := string(keys[0][0]) == "[" offset := 0 @@ -661,6 +678,7 @@ func createInsertComponent(keys []string, setValue []byte, comma, object bool) [ return buffer } +// SYS-REQ-009 func calcAllocateSpace(keys []string, setValue []byte, comma, object bool) int { isIndex := string(keys[0][0]) == "[" lk := 0 @@ -701,6 +719,7 @@ func calcAllocateSpace(keys []string, setValue []byte, comma, object bool) int { return lk } +// SYS-REQ-009 func WriteToBuffer(buffer []byte, str string) int { copy(buffer, str) return len(str) @@ -714,6 +733,7 @@ Returns: `data` - return modified data */ +// SYS-REQ-010, SYS-REQ-033, SYS-REQ-034, SYS-REQ-035, SYS-REQ-048, SYS-REQ-049, SYS-REQ-050, SYS-REQ-056 func Delete(data []byte, keys ...string) []byte { lk := len(keys) if lk == 0 { @@ -752,11 +772,16 @@ func Delete(data []byte, keys ...string) []byte { tokEnd := tokenEnd(data[endOffset:]) tokStart := findTokenStart(data[:keyOffset], ","[0]) - if data[endOffset+tokEnd] == ","[0] { + if endOffset+tokEnd >= len(data) { + // tokenEnd sentinel: no delimiter found, input is truncated + return data + } + + if data[endOffset+tokEnd] == ',' { endOffset += tokEnd + 1 - } else if data[endOffset+tokEnd] == " "[0] && len(data) > endOffset+tokEnd+1 && data[endOffset+tokEnd+1] == ","[0] { + } else if data[endOffset+tokEnd] == ' ' && len(data) > endOffset+tokEnd+1 && data[endOffset+tokEnd+1] == ',' { endOffset += tokEnd + 2 - } else if data[endOffset+tokEnd] == "}"[0] && data[tokStart] == ","[0] { + } else if data[endOffset+tokEnd] == '}' && data[tokStart] == ',' { keyOffset = tokStart } } else { @@ -769,19 +794,26 @@ func Delete(data []byte, keys ...string) []byte { tokEnd := tokenEnd(data[endOffset:]) tokStart := findTokenStart(data[:keyOffset], ","[0]) - if data[endOffset+tokEnd] == ","[0] { + if endOffset+tokEnd >= len(data) { + // tokenEnd sentinel: no delimiter found, input is truncated + return data + } + + if data[endOffset+tokEnd] == ',' { endOffset += tokEnd + 1 - } else if data[endOffset+tokEnd] == "]"[0] && data[tokStart] == ","[0] { + } else if data[endOffset+tokEnd] == ']' && data[tokStart] == ',' { keyOffset = tokStart } } - // We need to remove remaining trailing comma if we delete las element in the object + // We need to remove remaining trailing comma if we delete last element in the object. + // Extract nextToken once to avoid the redundant double call in the original code. prevTok := lastToken(data[:keyOffset]) remainedValue := data[endOffset:] + remainedTok := nextToken(remainedValue) var newOffset int - if nextToken(remainedValue) > -1 && remainedValue[nextToken(remainedValue)] == '}' && data[prevTok] == ',' { + if remainedTok > -1 && remainedValue[remainedTok] == '}' && data[prevTok] == ',' { newOffset = prevTok } else { newOffset = prevTok + 1 @@ -805,6 +837,7 @@ Returns: `err` - On any parsing error */ +// SYS-REQ-009, SYS-REQ-051, SYS-REQ-068, SYS-REQ-069, SYS-REQ-070 func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error) { // ensure keys are set if len(keys) == 0 { @@ -878,6 +911,7 @@ func Set(data []byte, setValue []byte, keys ...string) (value []byte, err error) return value, nil } +// SYS-REQ-001, SYS-REQ-027 func getType(data []byte, offset int) ([]byte, ValueType, int, error) { var dataType ValueType endOffset := offset @@ -912,12 +946,10 @@ func getType(data []byte, offset int) ([]byte, ValueType, int, error) { endOffset += offset } else { // Number, Boolean or None + // tokenEnd returns len(data) when no delimiter is found, never -1, + // so the old end == -1 guard was dead code and has been removed. end := tokenEnd(data[endOffset:]) - if end == -1 { - return nil, dataType, offset, MalformedValueError - } - value := data[offset : endOffset+end] switch data[offset] { @@ -956,11 +988,13 @@ Returns: Accept multiple keys to specify path to JSON value (in case of quering nested structures). If no keys provided it will try to extract closest JSON value (simple ones or object/array), useful for reading streams or arrays, see `ArrayEach` implementation. */ +// SYS-REQ-001, SYS-REQ-016, SYS-REQ-017, SYS-REQ-018, SYS-REQ-019, SYS-REQ-025, SYS-REQ-026, SYS-REQ-041, SYS-REQ-042, SYS-REQ-043 func Get(data []byte, keys ...string) (value []byte, dataType ValueType, offset int, err error) { a, b, _, d, e := internalGet(data, keys...) return a, b, d, e } +// SYS-REQ-001 func internalGet(data []byte, keys ...string) (value []byte, dataType ValueType, offset, endOffset int, err error) { if len(keys) > 0 { if offset = searchKeys(data, keys...); offset == -1 { @@ -988,6 +1022,7 @@ func internalGet(data []byte, keys ...string) (value []byte, dataType ValueType, return value[:len(value):len(value)], dataType, offset, endOffset, nil } +// SYS-REQ-006, SYS-REQ-028, SYS-REQ-029, SYS-REQ-052, SYS-REQ-053, SYS-REQ-055, SYS-REQ-083 // ArrayEach is used when iterating arrays, accepts a callback function with the same return arguments as `Get`. func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int, err error), keys ...string) (offset int, err error) { if len(data) == 0 { @@ -1032,23 +1067,23 @@ func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int return offset, nil } - for true { + for { v, t, o, e := Get(data[offset:]) - if e != nil { - return offset, e - } - if o == 0 { - break + // When Get returns endOffset==0, it always means a parse error + // (no valid value found at the current position). The former + // e==nil/break branch was structurally unreachable because Get + // never returns endOffset==0 without an error. + return offset, e } - if t != NotExist { - cb(v, t, offset+o-len(v), e) - } + // Pass the error to the callback — the callback signature declares + // an err parameter, so callers who check it should see real errors. + cb(v, t, offset+o-len(v), e) if e != nil { - break + return offset, e } offset += o @@ -1073,6 +1108,7 @@ func ArrayEach(data []byte, cb func(value []byte, dataType ValueType, offset int return offset, nil } +// SYS-REQ-007, SYS-REQ-030, SYS-REQ-031, SYS-REQ-032, SYS-REQ-054, SYS-REQ-084 // ObjectEach iterates over the key-value pairs of a JSON object, invoking a given callback for each such entry func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType ValueType, offset int) error, keys ...string) (err error) { offset := 0 @@ -1102,8 +1138,13 @@ func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType Va return nil } - // Loop pre-condition: data[offset] points to what should be either the next entry's key, or the closing brace (if it's anything else, the JSON is malformed) - for offset < len(data) { + // Loop pre-condition: data[offset] points to what should be either the next entry's key, + // or the closing brace (if it's anything else, the JSON is malformed). + // Every iteration either returns or advances offset past a token, so the loop + // always exits via return; the former `offset < len(data)` guard was structurally + // always true because internal nextToken/stringEnd calls return errors before + // offset can reach len(data). + for { // Step 1: find the next key var key []byte @@ -1180,6 +1221,7 @@ func ObjectEach(data []byte, callback func(key []byte, value []byte, dataType Va return MalformedObjectError // we shouldn't get here; it's expected that we will return via finding the ending brace } +// SYS-REQ-011, SYS-REQ-080, SYS-REQ-081, SYS-REQ-082 // GetUnsafeString returns the value retrieved by `Get`, use creates string without memory allocation by mapping string to slice memory. It does not handle escape symbols. func GetUnsafeString(data []byte, keys ...string) (val string, err error) { v, _, _, e := Get(data, keys...) @@ -1191,6 +1233,7 @@ func GetUnsafeString(data []byte, keys ...string) (val string, err error) { return bytesToString(&v), nil } +// SYS-REQ-002, SYS-REQ-071, SYS-REQ-072, SYS-REQ-073, SYS-REQ-074 // GetString returns the value retrieved by `Get`, cast to a string if possible, trying to properly handle escape and utf8 symbols // If key data type do not match, it will return an error. func GetString(data []byte, keys ...string) (val string, err error) { @@ -1218,6 +1261,7 @@ func GetString(data []byte, keys ...string) (val string, err error) { // GetFloat returns the value retrieved by `Get`, cast to a float64 if possible. // The offset is the same as in `Get`. // If key data type do not match, it will return an error. +// SYS-REQ-004 func GetFloat(data []byte, keys ...string) (val float64, err error) { v, t, _, e := Get(data, keys...) @@ -1237,6 +1281,7 @@ func GetFloat(data []byte, keys ...string) (val float64, err error) { // GetInt returns the value retrieved by `Get`, cast to a int64 if possible. // If key data type do not match, it will return an error. +// SYS-REQ-003, SYS-REQ-075, SYS-REQ-076, SYS-REQ-077, SYS-REQ-078 func GetInt(data []byte, keys ...string) (val int64, err error) { v, t, _, e := Get(data, keys...) @@ -1257,6 +1302,7 @@ func GetInt(data []byte, keys ...string) (val int64, err error) { // GetBoolean returns the value retrieved by `Get`, cast to a bool if possible. // The offset is the same as in `Get`. // If key data type do not match, it will return error. +// SYS-REQ-005, SYS-REQ-079 func GetBoolean(data []byte, keys ...string) (val bool, err error) { v, t, _, e := Get(data, keys...) @@ -1275,6 +1321,7 @@ func GetBoolean(data []byte, keys ...string) (val bool, err error) { } // ParseBoolean parses a Boolean ValueType into a Go bool (not particularly useful, but here for completeness) +// SYS-REQ-012, SYS-REQ-036, SYS-REQ-057, SYS-REQ-066 func ParseBoolean(b []byte) (bool, error) { switch { case bytes.Equal(b, trueLiteral): @@ -1287,6 +1334,7 @@ func ParseBoolean(b []byte) (bool, error) { } // ParseString parses a String ValueType into a Go string (the main parsing work is unescaping the JSON string) +// SYS-REQ-014, SYS-REQ-038, SYS-REQ-060, SYS-REQ-063, SYS-REQ-067 func ParseString(b []byte) (string, error) { var stackbuf [unescapeStackBufSize]byte // stack-allocated array for allocation-free unescaping of small strings if bU, err := Unescape(b, stackbuf[:]); err != nil { @@ -1297,6 +1345,7 @@ func ParseString(b []byte) (string, error) { } // ParseNumber parses a Number ValueType into a Go float64 +// SYS-REQ-013, SYS-REQ-037, SYS-REQ-065 func ParseFloat(b []byte) (float64, error) { if v, err := parseFloat(&b); err != nil { return 0, MalformedValueError @@ -1306,6 +1355,7 @@ func ParseFloat(b []byte) (float64, error) { } // ParseInt parses a Number ValueType into a Go int64 +// SYS-REQ-015, SYS-REQ-039, SYS-REQ-040, SYS-REQ-058, SYS-REQ-059, SYS-REQ-064 func ParseInt(b []byte) (int64, error) { if v, ok, overflow := parseInt(b); !ok { if overflow { diff --git a/vendor/github.com/buger/jsonparser/proof.yaml b/vendor/github.com/buger/jsonparser/proof.yaml new file mode 100644 index 000000000..4d82bc210 --- /dev/null +++ b/vendor/github.com/buger/jsonparser/proof.yaml @@ -0,0 +1,96 @@ +project: + name: jsonparser + specs: + - path: specs/stakeholder + prefix: STK-REQ + type: stakeholder + - path: specs/system + prefix: SYS-REQ + type: system + parent_spec: specs/stakeholder + obligation_classes: + - nominal + - missing_path + - malformed_input + - truncated_at_value_boundary + - truncated_mid_structure + - truncated_mid_key + - empty_input + - boundary + - type_mismatch + - negative_array_index + - sentinel_value_boundary + - error_propagation + - no_path_provided + - nested_mutation + - callback_error_propagation + - truncated_escape_sequence + - partial_literal + - truncated_mid_element + - determinism + - idempotency + - nil_safety + - encoding_safety + - edge_case + commands: + build: go build ./... + test: mkdir -p .proof/coverage .proof/test-results && go test ./... -count=1 -coverprofile=.proof/coverage/unit.coverprofile -json > .proof/test-results/go-test.json 2>&1 + # Fixtures are generated artifacts, not committed to the repo. + # MC/DC coverage is enforced through test annotations instead. + # To regenerate locally: + # proof testgen specs/system parser --output tests/ + # proof proptest specs/system parser --source z3 --output tests/parser/ + checks: + solver_latency_clean: + threshold: 360 + coverage_threshold: + threshold: 80 + auto_link: false + report_path: .proof/coverage/unit.coverprofile + format: go-cover + test_results: + auto_link: true + report_path: .proof/test-results/go-test.json + slow_tests: + enabled: true + code_mcdc: + severity: warn + engine: go + package_pattern: ./... + coverpkg: ./... + go_test_args: + - -race + min_decision_percent: 100 + min_condition_percent: 100 + max_incomplete_decisions: 0 + targets: + - id: parser + enabled: true + language: go + scope: ./... + test_mcdc_annotations: + enabled: true + mcdc_coverage: {} + proof_complexity_clean: + max_formalized_requirements: 120 + max_variables: 280 + max_guarantees: 120 + evidence_diversity: + min_classes: + A: 3 + B: 2 + C: 1 + approval: + required_for: + assurance_levels: + - A + - B + roles: + - system_owner + - lead_engineer + comment_required: true + documentation: + sources: + - path: . + type: auto + threshold: 0 diff --git a/vendor/github.com/mattn/go-shellwords/shellwords.go b/vendor/github.com/mattn/go-shellwords/shellwords.go index 1b42a0017..3747e3549 100644 --- a/vendor/github.com/mattn/go-shellwords/shellwords.go +++ b/vendor/github.com/mattn/go-shellwords/shellwords.go @@ -136,6 +136,12 @@ loop: for _, r := range line { i++ if escaped { + if r == 't' { + r = '\t' + } + if r == 'n' { + r = '\n' + } buf += string(r) escaped = false got = argSingle @@ -194,23 +200,49 @@ loop: backtick = "" backQuote = !backQuote } + case ')': if !singleQuoted && !doubleQuoted && !backQuote { if p.ParseBacktick { - if dollarQuote { - out, err := shellRun(backtick, p.Dir) - if err != nil { - return nil, err - } - buf = buf[:len(buf)-len(backtick)-2] + out + // Security fix: + // A bare ')' must never open dollarQuote state. + // Preserve prior behavior by rejecting unmatched ')' + // when command substitution parsing is enabled. + if !dollarQuote { + return nil, errors.New("invalid command line string") + } + + out, err := shellRun(backtick, p.Dir) + if err != nil { + return nil, err + } + + // Defensive guard: valid $(...) implies the buffer must contain + // the "$(" prefix plus the collected command body. + if len(buf) < len(backtick)+2 { + return nil, errors.New("invalid command line string") } + + buf = buf[:len(buf)-len(backtick)-2] + out backtick = "" - dollarQuote = !dollarQuote + dollarQuote = false continue } + + // Backtick parsing disabled: + // A bare ')' is a syntax error, consistent with '(' handling. + // Only close an already-open $(...) region. + if !dollarQuote { + return nil, errors.New("invalid command line string") + } + + buf += string(r) backtick = "" - dollarQuote = !dollarQuote + dollarQuote = false + got = argSingle + continue } + case '(': if !singleQuoted && !doubleQuoted && !backQuote { if !dollarQuote && strings.HasSuffix(buf, "$") { @@ -221,6 +253,7 @@ loop: return nil, errors.New("invalid command line string") } } + case '"': if !singleQuoted && !dollarQuote { if doubleQuoted { @@ -229,6 +262,7 @@ loop: doubleQuoted = !doubleQuoted continue } + case '\'': if !doubleQuoted && !dollarQuote { if singleQuoted { @@ -237,6 +271,7 @@ loop: singleQuoted = !singleQuoted continue } + case ';', '&', '|', '<', '>': if !(escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote) { if r == '>' && len(buf) > 0 { diff --git a/vendor/github.com/mattn/go-shellwords/util_posix.go b/vendor/github.com/mattn/go-shellwords/util_posix.go index b56a90120..4d6b924bb 100644 --- a/vendor/github.com/mattn/go-shellwords/util_posix.go +++ b/vendor/github.com/mattn/go-shellwords/util_posix.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package shellwords diff --git a/vendor/github.com/mattn/go-shellwords/util_windows.go b/vendor/github.com/mattn/go-shellwords/util_windows.go index fd738a721..0a650f56b 100644 --- a/vendor/github.com/mattn/go-shellwords/util_windows.go +++ b/vendor/github.com/mattn/go-shellwords/util_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package shellwords diff --git a/vendor/github.com/onsi/ginkgo/v2/.gitignore b/vendor/github.com/onsi/ginkgo/v2/.gitignore index 6faaaf315..c9f054620 100644 --- a/vendor/github.com/onsi/ginkgo/v2/.gitignore +++ b/vendor/github.com/onsi/ginkgo/v2/.gitignore @@ -1,6 +1,7 @@ .DS_Store TODO tmp/**/* +integration/tmp_*/ *.coverprofile .vscode .idea/ diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md index 70050f35d..224e8db5f 100644 --- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md +++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md @@ -1,3 +1,23 @@ +## 2.29.0 + +`GinkgoHelperGo` makes it easier to write test helpers that need to run in goroutines. Specifically, it makes managing the failure state and capturing failure panics correctly straightforward. + +`ginkgo outline` now includes entries defined in `DescribeTableSubtree` + +## 2.28.3 + +### Maintenance +Bump all dependencies + +## 2.28.2 + +- Add ArtifactDir() to support Go 1.26 testing.TB interface [f3a36b6] +- Implement shell completion [94151c8] +- Add asan CLI option mirroring msan implementation [4d21dbb] +- Bump uri from 1.0.3 to 1.0.4 in /docs (#1630) [c102161] +- fix aspect ratio [9619647] +- update logos [5779304] + ## 2.28.1 Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months. diff --git a/vendor/github.com/onsi/ginkgo/v2/README.md b/vendor/github.com/onsi/ginkgo/v2/README.md index b4c3ce0ad..6d36e377e 100644 --- a/vendor/github.com/onsi/ginkgo/v2/README.md +++ b/vendor/github.com/onsi/ginkgo/v2/README.md @@ -120,6 +120,6 @@ Sponsors commit to a [sponsorship](https://github.com/sponsors/onsi) for a year.

Browser testing via - +

diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go index c3f6d3a11..53114904c 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/command/program.go @@ -1,9 +1,13 @@ package command import ( + "bufio" "fmt" "io" + "maps" "os" + "path/filepath" + "slices" "strings" "github.com/onsi/ginkgo/v2/formatter" @@ -158,6 +162,166 @@ func (p Program) handleHelpRequestsAndExit(writer io.Writer, args []string) { } } +type completionOptions = struct { + Complete bool + Install bool +} + +func (p *Program) BuildCompletionCommand() Command { + opts := completionOptions{} + flags, err := types.NewGinkgoFlagSet( + types.GinkgoFlags{ + {Name: "complete", KeyPath: "Complete", Usage: "Generate completion for arguments after --"}, + {Name: "install", KeyPath: "Install", Usage: "Install shell completion script into $XDG_DATA_HOME, ~/.local/share"}, + }, + &opts, + types.GinkgoFlagSections{}, + ) + if err != nil { + panic(err) + } + return Command{ + Name: "completion", + Usage: "ginkgo completion [-- ]", + Flags: flags, + ShortDoc: "Generate shell completion", + Documentation: `To use install completion script for your shell (bash, fish, zsh). +Or load completion code by: {{bold}}source <(ginkgo completion ){{/}}.`, + Command: func(args []string, completeArgs []string) { + p.handleCompletionAndExit(args, completeArgs, opts) + }, + } +} + +func (p Program) generateShellCompletionScript(shell string) (scriptPath string, script string) { + switch shell { + case "bash": + scriptPath = fmt.Sprintf("bash-completion/completions/%s", p.Name) + script = fmt.Sprintf(`__%s_complete_bash() { + mapfile -t COMPREPLY < <("${COMP_WORDS[0]}" completion --complete bash -- "${COMP_WORDS[@]:1:COMP_CWORD}") +} +complete -o bashdefault -o default -F __%[1]s_complete_bash %[1]s +`, p.Name) + + case "fish": + scriptPath = fmt.Sprintf("fish/vendor_completions.d/%s.fish", p.Name) + script = fmt.Sprintf(`function __fish_%[1]s_complete + set -l args (commandline -opc) (commandline -ct) + set -e args[1] + %[1]s completion --complete fish -- $args +end +complete -c %[1]s -a "(__fish_%[1]s_complete)" +`, p.Name) + + case "zsh": + scriptPath = fmt.Sprintf("zsh/site-functions/_%s", p.Name) + script = fmt.Sprintf(`#compdef %[1]s +_%[1]s() { + local -a completions + completions=(${(f)"$("${words[1]}" completion --complete zsh -- "${words[@]:1:$((CURRENT-1))}")"}) + if (( ${#completions[@]} )); then + _describe 'completions' completions + else + _default + fi +} +compdef _%[1]s %[1]s +if [ "$funcstack[1]" = "_%[1]s" ]; then + _%[1]s +fi +`, p.Name) + + case "": + AbortWithUsage("Shell is not specified") + default: + AbortWith("Shell %q is not supported yet. Choose: bash, fish, zsh", shell) + } + + return scriptPath, script +} + +func (p Program) handleCompletionAndExit(args, completeArgs []string, opts completionOptions) { + writer := p.OutWriter + if writer == nil { + writer = os.Stdout + } + buffer := bufio.NewWriter(writer) + defer buffer.Flush() + + var shell string + if len(args) > 0 { + shell = args[0] + } + + if !opts.Complete { + scriptPath, script := p.generateShellCompletionScript(shell) + if opts.Install { + dataHomeDir := os.Getenv("XDG_DATA_HOME") + if dataHomeDir == "" { + userHomeDir, err := os.UserHomeDir() + AbortIfError("Failed to find home", err) + dataHomeDir = filepath.Join(userHomeDir, ".local/share") + } + scriptPath = filepath.Join(dataHomeDir, scriptPath) + fmt.Fprintf(buffer, "Installing completion script: %v\n", scriptPath) + err := os.WriteFile(scriptPath, []byte(script), 0644) + AbortIfError("Failed to install completion script", err) + } else { + buffer.Write([]byte(script)) + } + Abort(AbortDetails{}) + } + + var lastArg string + var result map[string]string + if len(completeArgs) > 0 { + lastArg = completeArgs[len(completeArgs)-1] + } + + if delim := slices.Index(completeArgs, "--"); delim >= 0 && delim != len(completeArgs)-1 { + // No completion for pass-through arguments after "--" + } else if len(lastArg) > 0 && lastArg[0] == '-' { + // Complete flags + cmd := &p.DefaultCommand + for i := range p.Commands { + if p.Commands[i].Name == completeArgs[0] { + cmd = &p.Commands[i] + break + } + } + result = cmd.Flags.Completion(lastArg) + } else if len(completeArgs) <= 1 { + // Complete commands + result = make(map[string]string, len(p.Commands)+1) + for _, cmd := range append(p.Commands, p.DefaultCommand) { + if strings.HasPrefix(cmd.Name, lastArg) { + result[cmd.Name] = cmd.Usage + } + } + } + + width := 0 + for suggest := range result { + width = max(width, len(suggest)) + } + + for _, suggest := range slices.Sorted(maps.Keys(result)) { + usage := result[suggest] + switch { + case shell == "bash" && usage != "" && len(result) > 1: + fmt.Fprintf(buffer, "%*s (%s)\n", -width-2, suggest, usage) + case shell == "fish": + fmt.Fprintf(buffer, "%s\t%s\n", suggest, usage) + case shell == "zsh": + fmt.Fprintf(buffer, "%s:%s\n", suggest, usage) + default: + fmt.Fprintln(buffer, suggest) + } + } + + Abort(AbortDetails{}) +} + func (p Program) EmitUsage(writer io.Writer) { fmt.Fprintln(writer, formatter.F(p.Heading)) fmt.Fprintln(writer, formatter.F("{{gray}}%s{{/}}", strings.Repeat("-", len(p.Heading)))) diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go index 419589b48..596c210cf 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/main.go @@ -41,6 +41,7 @@ func main() { {Name: "nodot", Deprecation: types.Deprecations.Nodot()}, }, } + program.Commands = append(program.Commands, program.BuildCompletionCommand()) program.RunAndExit(os.Args) } diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go index 5d8d00bb1..c380bbf21 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/ginkgo.go @@ -163,17 +163,17 @@ func ginkgoNodeFromCallExpr(fset *token.FileSet, ce *ast.CallExpr, ginkgoPackage n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "Context", "Describe", "When", "DescribeTable": + case "Context", "Describe", "When", "DescribeTable", "DescribeTableSubtree": n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) n.Pending = pendingFromCallExpr(ce) return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "FContext", "FDescribe", "FWhen", "FDescribeTable": + case "FContext", "FDescribe", "FWhen", "FDescribeTable", "FDescribeTableSubtree": n.Focused = true n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) return &n, ginkgoPackageName != nil && *ginkgoPackageName == packageName - case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable": + case "PContext", "PDescribe", "PWhen", "XContext", "XDescribe", "XWhen", "PDescribeTable", "XDescribeTable", "PDescribeTableSubtree", "XDescribeTableSubtree": n.Pending = true n.Text = textOrAltFromCallExpr(ce, undefinedTextAlt) n.Labels = labelFromCallExpr(ce) diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go index e99d557d1..206043f1d 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/outline/outline.go @@ -54,6 +54,7 @@ func FromASTFile(fset *token.FileSet, src *ast.File) (*outline, error) { // Node is not a Ginkgo spec or container, so it was not pushed onto the stack, continue return true } + expandSubtree(lastVisitedGinkgoNode) stack = stack[0 : len(stack)-1] return true }) @@ -128,3 +129,29 @@ func (o *outline) StringIndent(width int) string { return b.String() } + +// expandSubtree restructures a DescribeTableSubtree node so that each Entry +// child gets a copy of the subtree's spec nodes as its children. This mirrors +// the runtime behavior where each Entry generates a container with the specs +// defined in the DescribeTableSubtree body. +func expandSubtree(gn *ginkgoNode) { + if !strings.Contains(gn.Name, "DescribeTableSubtree") { + return + } + subNodes, entries := splitSubtreeSubnodes(gn.Nodes) + gn.Nodes = entries + for _, entry := range entries { + entry.Nodes = subNodes + } +} + +// splitSubtreeSubnodes splits the child nodes of a DescribeTableSubtree into +// spec/container nodes (defined in the body) and Entry nodes. +func splitSubtreeSubnodes(nodes []*ginkgoNode) ([]*ginkgoNode, []*ginkgoNode) { + for i, node := range nodes { + if strings.Contains(node.Name, "Entry") { + return nodes[:i], nodes[i:] + } + } + return nodes, nil +} diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go index 40d1e1ab5..db3e24847 100644 --- a/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go +++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo_t_dsl.go @@ -72,6 +72,7 @@ type GinkgoTInterface interface { TempDir() string Attr(key, value string) Output() io.Writer + ArtifactDir() string } /* @@ -196,3 +197,6 @@ func (g *GinkgoTBWrapper) Attr(key, value string) { func (g *GinkgoTBWrapper) Output() io.Writer { return g.GinkgoT.Output() } +func (g *GinkgoTBWrapper) ArtifactDir() string { + return g.GinkgoT.ArtifactDir() +} diff --git a/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go new file mode 100644 index 000000000..9d04cc845 --- /dev/null +++ b/vendor/github.com/onsi/ginkgo/v2/helpergo_dsl.go @@ -0,0 +1,143 @@ +package ginkgo + +import ( + "github.com/onsi/ginkgo/v2/internal/global" + ginkgotypes "github.com/onsi/ginkgo/v2/types" +) + +// GinkgoHelperGo synchronously calls the specified “helper” function in a new +// go routine and with a “defer GinkgoRecover()” already in place, passing the +// function a “helper Fail”. GinkgoHelperGo is typically called from custom test +// helpers that in turn need to synchronously execute caller-supplied custom +// test code in a new Go routine while waiting for this new Go routine to +// terminate (either successfully or failing). +// +// GinkgoHelperGo hides the non-trivial details of correctly unblocking the +// caller's waiting go routine as well as reporting the correct call sites, +// depending on whether the test helper failed, or the caller-supplied function +// had its assertions failing or panicked. +// +// Let's take the following example of a test helper named “EnsureSprockets” +// that runs a set of caller-supplied assertions synchronously on a new Go +// routine and waits for the outcome before returning to the caller of the test +// helper. This is just using Ginkgo: +// +// func EnsureSprockets(sprockets int, assertions func()) { +// GinkgoHelper() +// GinkgoHelperGo(func(helperFail func(string, ...int)) { +// if sprockets == 0 { +// helperFail("sprockets must not be zero") +// } +// assertions() +// }) +// } +// +// And now for an example that additionally uses Gomega assertions. +// +// func EnsureSprockets(sprockets int, assertions func()) { +// GinkgoHelper() +// GinkgoHelperGo(func(helperFail func(string, ...int)) { +// g := gomega.NewGomega(helperFail) +// g.Expect(sprockets).Not(BeZero()) +// assertions() +// }) +// } +// +// The called helper function should make any custom helper-related assertions +// using the passed “helper Fail”. Gomega users will want to create a new Gomega +// wired into this helper Fail. It is expected for the helper function at some +// point to call into a user-supplied function that might contain its own +// assertions. In the example above, that would be the function passed as +// assertions. +// +// Any failing assertion using the helper Gomega in the helper function will be +// reported as a fail at the call site of GinkgoHelperGo. Preferably, only +// custom test helpers call GinkgoHelperGo and thus mark themselves as +// [GinkgoHelper] also: in this case, the fail will be shown at the call site of +// the custom test helper. +// +// Any other failing assertions inside the caller-supplied custom test code and +// thus inside the helper function will instead be reported at the location of +// the failed assertion. +// +// If the caller-supplied custom test code panics, GinkgoHelperGo will fail at +// its call site, or at the call site of the custom test helper if it uses +// GinkgoHelper, reporting the usual stack trace for the panic, as a plain +// GinkgoRecover would also do. +// +// Important: the Gomega passed to the called function must only be used in +// assertions belonging to the test helper, but not any user test code called +// from the test helper. Thus, do not pass the Gomega passed to the helper +// function further on to any user test code functions. +func GinkgoHelperGo(fn func(fail func(message string, callerSkip ...int))) { + // userPanicked signals that the called user code panicked, such as due to a + // failed Gomega assertion. + type userPanicked struct{} + + // helperPanicked signals that some helper code assertion panicked in the + // separate Go routine and we are expected to Fail the current test with that + // reason, but on the caller's Go routine. + type helperPanicked string + + GinkgoHelper() + + // possible types of values sent over the result channel: + // - nil (untyped): no problem at all, proceed. + // - helperPanicked: the message with which to (re)fail in the caller's + // go routine. + // - userPanicked: indication to (also) fail on the caller's go routine; + // the message doesn't matter as the user code fail takes precedence. + ch := make(chan any) + + go func() { + isHelperPanic := false + helperFail := func(message string, callerSkip ...int) { + isHelperPanic = true + Fail(message, callerSkip...) + } + // Please note that we cannot simply recover a helper panic before + // GinkgoRecover kicks in as then GinkgoRecover would always report the + // stack trace only from the place of rethrown panic ... and that's + // pretty useless, because it would just consist of the panic rethrow. + defer func() { + // We need to unblock and immediately fail the waiting caller's + // go routine either for a reason, or just "because" when + // GinkgoRecover has already failed the current test on the + // separate go routine. + if global.Failer.GetState() != ginkgotypes.SpecStatePassed { + if isHelperPanic { + _, failure := global.Failer.Drain() + ch <- helperPanicked(failure.Message) + } else { + // keep the panic failure already recorded by GinkgoRecover. + ch <- userPanicked{} + } + } + close(ch) // causes a nil in case there were no panics anywhere. + }() + // Nota bene: GinkgoRecover always eats any user panic and channel the + // panic value into Ginkgo's Failer.Panic(). We can peek at the last + // failure recorded, which should be nil if GinkgoRecover didn't swallow + // a user code panic. The "problem" with GinkgoRecover is that it turns + // any panic value into a string message, so we loose any specific + // typing. + defer GinkgoRecover() + + fn(helperFail) + }() + + // Did we run into trouble? + switch v := (<-ch).(type) { + case userPanicked: + // The message actually is irrelevant, as it comes only second to + // the already registered user panic message. We just need Fail to + // panic on the caller's go routine in order to unblock the test. + Fail("fn panicked", 1) + case helperPanicked: + // Report the failure on the new go routine instead on the caller's go + // routine. + Fail(string(v), 1) + default: + // It's all fine! + } +} diff --git a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go index 5704f0fdf..e6fbaee41 100644 --- a/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go +++ b/vendor/github.com/onsi/ginkgo/v2/internal/testingtproxy/testing_t_proxy.go @@ -181,6 +181,15 @@ func (t *ginkgoTestingTProxy) TempDir() string { return tmpDir } +func (t *ginkgoTestingTProxy) ArtifactDir() string { + artifactDir, err := os.MkdirTemp("", "ginkgo") + if err != nil { + t.fail(fmt.Sprintf("Failed to create artifact directory: %v", err), 1) + return "" + } + return artifactDir +} + // FullGinkgoTInterface func (t *ginkgoTestingTProxy) AddReportEntryVisibilityAlways(name string, args ...any) { finalArgs := []any{internal.Offset(1), types.ReportEntryVisibilityAlways} diff --git a/vendor/github.com/onsi/ginkgo/v2/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go index f84703604..ca64acb27 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/config.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/config.go @@ -215,6 +215,7 @@ type GoFlagsConfig struct { N bool ModFile string ModCacheRW bool + ASan bool MSan bool PkgDir string Tags string @@ -570,6 +571,8 @@ var GoBuildFlags = GinkgoFlags{ Usage: "leave newly-created directories in the module cache read-write instead of making them read-only."}, {KeyPath: "Go.ModFile", Name: "modfile", UsageArgument: "file", SectionKey: "go-build", Usage: `in module aware mode, read (and possibly write) an alternate go.mod file instead of the one in the module root directory. A file named go.mod must still be present in order to determine the module root directory, but it is not accessed. When -modfile is specified, an alternate go.sum file is also used: its path is derived from the -modfile flag by trimming the ".mod" extension and appending ".sum".`}, + {KeyPath: "Go.ASan", Name: "asan", SectionKey: "go-build", + Usage: "enable interoperation with address sanitizer."}, {KeyPath: "Go.MSan", Name: "msan", SectionKey: "go-build", Usage: "enable interoperation with memory sanitizer. Supported only on linux/amd64, linux/arm64 and only with Clang/LLVM as the host C compiler. On linux/arm64, pie build mode will be used."}, {KeyPath: "Go.N", Name: "n", SectionKey: "go-build", diff --git a/vendor/github.com/onsi/ginkgo/v2/types/flags.go b/vendor/github.com/onsi/ginkgo/v2/types/flags.go index 8409653f9..eb04c3e78 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/flags.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/flags.go @@ -212,6 +212,24 @@ func (f GinkgoFlagSet) IsZero() bool { return f.flagSet == nil } +func (f GinkgoFlagSet) Completion(arg string) map[string]string { + if f.IsZero() { + return nil + } + prefix := strings.TrimLeft(arg, "-") + dash := arg[:len(arg)-len(prefix)] + if len(dash) < 1 || len(dash) > 3 { + return nil + } + result := make(map[string]string, len(f.flags)) + for _, flag := range f.flags { + if flag.Name != "" && strings.HasPrefix(flag.Name, prefix) { + result[dash+flag.Name] = flag.Usage + } + } + return result +} + func (f GinkgoFlagSet) WasSet(name string) bool { found := false f.flagSet.Visit(func(f *flag.Flag) { diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go index 1df09be00..003604bd8 100644 --- a/vendor/github.com/onsi/ginkgo/v2/types/version.go +++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go @@ -1,3 +1,3 @@ package types -const VERSION = "2.28.1" +const VERSION = "2.29.0" diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md index 91e65521b..9c94d0e6c 100644 --- a/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.40.0 + +We're adopting a new release strategy to minimize dependency bloat in projects that consume Gomega. It is a limitation of the go mod toolchain that _test_ subdependencies of your project's direct dependencies get pulled in as *indirect* dependencies. In the case of Gomega, this ends up pulling in all of Ginkgo into your `go.mod` even if you are only using Gomega (Gomega uses Ginkgo for its own tests). + +Going forward, releases will strip out all tests, tidy up the `go.mod` and then push this stripped down version to a new `master-lite` branch. These stripped-down versions will receive the `vx.y.z` git tag and will be picked up by the go toolchain. + +Please open an issue if this new release process causes unexpected changes for your projects. + ## 1.39.1 Update all dependencies. This auto-updated the required version of Go to 1.24, consistent with the fact that Go 1.23 has been out of support for almost six months. diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go index 87c70692b..af1341bdb 100644 --- a/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.39.1" +const GOMEGA_VERSION = "1.40.0" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index 15150d475..06b4acacb 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -26,11 +26,6 @@ var ( // ErrInvalidLabel is returned when an invalid label is specified. ErrInvalidLabel = errors.New("invalid Label") - // InvalidLabel is returned when an invalid label is specified. - // - // Deprecated: use [ErrInvalidLabel]. - InvalidLabel = ErrInvalidLabel - // ErrIncomparable is returned two levels are not comparable ErrIncomparable = errors.New("incomparable levels") // ErrLevelSyntax is returned when a sensitivity or category do not have correct syntax in a level @@ -45,12 +40,29 @@ var ( // is not the thread group leader. ErrNotTGLeader = errors.New("calling thread is not the thread group leader") - // CategoryRange allows the upper bound on the category range to be adjusted + // CategoryRange allows the upper bound on the category range to be adjusted. + // + // Deprecated: use [SetCategoryRange] instead. CategoryRange = DefaultCategoryRange privContainerMountLabel string ) +// ProcessKind selects which process domain [SetProcessKind] applies to a label. +type ProcessKind int + +const ( + ProcessKindRegular ProcessKind = 1 + ProcessKindInit ProcessKind = 2 + ProcessKindKVM ProcessKind = 3 +) + +// SetProcessKind returns label with its type component replaced by the one +// corresponding to kind. Other label components are kept intact. +func SetProcessKind(label string, kind ProcessKind) (string, error) { + return setProcessKind(label, kind) +} + // Context is a representation of the SELinux label broken into 4 parts type Context map[string]string @@ -64,6 +76,16 @@ func GetEnabled() bool { return getEnabled() } +// SetCategoryRange allows to adjust the upper bound of the category range. +// It affects subsequent calls to [KVMContainerLabel] and [InitContainerLabel]. +func SetCategoryRange(upper uint32) error { + if upper > DefaultCategoryRange { + return errors.New("can't have more than DefaultCategoryRange categories") + } + CategoryRange = upper + return nil +} + // ClassIndex returns the int index for an object class in the loaded policy, // or -1 and an error func ClassIndex(class string) (int, error) { @@ -107,12 +129,12 @@ func SetFSCreateLabel(label string) error { // FSCreateLabel returns the default label the kernel which the kernel is using // for file system objects created by this task. "" indicates default. func FSCreateLabel() (string, error) { - return fsCreateLabel() + return readConThreadSelf("attr/fscreate") } // CurrentLabel returns the SELinux label of the current process thread, or an error. func CurrentLabel() (string, error) { - return currentLabel() + return readConThreadSelf("attr/current") } // PidLabel returns the SELinux label of the given pid, or an error. @@ -123,7 +145,7 @@ func PidLabel(pid int) (string, error) { // ExecLabel returns the SELinux label that the kernel will use for any programs // that are executed by the current process thread, or an error. func ExecLabel() (string, error) { - return execLabel() + return readConThreadSelf("attr/exec") } // CanonicalizeContext takes a context string and writes it to the kernel @@ -180,7 +202,7 @@ func SocketLabel() (string, error) { // PeerLabel retrieves the label of the client on the other side of a socket func PeerLabel(fd uintptr) (string, error) { - return peerLabel(fd) + return peerLabel(int(fd)) //#nosec G115 -- ignore "integer overflow conversion uintptr -> int". } // SetKeyLabel takes a process label and tells the kernel to assign the @@ -216,9 +238,26 @@ func ClearLabels() { clearLabels() } -// ReserveLabel reserves the MLS/MCS level component of the specified label +// ReserveLabel reserves the MLS/MCS level component of the specified label. +// +// Deprecated: use [ReserveLabelV2] instead. func ReserveLabel(label string) { - reserveLabel(label) + _ = reserveLabel(label) +} + +// ReserveLabelV2 reserves the MLS/MCS level component of the specified label. +// Returns an error if the label can't be reserved. +// +// Callers that are intentionally reusing an existing level/MCS (e.g. multiple +// container in a pod sharing a label) may safely ignore [ErrMCSAlreadyExists] +// error. +func ReserveLabelV2(label string) error { + return reserveLabel(label) +} + +// CheckLabel check the MLS/MCS level component of the specified label +func CheckLabel(label string) error { + return checkLabel(label) } // MLSEnabled checks if MLS is enabled. @@ -250,25 +289,51 @@ func ReleaseLabel(label string) { releaseLabel(label) } -// ROFileLabel returns the specified SELinux readonly file label +// ROFileLabel returns the specified SELinux readonly file label. +// +// Deprecated: this (apparently) has no users and will be removed from the +// future version of this package. Open a bug report if you use it. func ROFileLabel() string { return roFileLabel() } // KVMContainerLabels returns the default processLabel and mountLabel to be used // for kvm containers by the calling process. +// +// Deprecated: use [KVMContainerLabel] instead. func KVMContainerLabels() (string, string) { return kvmContainerLabels() } +// KVMContainerLabel returns the default process label to be used +// for KVM containers by the calling process. +// +// If you only need to change a type of existing label, use [SetProcessKind] instead. +func KVMContainerLabel() (string, error) { + return kvmContainerLabel() +} + // InitContainerLabels returns the default processLabel and file labels to be // used for containers running an init system like systemd by the calling process. +// +// Deprecated: use [InitContainerLabel] instead. func InitContainerLabels() (string, string) { return initContainerLabels() } +// InitContainerLabel returns the default process label to be used +// for containers running an init system like systemd by the calling process. +// +// If you only need to change a type of existing label, use [SetProcessKind] instead. +func InitContainerLabel() (string, error) { + return initContainerLabel() +} + // ContainerLabels returns an allocated processLabel and fileLabel to be used for // container labeling by the calling process. +// +// Deprecated: this (apparently) has no users and will be removed from the +// future version of this package. Open a bug report if you use it. func ContainerLabels() (processLabel string, fileLabel string) { return containerLabels() } @@ -305,11 +370,19 @@ func DisableSecOpt() []string { return []string{"disable"} } +// SEUserByName retrieves the SELinux username and security level for a given +// Linux username. The username and security level is based on the +// /etc/selinux/{SELINUXTYPE}/seusers file. +func SEUserByName(username string) (seUser string, level string, err error) { + return getSeUserByName(username) +} + // GetDefaultContextWithLevel gets a single context for the specified SELinux user // identity that is reachable from the specified scon context. The context is based // on the per-user /etc/selinux/{SELINUXTYPE}/contexts/users/ if it exists, // and falls back to the global /etc/selinux/{SELINUXTYPE}/contexts/default_contexts -// file. +// file and finally the global /etc/selinux/{SELINUXTYPE}/contexts/failsafe_context +// file if no match can be found anywhere else. func GetDefaultContextWithLevel(user, level, scon string) (string, error) { return getDefaultContextWithLevel(user, level, scon) } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index 6d7f8e270..f238b1940 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -3,16 +3,16 @@ package selinux import ( "bufio" "bytes" - "crypto/rand" - "encoding/binary" "errors" "fmt" "io" "io/fs" "math/big" + "math/rand/v2" "os" "os/user" "path/filepath" + "slices" "strconv" "strings" "sync" @@ -30,6 +30,7 @@ const ( selinuxDir = "/etc/selinux/" selinuxUsersDir = "contexts/users" defaultContexts = "contexts/default_contexts" + failsafeContext = "contexts/failsafe_context" selinuxConfig = selinuxDir + "config" selinuxfsMount = "/sys/fs/selinux" selinuxTypeTag = "SELINUXTYPE" @@ -38,11 +39,9 @@ const ( ) type selinuxState struct { - mcsList map[string]bool - selinuxfs string - selinuxfsOnce sync.Once - enabledSet bool - enabled bool + mcsList map[string]struct{} + enabledSet bool + enabled bool sync.Mutex } @@ -56,10 +55,19 @@ type mlsRange struct { high *level } +type openReaderCloser func() (io.ReadCloser, error) + +func createOpener(path string) openReaderCloser { + return func() (io.ReadCloser, error) { + return os.Open(path) + } +} + type defaultSECtx struct { - userRdr io.Reader + openUserRdr openReaderCloser verifier func(string) error - defaultRdr io.Reader + openDefaultRdr openReaderCloser + openFailsafeRdr openReaderCloser user, level, scon string } @@ -72,26 +80,15 @@ const ( var ( readOnlyFileLabel string - state = selinuxState{ - mcsList: make(map[string]bool), - } - - // for policyRoot() - policyRootOnce sync.Once - policyRootVal string - // for label() - loadLabelsOnce sync.Once - labels map[string]string + state = selinuxState{ + mcsList: make(map[string]struct{}), + } ) -func policyRoot() string { - policyRootOnce.Do(func() { - policyRootVal = filepath.Join(selinuxDir, readConfig(selinuxTypeTag)) - }) - - return policyRootVal -} +var policyRoot = sync.OnceValue(func() string { + return filepath.Join(selinuxDir, readConfig(selinuxTypeTag)) +}) func (s *selinuxState) setEnable(enabled bool) bool { s.Lock() @@ -148,7 +145,12 @@ func verifySELinuxfsMount(mnt string) bool { return true } -func findSELinuxfs() string { +// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs +// filesystem or an empty string if no mountpoint is found. Selinuxfs is +// a proc-like pseudo-filesystem that exposes the SELinux policy API to +// processes. The existence of an selinuxfs mount is used to determine +// whether SELinux is currently enabled or not. +var getSelinuxMountPoint = sync.OnceValue(func() string { // fast path: check the default mount first if verifySELinuxfsMount(selinuxfsMount) { return selinuxfsMount @@ -180,7 +182,7 @@ func findSELinuxfs() string { return mnt } } -} +}) // findSELinuxfsMount returns a next selinuxfs mount point found, // if there is one, or an empty string in case of EOF or error. @@ -203,23 +205,6 @@ func findSELinuxfsMount(s *bufio.Scanner) string { return "" } -func (s *selinuxState) getSELinuxfs() string { - s.selinuxfsOnce.Do(func() { - s.selinuxfs = findSELinuxfs() - }) - - return s.selinuxfs -} - -// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs -// filesystem or an empty string if no mountpoint is found. Selinuxfs is -// a proc-like pseudo-filesystem that exposes the SELinux policy API to -// processes. The existence of an selinuxfs mount is used to determine -// whether SELinux is currently enabled or not. -func getSelinuxMountPoint() string { - return state.getSELinuxfs() -} - // getEnabled returns whether SELinux is currently enabled. func getEnabled() bool { return state.getEnabled() @@ -244,12 +229,9 @@ func readConfig(target string) string { // Skip comments continue } - fields := bytes.SplitN(line, []byte{'='}, 2) - if len(fields) != 2 { - continue - } - if bytes.Equal(fields[0], []byte(target)) { - return string(bytes.Trim(fields[1], `"`)) + key, val, ok := bytes.Cut(line, []byte{'='}) + if ok && string(key) == target { + return string(bytes.Trim(val, `"`)) } } return "" @@ -530,17 +512,6 @@ func setFSCreateLabel(label string) error { return writeConThreadSelf("attr/fscreate", label) } -// fsCreateLabel returns the default label the kernel which the kernel is using -// for file system objects created by this task. "" indicates default. -func fsCreateLabel() (string, error) { - return readConThreadSelf("attr/fscreate") -} - -// currentLabel returns the SELinux label of the current process thread, or an error. -func currentLabel() (string, error) { - return readConThreadSelf("attr/current") -} - // pidLabel returns the SELinux label of the given pid, or an error. func pidLabel(pid int) (string, error) { it, err := openProcPid(pid, "attr/current", os.O_RDONLY|unix.O_CLOEXEC) @@ -551,12 +522,6 @@ func pidLabel(pid int) (string, error) { return readConFd(it) } -// ExecLabel returns the SELinux label that the kernel will use for any programs -// that are executed by the current process thread, or an error. -func execLabel() (string, error) { - return readConThreadSelf("exec") -} - // canonicalizeContext takes a context string and writes it to the kernel // the function then returns the context that the kernel will use. Use this // function to check if two contexts are equivalent @@ -581,13 +546,12 @@ func catsToBitset(cats string) (*big.Int, error) { catlist := strings.Split(cats, ",") for _, r := range catlist { - ranges := strings.SplitN(r, ".", 2) - if len(ranges) > 1 { - catstart, err := parseLevelItem(ranges[0], category) + if s, e, ok := strings.Cut(r, "."); ok { + catstart, err := parseLevelItem(s, category) if err != nil { return nil, err } - catend, err := parseLevelItem(ranges[1], category) + catend, err := parseLevelItem(e, category) if err != nil { return nil, err } @@ -595,7 +559,7 @@ func catsToBitset(cats string) (*big.Int, error) { bitset.SetBit(bitset, i, 1) } } else { - cat, err := parseLevelItem(ranges[0], category) + cat, err := parseLevelItem(r, category) if err != nil { return nil, err } @@ -623,14 +587,14 @@ func parseLevelItem(s string, sep levelItem) (int, error) { // parseLevel fills a level from a string that contains // a sensitivity and categories func (l *level) parseLevel(levelStr string) error { - lvl := strings.SplitN(levelStr, ":", 2) - sens, err := parseLevelItem(lvl[0], sensitivity) + s, c, ok := strings.Cut(levelStr, ":") + sens, err := parseLevelItem(s, sensitivity) if err != nil { return fmt.Errorf("failed to parse sensitivity: %w", err) } l.sens = sens - if len(lvl) > 1 { - cats, err := catsToBitset(lvl[1]) + if ok { + cats, err := catsToBitset(c) if err != nil { return fmt.Errorf("failed to parse categories: %w", err) } @@ -643,25 +607,19 @@ func (l *level) parseLevel(levelStr string) error { // rangeStrToMLSRange marshals a string representation of a range. func rangeStrToMLSRange(rangeStr string) (*mlsRange, error) { r := &mlsRange{} - l := strings.SplitN(rangeStr, "-", 2) - - switch len(l) { - // rangeStr that has a low and a high level, e.g. s4:c0.c1023-s6:c0.c1023 - case 2: + lo, hi, ok := strings.Cut(rangeStr, "-") + r.low = &level{} + if err := r.low.parseLevel(lo); err != nil { + return nil, fmt.Errorf("failed to parse low level %q: %w", lo, err) + } + if ok { + // rangeStr that has a low and a high level, e.g. s4:c0.c1023-s6:c0.c1023. r.high = &level{} - if err := r.high.parseLevel(l[1]); err != nil { - return nil, fmt.Errorf("failed to parse high level %q: %w", l[1], err) - } - fallthrough - // rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023 - case 1: - r.low = &level{} - if err := r.low.parseLevel(l[0]); err != nil { - return nil, fmt.Errorf("failed to parse low level %q: %w", l[0], err) + if err := r.high.parseLevel(hi); err != nil { + return nil, fmt.Errorf("failed to parse high level %q: %w", hi, err) } - } - - if r.high == nil { + } else { + // rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023. r.high = r.low } @@ -732,22 +690,6 @@ func (m mlsRange) String() string { return low + "-" + high } -// TODO: remove these in favor of built-in min/max -// once we stop supporting Go < 1.21. -func maxInt(a, b int) int { - if a > b { - return a - } - return b -} - -func minInt(a, b int) int { - if a < b { - return a - } - return b -} - // calculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound) // of a source and target range. // The glblub is calculated as the greater of the low sensitivities and @@ -770,10 +712,10 @@ func calculateGlbLub(sourceRange, targetRange string) (string, error) { outrange := &mlsRange{low: &level{}, high: &level{}} /* take the greatest of the low */ - outrange.low.sens = maxInt(s.low.sens, t.low.sens) + outrange.low.sens = max(s.low.sens, t.low.sens) /* take the least of the high */ - outrange.high.sens = minInt(s.high.sens, t.high.sens) + outrange.high.sens = min(s.high.sens, t.high.sens) /* find the intersecting categories */ if s.low.cats != nil && t.low.cats != nil { @@ -807,10 +749,10 @@ func readWriteCon(fpath string, val string) (string, error) { } // peerLabel retrieves the label of the client on the other side of a socket -func peerLabel(fd uintptr) (string, error) { - l, err := unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC) +func peerLabel(fd int) (string, error) { + l, err := unix.GetsockoptString(fd, unix.SOL_SOCKET, unix.SO_PEERSEC) if err != nil { - return "", &os.PathError{Op: "getsockopt", Path: "fd " + strconv.Itoa(int(fd)), Err: err} + return "", &os.PathError{Op: "getsockopt", Path: "fd " + strconv.Itoa(fd), Err: err} } return l, nil } @@ -871,18 +813,34 @@ func newContext(label string) (Context, error) { // clearLabels clears all reserved labels func clearLabels() { state.Lock() - state.mcsList = make(map[string]bool) + state.mcsList = make(map[string]struct{}) state.Unlock() } -// reserveLabel reserves the MLS/MCS level component of the specified label -func reserveLabel(label string) { +// reserveLabel reserves the MLS/MCS level component of the specified label. +func reserveLabel(label string) error { + if len(label) != 0 { + con := strings.SplitN(label, ":", 4) + if len(con) > 3 { + return mcsAdd(con[3]) + } + } + + return nil +} + +func checkLabel(label string) error { if len(label) != 0 { con := strings.SplitN(label, ":", 4) if len(con) > 3 { - _ = mcsAdd(con[3]) + state.Lock() + defer state.Unlock() + if _, exist := state.mcsList[con[3]]; exist { + return ErrMCSAlreadyExists + } } } + return nil } func selinuxEnforcePath() string { @@ -938,10 +896,10 @@ func mcsAdd(mcs string) error { } state.Lock() defer state.Unlock() - if state.mcsList[mcs] { + if _, exist := state.mcsList[mcs]; exist { return ErrMCSAlreadyExists } - state.mcsList[mcs] = true + state.mcsList[mcs] = struct{}{} return nil } @@ -951,41 +909,21 @@ func mcsDelete(mcs string) { } state.Lock() defer state.Unlock() - state.mcsList[mcs] = false -} - -func intToMcs(id int, catRange uint32) string { - var ( - SETSIZE = int(catRange) - TIER = SETSIZE - ORD = id - ) - - if id < 1 || id > 523776 { - return "" - } - - for ORD > TIER { - ORD -= TIER - TIER-- - } - TIER = SETSIZE - TIER - ORD += TIER - return fmt.Sprintf("s0:c%d,c%d", TIER, ORD) + delete(state.mcsList, mcs) } func uniqMcs(catRange uint32) string { var ( - n uint32 c1, c2 uint32 mcs string ) for { - _ = binary.Read(rand.Reader, binary.LittleEndian, &n) - c1 = n % catRange - _ = binary.Read(rand.Reader, binary.LittleEndian, &n) - c2 = n % catRange + //#nosec G404 -- using slightly more predictable MCS labels won't affect security, so it's fine to use math/rand/v2 here. + { + c1 = rand.Uint32N(catRange) + c2 = rand.Uint32N(catRange) + } if c1 == c2 { continue } else if c1 > c2 { @@ -1023,11 +961,11 @@ func openContextFile() (*os.File, error) { return os.Open(filepath.Join(policyRoot(), "contexts", "lxc_contexts")) } -func loadLabels() { - labels = make(map[string]string) +var loadLabels = sync.OnceValue(func() map[string]string { + labels := make(map[string]string) in, err := openContextFile() if err != nil { - return + return labels } defer in.Close() @@ -1043,25 +981,21 @@ func loadLabels() { // Skip comments continue } - fields := bytes.SplitN(line, []byte{'='}, 2) - if len(fields) != 2 { - continue + if key, val, ok := bytes.Cut(line, []byte{'='}); ok { + key, val = bytes.TrimSpace(key), bytes.TrimSpace(val) + labels[string(key)] = string(bytes.Trim(val, `"`)) } - key, val := bytes.TrimSpace(fields[0]), bytes.TrimSpace(fields[1]) - labels[string(key)] = string(bytes.Trim(val, `"`)) } con, _ := NewContext(labels["file"]) con["level"] = fmt.Sprintf("s0:c%d,c%d", maxCategory-2, maxCategory-1) privContainerMountLabel = con.get() - reserveLabel(privContainerMountLabel) -} + _ = reserveLabel(privContainerMountLabel) + return labels +}) func label(key string) string { - loadLabelsOnce.Do(func() { - loadLabels() - }) - return labels[key] + return loadLabels()[key] } // kvmContainerLabels returns the default processLabel and mountLabel to be used @@ -1075,6 +1009,15 @@ func kvmContainerLabels() (string, string) { return addMcs(processLabel, label("file")) } +func kvmContainerLabel() (string, error) { + processLabel := label("kvm_process") + if processLabel == "" { + processLabel = label("process") + } + pLabel, _, err := addMcsProc(processLabel) + return pLabel, err +} + // initContainerLabels returns the default processLabel and file labels to be // used for containers running an init system like systemd by the calling process. func initContainerLabels() (string, string) { @@ -1086,6 +1029,16 @@ func initContainerLabels() (string, string) { return addMcs(processLabel, label("file")) } +func initContainerLabel() (string, error) { + processLabel := label("init_process") + if processLabel == "" { + processLabel = label("process") + } + + pLabel, _, err := addMcsProc(processLabel) + return pLabel, err +} + // containerLabels returns an allocated processLabel and fileLabel to be used for // container labeling by the calling process. func containerLabels() (processLabel string, fileLabel string) { @@ -1108,13 +1061,24 @@ func containerLabels() (processLabel string, fileLabel string) { return addMcs(processLabel, fileLabel) } -func addMcs(processLabel, fileLabel string) (string, string) { - scon, _ := NewContext(processLabel) +func addMcsProc(processLabel string) (string, string, error) { + var mcs string + scon, err := NewContext(processLabel) + if err != nil { + return "", "", err + } if scon["level"] != "" { - mcs := uniqMcs(CategoryRange) + mcs = uniqMcs(CategoryRange) scon["level"] = mcs processLabel = scon.Get() - scon, _ = NewContext(fileLabel) + } + return processLabel, mcs, nil +} + +func addMcs(processLabel, fileLabel string) (string, string) { + processLabel, mcs, _ := addMcsProc(processLabel) + if mcs != "" { + scon, _ := NewContext(fileLabel) scon["level"] = mcs fileLabel = scon.Get() } @@ -1281,6 +1245,111 @@ func dupSecOpt(src string) ([]string, error) { return dup, nil } +// checkGroup returns true if group's GID is in the list of GIDs gids. +func checkGroup(group string, gids []string, lookupGroup func(string) (*user.Group, error)) bool { + grp, err := lookupGroup(group) + if err != nil { + return false + } + + return slices.Contains(gids, grp.Gid) +} + +// getSeUserFromReader reads the seusers file: https://www.man7.org/linux/man-pages/man5/seusers.5.html +func getSeUserFromReader(username string, gids []string, r io.Reader, lookupGroup func(string) (*user.Group, error)) (seUser string, level string, err error) { + var defaultSeUser, defaultLevel string + var groupSeUser, groupLevel string + + lineNum := -1 + scanner := bufio.NewScanner(r) + for scanner.Scan() { + rawLine := scanner.Text() + lineNum++ + + // remove any trailing comments, then extra whitespace + line, _, _ := strings.Cut(rawLine, "#") + line = strings.TrimSpace(line) + if line == "" { + continue + } + + userField, rest, ok := strings.Cut(line, ":") + if !ok { + return "", "", fmt.Errorf("line %d: malformed line", lineNum) + } + if userField == "" { + return "", "", fmt.Errorf("line %d: user_id or group_id is empty", lineNum) + } + seUserField, rest, ok := strings.Cut(rest, ":") + if seUserField == "" { + return "", "", fmt.Errorf("line %d: seuser_id is empty", lineNum) + } + var levelField string + // level is optional + if ok { + levelField = rest + } + + // we found a match, return it + if userField == username { + return seUserField, levelField, nil + } + + // if the first field starts with '%' it's a group, check if + // the user is a member of that group and set the group + // SELinux user and level if so + if userField[0] == '%' && groupSeUser == "" { + if checkGroup(userField[1:], gids, lookupGroup) { + groupSeUser = seUserField + groupLevel = levelField + } + } else if userField == "__default__" && defaultSeUser == "" { + defaultSeUser = seUserField + defaultLevel = levelField + } + } + if err := scanner.Err(); err != nil { + return "", "", fmt.Errorf("failed to read seusers file: %w", err) + } + + if groupSeUser != "" { + return groupSeUser, groupLevel, nil + } + if defaultSeUser != "" { + return defaultSeUser, defaultLevel, nil + } + + return "", "", fmt.Errorf("could not find SELinux user for %q login", username) +} + +// getSeUserByName returns an SELinux user and MLS level that is +// mapped to a given Linux user. +func getSeUserByName(username string) (string, string, error) { + seUsersConf := filepath.Join(policyRoot(), "seusers") + confFile, err := os.Open(seUsersConf) + if err != nil { + return "", "", fmt.Errorf("failed to open seusers file: %w", err) + } + defer confFile.Close() + + usr, err := user.Lookup(username) + if err != nil { + return "", "", err + } + gids, err := usr.GroupIds() + if err != nil { + return "", "", err + } + gids = append([]string{usr.Gid}, gids...) + + seUser, level, err := getSeUserFromReader(username, gids, confFile, user.LookupGroup) + if err != nil { + return "", "", fmt.Errorf("failed to parse seusers file: %w", err) + } + + return seUser, level, nil +} + // findUserInContext scans the reader for a valid SELinux context // match that is verified with the verifier. Invalid contexts are // skipped. It returns a matched context or an empty string if no @@ -1338,6 +1407,33 @@ func findUserInContext(context Context, r io.Reader, verifier func(string) error return "", nil } +// getFailsafeContext returns the context in the failsafe_context file: +// https://www.man7.org/linux/man-pages/man5/failsafe_context.5.html +func getFailsafeContext(context Context, r io.Reader, verifier func(string) error) (string, error) { + conn := make([]byte, 256) + limReader := io.LimitReader(r, int64(len(conn))) + _, err := limReader.Read(conn) + if err != nil { + return "", fmt.Errorf("failed to read failsafe context: %w", err) + } + + conn = bytes.TrimSpace(conn) + toConns := strings.SplitN(string(conn), ":", 4) + if len(toConns) != 3 { + return "", nil + } + + context["role"] = toConns[0] + context["type"] = toConns[1] + + outConn := context.get() + if err := verifier(outConn); err != nil { + return "", err + } + + return outConn, nil +} + func getDefaultContextFromReaders(c *defaultSECtx) (string, error) { if c.verifier == nil { return "", ErrVerifierNil @@ -1352,18 +1448,45 @@ func getDefaultContextFromReaders(c *defaultSECtx) (string, error) { context["user"] = c.user context["level"] = c.level - conn, err := findUserInContext(context, c.userRdr, c.verifier) + userRdr, err := c.openUserRdr() if err != nil { - return "", err + return "", fmt.Errorf("failed to open user context file: %w", err) + } + defer userRdr.Close() + + conn, err := findUserInContext(context, userRdr, c.verifier) + if err != nil { + return "", fmt.Errorf("failed to read %q's user context file: %w", c.user, err) } if conn != "" { return conn, nil } - conn, err = findUserInContext(context, c.defaultRdr, c.verifier) + defaultRdr, err := c.openDefaultRdr() if err != nil { - return "", err + return "", fmt.Errorf("failed to open default context file: %w", err) + } + defer defaultRdr.Close() + + conn, err = findUserInContext(context, defaultRdr, c.verifier) + if err != nil { + return "", fmt.Errorf("failed to read default user context file: %w", err) + } + + if conn != "" { + return conn, nil + } + + failsafeRdr, err := c.openFailsafeRdr() + if err != nil { + return "", fmt.Errorf("failed to open failsafe context file: %w", err) + } + defer failsafeRdr.Close() + + conn, err = getFailsafeContext(context, failsafeRdr, c.verifier) + if err != nil { + return "", fmt.Errorf("failed to read failsafe_context: %w", err) } if conn != "" { @@ -1375,27 +1498,61 @@ func getDefaultContextFromReaders(c *defaultSECtx) (string, error) { func getDefaultContextWithLevel(user, level, scon string) (string, error) { userPath := filepath.Join(policyRoot(), selinuxUsersDir, user) - fu, err := os.Open(userPath) - if err != nil { - return "", err - } - defer fu.Close() - defaultPath := filepath.Join(policyRoot(), defaultContexts) - fd, err := os.Open(defaultPath) - if err != nil { - return "", err - } - defer fd.Close() + failsafePath := filepath.Join(policyRoot(), failsafeContext) c := defaultSECtx{ - user: user, - level: level, - scon: scon, - userRdr: fu, - defaultRdr: fd, - verifier: securityCheckContext, + user: user, + level: level, + scon: scon, + openUserRdr: createOpener(userPath), + openDefaultRdr: createOpener(defaultPath), + openFailsafeRdr: createOpener(failsafePath), + verifier: securityCheckContext, } return getDefaultContextFromReaders(&c) } + +func (k ProcessKind) keys() (primary, fallback string, ok bool) { + switch k { + case ProcessKindRegular: + return "process", "", true + case ProcessKindInit: + return "init_process", "process", true + case ProcessKindKVM: + return "kvm_process", "process", true + } + return "", "", false +} + +func setProcessKind(cLabel string, k ProcessKind) (string, error) { + if cLabel == "" { + return "", nil + } + primary, fallback, ok := k.keys() + if !ok { + return "", fmt.Errorf("selinux.SetProcessKind: invalid ProcessKind %d", k) + } + + src := label(primary) + if src == "" && fallback != "" { + src = label(fallback) + } + if src == "" { + return cLabel, nil + } + + // Replace cLabel type with one from src. + srcCtx, err := newContext(src) + if err != nil { + return "", fmt.Errorf("selinux.SetProcessKind: invalid %s label %s: %w", primary, src, err) + } + dstCtx, err := newContext(cLabel) + if err != nil { + return "", fmt.Errorf("selinux.SetProcessKind: invalid label %s: %w", cLabel, err) + } + + dstCtx["type"] = srcCtx["type"] + return dstCtx.get(), nil +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 382244e50..d01bf2615 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -1,5 +1,4 @@ //go:build !linux -// +build !linux package selinux @@ -41,22 +40,10 @@ func setFSCreateLabel(string) error { return nil } -func fsCreateLabel() (string, error) { - return "", nil -} - -func currentLabel() (string, error) { - return "", nil -} - func pidLabel(int) (string, error) { return "", nil } -func execLabel() (string, error) { - return "", nil -} - func canonicalizeContext(string) (string, error) { return "", nil } @@ -69,7 +56,7 @@ func calculateGlbLub(string, string) (string, error) { return "", nil } -func peerLabel(uintptr) (string, error) { +func peerLabel(int) (string, error) { return "", nil } @@ -92,7 +79,12 @@ func newContext(string) (Context, error) { func clearLabels() { } -func reserveLabel(string) { +func reserveLabel(string) error { + return nil +} + +func checkLabel(string) error { + return nil } func isMLSEnabled() bool { @@ -122,10 +114,18 @@ func kvmContainerLabels() (string, string) { return "", "" } +func kvmContainerLabel() (string, error) { + return "", nil +} + func initContainerLabels() (string, string) { return "", "" } +func initContainerLabel() (string, error) { + return "", nil +} + func containerLabels() (string, string) { return "", "" } @@ -146,6 +146,10 @@ func dupSecOpt(string) ([]string, error) { return nil, nil } +func getSeUserByName(string) (string, string, error) { + return "", "", nil +} + func getDefaultContextWithLevel(string, string, string) (string, error) { return "", nil } @@ -153,3 +157,7 @@ func getDefaultContextWithLevel(string, string, string) (string, error) { func label(_ string) string { return "" } + +func setProcessKind(string, ProcessKind) (string, error) { + return "", nil +} diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go b/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go index 5d2d09a29..d361dcb64 100644 --- a/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go +++ b/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go @@ -1,6 +1,3 @@ -//go:build go1.16 -// +build go1.16 - package pwalkdir import ( @@ -92,7 +89,7 @@ func WalkN(root string, walkFn fs.WalkDirFunc, num int) error { }() wg.Add(num) - for i := 0; i < num; i++ { + for range num { go func() { for file := range files { if e := walkFn(file.path, file.entry, nil); e != nil { diff --git a/vendor/golang.org/x/net/html/iter.go b/vendor/golang.org/x/net/html/iter.go index 54be8fd30..349ef73e6 100644 --- a/vendor/golang.org/x/net/html/iter.go +++ b/vendor/golang.org/x/net/html/iter.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.23 - package html import "iter" diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go index 77741a195..253e4679c 100644 --- a/vendor/golang.org/x/net/html/node.go +++ b/vendor/golang.org/x/net/html/node.go @@ -11,6 +11,7 @@ import ( // A NodeType is the type of a Node. type NodeType uint32 +//go:generate stringer -type NodeType const ( ErrorNode NodeType = iota TextNode diff --git a/vendor/golang.org/x/net/html/nodetype_string.go b/vendor/golang.org/x/net/html/nodetype_string.go new file mode 100644 index 000000000..8253af491 --- /dev/null +++ b/vendor/golang.org/x/net/html/nodetype_string.go @@ -0,0 +1,31 @@ +// Code generated by "stringer -type NodeType"; DO NOT EDIT. + +package html + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ErrorNode-0] + _ = x[TextNode-1] + _ = x[DocumentNode-2] + _ = x[ElementNode-3] + _ = x[CommentNode-4] + _ = x[DoctypeNode-5] + _ = x[RawNode-6] + _ = x[scopeMarkerNode-7] +} + +const _NodeType_name = "ErrorNodeTextNodeDocumentNodeElementNodeCommentNodeDoctypeNodeRawNodescopeMarkerNode" + +var _NodeType_index = [...]uint8{0, 9, 17, 29, 40, 51, 62, 69, 84} + +func (i NodeType) String() string { + idx := int(i) - 0 + if i < 0 || idx >= len(_NodeType_index)-1 { + return "NodeType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _NodeType_name[_NodeType_index[idx]:_NodeType_index[idx+1]] +} diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go index 3ca814f54..1157b06d8 100644 --- a/vendor/golang.org/x/sys/windows/dll_windows.go +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -163,42 +163,7 @@ func (p *Proc) Addr() uintptr { // (according to the semantics of the specific function being called) before consulting // the error. The error will be guaranteed to contain windows.Errno. func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { - switch len(a) { - case 0: - return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0) - case 1: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0) - case 2: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0) - case 3: - return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2]) - case 4: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0) - case 5: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0) - case 6: - return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5]) - case 7: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0) - case 8: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0) - case 9: - return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) - case 10: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0) - case 11: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0) - case 12: - return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) - case 13: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0) - case 14: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0) - case 15: - return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]) - default: - panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".") - } + return syscall.SyscallN(p.Addr(), a...) } // A LazyDLL implements access to a single DLL. diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go index a8b0364c7..6c955cea1 100644 --- a/vendor/golang.org/x/sys/windows/security_windows.go +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -1438,13 +1438,17 @@ func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformati } // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security -// descriptor result on the Go heap. +// descriptor result on the Go heap. The security descriptor might be nil, even when err is nil, if the object exists +// but has no security descriptor. func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) { var winHeapSD *SECURITY_DESCRIPTOR err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD) if err != nil { return } + if winHeapSD == nil { + return nil, nil + } defer LocalFree(Handle(unsafe.Pointer(winHeapSD))) return winHeapSD.copySelfRelativeSecurityDescriptor(), nil } diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go index 60ad425f3..239b10c4d 100644 --- a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go +++ b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go @@ -18,8 +18,11 @@ import ( // // Two Cursors compare equal if they represent the same node. // -// Call [Inspector.Root] to obtain a valid cursor for the virtual root -// node of the traversal. +// The zero value of Cursor is not valid. +// +// Call [Inspector.Root] to obtain a cursor for the virtual root node +// of the traversal. This is the sole valid cursor for which [Cursor.Node] +// returns nil. // // Use the following methods to navigate efficiently around the tree: // - for ancestors, use [Cursor.Parent] and [Cursor.Enclosing]; @@ -37,7 +40,7 @@ type Cursor struct { index int32 // index of push node; -1 for virtual root node } -// Root returns a cursor for the virtual root node, +// Root returns a valid cursor for the virtual root node, // whose children are the files provided to [New]. // // Its [Cursor.Node] method return nil. @@ -61,14 +64,23 @@ func (in *Inspector) At(index int32) Cursor { return Cursor{in, index} } +// Valid reports whether the cursor is valid. +// The zero value of cursor is invalid. +// Unless otherwise documented, it is not safe to call +// any other method on an invalid cursor. +func (c Cursor) Valid() bool { + return c.in != nil +} + // Inspector returns the cursor's Inspector. +// It returns nil if the Cursor is not valid. func (c Cursor) Inspector() *Inspector { return c.in } // Index returns the index of this cursor position within the package. // // Clients should not assume anything about the numeric Index value // except that it increases monotonically throughout the traversal. -// It is provided for use with [At]. +// It is provided for use with [Inspector.At]. // // Index must not be called on the Root node. func (c Cursor) Index() int32 { @@ -89,7 +101,7 @@ func (c Cursor) Node() ast.Node { // String returns information about the cursor's node, if any. func (c Cursor) String() string { - if c.in == nil { + if !c.Valid() { return "(invalid)" } if c.index < 0 { @@ -233,6 +245,18 @@ func (c Cursor) ParentEdge() (edge.Kind, int) { return unpackEdgeKindAndIndex(events[pop].parent) } +// ParentEdgeKind returns the kind component of the result of [Cursor.ParentEdge]. +func (c Cursor) ParentEdgeKind() edge.Kind { + ek, _ := c.ParentEdge() + return ek +} + +// ParentEdgeIndex returns the index component of the result of [Cursor.ParentEdge]. +func (c Cursor) ParentEdgeIndex() int { + _, index := c.ParentEdge() + return index +} + // ChildAt returns the cursor for the child of the // current node identified by its edge and index. // The index must be -1 if the edge.Kind is not a slice. diff --git a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go index a703cdfcf..b414d17eb 100644 --- a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go +++ b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go @@ -87,7 +87,7 @@ type event struct { // Type can be recovered from the sole bit in typ. // [Tried this, wasn't faster. --adonovan] -// Preorder visits all the nodes of the files supplied to New in +// Preorder visits all the nodes of the files supplied to [New] in // depth-first order. It calls f(n) for each node n before it visits // n's children. // @@ -133,7 +133,7 @@ func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) { } } -// Nodes visits the nodes of the files supplied to New in depth-first +// Nodes visits the nodes of the files supplied to [New] in depth-first // order. It calls f(n, true) for each node n before it visits n's // children. If f returns true, Nodes invokes f recursively for each // of the non-nil children of the node, followed by a call of diff --git a/vendor/golang.org/x/tools/go/ast/inspector/iter.go b/vendor/golang.org/x/tools/go/ast/inspector/iter.go index c576dc70a..b68c553d4 100644 --- a/vendor/golang.org/x/tools/go/ast/inspector/iter.go +++ b/vendor/golang.org/x/tools/go/ast/inspector/iter.go @@ -12,13 +12,31 @@ import ( ) // PreorderSeq returns an iterator that visits all the -// nodes of the files supplied to New in depth-first order. +// nodes of the files supplied to [New] in depth-first order. // It visits each node n before n's children. // The complete traversal sequence is determined by ast.Inspect. // -// The types argument, if non-empty, enables type-based -// filtering of events: only nodes whose type matches an -// element of the types slice are included in the sequence. +// The types argument, if non-empty, enables type-based filtering: +// only nodes whose type matches an element of the types slice are +// included in the sequence. +// +// Example: +// +// for call := range in.PreorderSeq((*ast.CallExpr)(nil)) { ... } +// +// The [All] function is more convenient if there is exactly one node type: +// +// for call := range All[*ast.CallExpr](in) { ... } +// +// See also the newer and more flexible [Cursor] API, which lets you +// start the traversal at an arbitrary node, and reports each matching +// node by its Cursor, enabling easier navigation. +// The above example would be written thus: +// +// for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { +// call := curCall.Node().(*ast.CallExpr) +// ... +// } func (in *Inspector) PreorderSeq(types ...ast.Node) iter.Seq[ast.Node] { // This implementation is identical to Preorder, @@ -53,6 +71,16 @@ func (in *Inspector) PreorderSeq(types ...ast.Node) iter.Seq[ast.Node] { // Example: // // for call := range All[*ast.CallExpr](in) { ... } +// +// See also the newer and more flexible [Cursor] API, which lets you +// start the traversal at an arbitrary node, and reports each matching +// node by its Cursor, enabling easier navigation. +// The above example would be written thus: +// +// for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { +// call := curCall.Node().(*ast.CallExpr) +// ... +// } func All[N interface { *S ast.Node diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go index 680a70ca8..a6c17cf63 100644 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -61,13 +61,42 @@ func (r *responseDeduper) addAll(dr *DriverResponse) { } func (r *responseDeduper) addPackage(p *Package) { - if r.seenPackages[p.ID] != nil { + if prev := r.seenPackages[p.ID]; prev != nil { + // Package already seen in a previous response. Merge the file lists, + // removing duplicates. This can happen when the same package appears + // in multiple driver responses that are being merged together. + prev.GoFiles = appendUniqueStrings(prev.GoFiles, p.GoFiles) + prev.CompiledGoFiles = appendUniqueStrings(prev.CompiledGoFiles, p.CompiledGoFiles) + prev.OtherFiles = appendUniqueStrings(prev.OtherFiles, p.OtherFiles) + prev.IgnoredFiles = appendUniqueStrings(prev.IgnoredFiles, p.IgnoredFiles) + prev.EmbedFiles = appendUniqueStrings(prev.EmbedFiles, p.EmbedFiles) + prev.EmbedPatterns = appendUniqueStrings(prev.EmbedPatterns, p.EmbedPatterns) return } r.seenPackages[p.ID] = p r.dr.Packages = append(r.dr.Packages, p) } +// appendUniqueStrings appends elements from src to dst, skipping duplicates. +func appendUniqueStrings(dst, src []string) []string { + if len(src) == 0 { + return dst + } + + seen := make(map[string]bool, len(dst)) + for _, s := range dst { + seen[s] = true + } + + for _, s := range src { + if !seen[s] { + dst = append(dst, s) + } + } + + return dst +} + func (r *responseDeduper) addRoot(id string) { if r.seenRoots[id] { return @@ -832,6 +861,8 @@ func golistargs(cfg *Config, words []string, goVersion int) []string { // go list doesn't let you pass -test and -find together, // probably because you'd just get the TestMain. fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)), + // VCS information is not needed when not printing Stale or StaleReason fields + "-buildvcs=false", } // golang/go#60456: with go1.21 and later, go list serves pgo variants, which diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go index ff607389d..412ba06b5 100644 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ b/vendor/golang.org/x/tools/go/packages/packages.go @@ -284,6 +284,8 @@ func Load(cfg *Config, patterns ...string) ([]*Package, error) { } } + ld.externalDriver = external + return ld.refine(response) } @@ -401,6 +403,10 @@ func mergeResponses(responses ...*DriverResponse) *DriverResponse { if len(responses) == 0 { return nil } + // No dedup needed + if len(responses) == 1 { + return responses[0] + } response := newDeduper() response.dr.NotHandled = false response.dr.Compiler = responses[0].Compiler @@ -692,10 +698,11 @@ type loaderPackage struct { type loader struct { pkgs map[string]*loaderPackage // keyed by Package.ID Config - sizes types.Sizes // non-nil if needed by mode - parseCache map[string]*parseValue - parseCacheMu sync.Mutex - exportMu sync.Mutex // enforces mutual exclusion of exportdata operations + sizes types.Sizes // non-nil if needed by mode + parseCache map[string]*parseValue + parseCacheMu sync.Mutex + exportMu sync.Mutex // enforces mutual exclusion of exportdata operations + externalDriver bool // true if an external GOPACKAGESDRIVER handled the request // Config.Mode contains the implied mode (see impliedLoadMode). // Implied mode contains all the fields we need the data for. @@ -1226,6 +1233,10 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { } if lpkg.Module != nil && lpkg.Module.GoVersion != "" { tc.GoVersion = "go" + lpkg.Module.GoVersion + } else if ld.externalDriver && lpkg.goVersion != 0 { + // Module information is missing when GOPACKAGESDRIVER is used, + // so use the go version from the driver response. + tc.GoVersion = fmt.Sprintf("go1.%d", lpkg.goVersion) } if (ld.Mode & typecheckCgo) != 0 { if !typesinternal.SetUsesCgo(tc) { 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 6646bf550..77aad553d 100644 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -29,7 +29,6 @@ import ( "strconv" "strings" - "golang.org/x/tools/internal/aliases" "golang.org/x/tools/internal/typesinternal" ) @@ -281,10 +280,10 @@ func (enc *Encoder) For(obj types.Object) (Path, error) { T := o.Type() if alias, ok := T.(*types.Alias); ok { - if r := findTypeParam(obj, aliases.TypeParams(alias), path, opTypeParam); r != nil { + if r := findTypeParam(obj, alias.TypeParams(), path, opTypeParam); r != nil { return Path(r), nil } - if r := find(obj, aliases.Rhs(alias), append(path, opRhs)); r != nil { + if r := find(obj, alias.Rhs(), append(path, opRhs)); r != nil { return Path(r), nil } @@ -525,7 +524,7 @@ func (f *finder) find(T types.Type, path []byte) []byte { for i := 0; i < T.NumMethods(); i++ { m := T.Method(i) if f.seenMethods[m] { - return nil + continue // break cycles (see TestIssue70418) } path2 := appendOpArg(path, opMethod, i) if m == f.obj { @@ -694,14 +693,11 @@ func Object(pkg *types.Package, p Path) (types.Object, error) { case opRhs: if alias, ok := t.(*types.Alias); ok { - t = aliases.Rhs(alias) - } else if false && aliases.Enabled() { - // The Enabled check is too expensive, so for now we - // simply assume that aliases are not enabled. - // + t = alias.Rhs() + } else if false { // Now that go1.24 is assured, we should be able to - // replace this with "if true {", but it causes tests - // to fail. TODO(adonovan): investigate. + // replace this with "if true {", but it causes objectpath + // tests to fail. TODO(adonovan): investigate. return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t) } diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases.go b/vendor/golang.org/x/tools/internal/aliases/aliases.go index b9425f5a2..a4ae04bc7 100644 --- a/vendor/golang.org/x/tools/internal/aliases/aliases.go +++ b/vendor/golang.org/x/tools/internal/aliases/aliases.go @@ -9,30 +9,10 @@ import ( "go/types" ) -// Package aliases defines backward compatible shims -// for the types.Alias type representation added in 1.22. -// This defines placeholders for x/tools until 1.26. - -// NewAlias creates a new TypeName in Package pkg that +// New creates a new TypeName in Package pkg that // is an alias for the type rhs. -// -// The enabled parameter determines whether the resulting [TypeName]'s -// type is an [types.Alias]. Its value must be the result of a call to -// [Enabled], which computes the effective value of -// GODEBUG=gotypesalias=... by invoking the type checker. The Enabled -// function is expensive and should be called once per task (e.g. -// package import), not once per call to NewAlias. -// -// Precondition: enabled || len(tparams)==0. -// If materialized aliases are disabled, there must not be any type parameters. -func NewAlias(enabled bool, pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName { - if enabled { - tname := types.NewTypeName(pos, pkg, name, nil) - SetTypeParams(types.NewAlias(tname, rhs), tparams) - return tname - } - if len(tparams) > 0 { - panic("cannot create an alias with type parameters when gotypesalias is not enabled") - } - return types.NewTypeName(pos, pkg, name, rhs) +func New(pos token.Pos, pkg *types.Package, name string, rhs types.Type, tparams []*types.TypeParam) *types.TypeName { + tname := types.NewTypeName(pos, pkg, name, nil) + types.NewAlias(tname, rhs).SetTypeParams(tparams) + return tname } diff --git a/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go b/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go deleted file mode 100644 index 7716a3331..000000000 --- a/vendor/golang.org/x/tools/internal/aliases/aliases_go122.go +++ /dev/null @@ -1,80 +0,0 @@ -// 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 aliases - -import ( - "go/ast" - "go/parser" - "go/token" - "go/types" -) - -// Rhs returns the type on the right-hand side of the alias declaration. -func Rhs(alias *types.Alias) types.Type { - if alias, ok := any(alias).(interface{ Rhs() types.Type }); ok { - return alias.Rhs() // go1.23+ - } - - // go1.22's Alias didn't have the Rhs method, - // so Unalias is the best we can do. - return types.Unalias(alias) -} - -// TypeParams returns the type parameter list of the alias. -func TypeParams(alias *types.Alias) *types.TypeParamList { - if alias, ok := any(alias).(interface{ TypeParams() *types.TypeParamList }); ok { - return alias.TypeParams() // go1.23+ - } - return nil -} - -// SetTypeParams sets the type parameters of the alias type. -func SetTypeParams(alias *types.Alias, tparams []*types.TypeParam) { - if alias, ok := any(alias).(interface { - SetTypeParams(tparams []*types.TypeParam) - }); ok { - alias.SetTypeParams(tparams) // go1.23+ - } else if len(tparams) > 0 { - panic("cannot set type parameters of an Alias type in go1.22") - } -} - -// TypeArgs returns the type arguments used to instantiate the Alias type. -func TypeArgs(alias *types.Alias) *types.TypeList { - if alias, ok := any(alias).(interface{ TypeArgs() *types.TypeList }); ok { - return alias.TypeArgs() // go1.23+ - } - return nil // empty (go1.22) -} - -// Origin returns the generic Alias type of which alias is an instance. -// If alias is not an instance of a generic alias, Origin returns alias. -func Origin(alias *types.Alias) *types.Alias { - if alias, ok := any(alias).(interface{ Origin() *types.Alias }); ok { - return alias.Origin() // go1.23+ - } - return alias // not an instance of a generic alias (go1.22) -} - -// Enabled reports whether [NewAlias] should create [types.Alias] types. -// -// This function is expensive! Call it sparingly. -func Enabled() bool { - // The only reliable way to compute the answer is to invoke go/types. - // We don't parse the GODEBUG environment variable, because - // (a) it's tricky to do so in a manner that is consistent - // with the godebug package; in particular, a simple - // substring check is not good enough. The value is a - // rightmost-wins list of options. But more importantly: - // (b) it is impossible to detect changes to the effective - // setting caused by os.Setenv("GODEBUG"), as happens in - // many tests. Therefore any attempt to cache the result - // is just incorrect. - fset := token.NewFileSet() - f, _ := parser.ParseFile(fset, "a.go", "package p; type A = int", parser.SkipObjectResolution) - pkg, _ := new(types.Config).Check("p", fset, []*ast.File{f}, nil) - _, enabled := pkg.Scope().Lookup("A").Type().(*types.Alias) - return enabled -} diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go index ade5d1e79..42c218818 100644 --- a/vendor/golang.org/x/tools/internal/event/core/event.go +++ b/vendor/golang.org/x/tools/internal/event/core/event.go @@ -7,6 +7,7 @@ package core import ( "fmt" + "iter" "time" "golang.org/x/tools/internal/event/label" @@ -34,10 +35,8 @@ func (ev Event) Format(f fmt.State, r rune) { if !ev.at.IsZero() { fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) } - for index := 0; ev.Valid(index); index++ { - if l := ev.Label(index); l.Valid() { - fmt.Fprintf(f, "\n\t%v", l) - } + for l := range ev.Labels() { + fmt.Fprintf(f, "\n\t%v", l) } } @@ -52,6 +51,22 @@ func (ev Event) Label(index int) label.Label { return ev.dynamic[index-len(ev.static)] } +// Labels returns an iterator over the event's valid labels. +func (ev Event) Labels() iter.Seq[label.Label] { + return func(yield func(label.Label) bool) { + for _, l := range ev.static { + if l.Valid() && !yield(l) { + return + } + } + for _, l := range ev.dynamic { + if l.Valid() && !yield(l) { + return + } + } + } +} + func (ev Event) Find(key label.Key) label.Label { for _, l := range ev.static { if l.Key() == key { diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go index 4cfa51b61..ac78bc3b9 100644 --- a/vendor/golang.org/x/tools/internal/event/keys/keys.go +++ b/vendor/golang.org/x/tools/internal/event/keys/keys.go @@ -6,14 +6,13 @@ package keys import ( "fmt" - "io" "math" "strconv" "golang.org/x/tools/internal/event/label" ) -// Value represents a key for untyped values. +// Value is a [label.Key] for untyped values. type Value struct { name string description string @@ -27,11 +26,11 @@ func New(name, description string) *Value { func (k *Value) Name() string { return k.name } func (k *Value) Description() string { return k.description } -func (k *Value) Format(w io.Writer, buf []byte, l label.Label) { - fmt.Fprint(w, k.From(l)) +func (k *Value) Append(buf []byte, l label.Label) []byte { + return fmt.Append(buf, k.From(l)) } -// Get can be used to get a label for the key from a label.Map. +// Get returns the label for the key of a label.Map. func (k *Value) Get(lm label.Map) any { if t := lm.Find(k); t.Valid() { return k.From(t) @@ -39,7 +38,7 @@ func (k *Value) Get(lm label.Map) any { return nil } -// From can be used to get a value from a Label. +// From returns the value of a Label. func (k *Value) From(t label.Label) any { return t.UnpackValue() } // Of creates a new Label with this key and the supplied value. @@ -54,7 +53,7 @@ type Tag struct { description string } -// NewTag creates a new Key for tagging labels. +// NewTag creates a new [label.Key] for tagging labels. func NewTag(name, description string) *Tag { return &Tag{name: name, description: description} } @@ -62,18 +61,18 @@ func NewTag(name, description string) *Tag { func (k *Tag) Name() string { return k.name } func (k *Tag) Description() string { return k.description } -func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {} +func (k *Tag) Append(buf []byte, l label.Label) []byte { return buf } // New creates a new Label with this key. func (k *Tag) New() label.Label { return label.OfValue(k, nil) } -// Int represents a key +// Int is a [label.Key] for signed integers. type Int struct { name string description string } -// NewInt creates a new Key for int values. +// NewInt returns a new [label.Key] for int64 values. func NewInt(name, description string) *Int { return &Int{name: name, description: description} } @@ -81,381 +80,92 @@ func NewInt(name, description string) *Int { func (k *Int) Name() string { return k.name } func (k *Int) Description() string { return k.description } -func (k *Int) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) +func (k *Int) Append(buf []byte, l label.Label) []byte { + return strconv.AppendInt(buf, k.From(l), 10) } // Of creates a new Label with this key and the supplied value. -func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) } +func (k *Int) Of(v int) label.Label { return k.Of64(int64(v)) } -// Get can be used to get a label for the key from a label.Map. -func (k *Int) Get(lm label.Map) int { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int) From(t label.Label) int { return int(t.Unpack64()) } - -// Int8 represents a key -type Int8 struct { - name string - description string -} - -// NewInt8 creates a new Key for int8 values. -func NewInt8(name, description string) *Int8 { - return &Int8{name: name, description: description} -} - -func (k *Int8) Name() string { return k.name } -func (k *Int8) Description() string { return k.description } - -func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int8) Get(lm label.Map) int8 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) } - -// Int16 represents a key -type Int16 struct { - name string - description string -} - -// NewInt16 creates a new Key for int16 values. -func NewInt16(name, description string) *Int16 { - return &Int16{name: name, description: description} -} - -func (k *Int16) Name() string { return k.name } -func (k *Int16) Description() string { return k.description } - -func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int16) Get(lm label.Map) int16 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) } - -// Int32 represents a key -type Int32 struct { - name string - description string -} +// Of64 creates a new Label with this key and the supplied value. +func (k *Int) Of64(v int64) label.Label { return label.Of64(k, uint64(v)) } -// NewInt32 creates a new Key for int32 values. -func NewInt32(name, description string) *Int32 { - return &Int32{name: name, description: description} -} - -func (k *Int32) Name() string { return k.name } -func (k *Int32) Description() string { return k.description } - -func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int32) Get(lm label.Map) int32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) } - -// Int64 represents a key -type Int64 struct { - name string - description string -} - -// NewInt64 creates a new Key for int64 values. -func NewInt64(name, description string) *Int64 { - return &Int64{name: name, description: description} -} - -func (k *Int64) Name() string { return k.name } -func (k *Int64) Description() string { return k.description } - -func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendInt(buf, k.From(l), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *Int64) Get(lm label.Map) int64 { +// Get returns the label for the key of a label.Map. +func (k *Int) Get(lm label.Map) int64 { if t := lm.Find(k); t.Valid() { return k.From(t) } return 0 } -// From can be used to get a value from a Label. -func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) } +// From returns the value of a Label. +func (k *Int) From(t label.Label) int64 { return int64(t.Unpack64()) } -// UInt represents a key -type UInt struct { +// Uint is a [label.Key] for unsigned integers. +type Uint struct { name string description string } -// NewUInt creates a new Key for uint values. -func NewUInt(name, description string) *UInt { - return &UInt{name: name, description: description} +// NewUint creates a new [label.Key] for unsigned values. +func NewUint(name, description string) *Uint { + return &Uint{name: name, description: description} } -func (k *UInt) Name() string { return k.name } -func (k *UInt) Description() string { return k.description } +func (k *Uint) Name() string { return k.name } +func (k *Uint) Description() string { return k.description } -func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +func (k *Uint) Append(buf []byte, l label.Label) []byte { + return strconv.AppendUint(buf, k.From(l), 10) } // Of creates a new Label with this key and the supplied value. -func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) } +func (k *Uint) Of(v uint64) label.Label { return label.Of64(k, v) } -// Get can be used to get a label for the key from a label.Map. -func (k *UInt) Get(lm label.Map) uint { +// Get returns the label for the key of a label.Map. +func (k *Uint) Get(lm label.Map) uint64 { if t := lm.Find(k); t.Valid() { return k.From(t) } return 0 } -// From can be used to get a value from a Label. -func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) } +// From returns the value of a Label. +func (k *Uint) From(t label.Label) uint64 { return t.Unpack64() } -// UInt8 represents a key -type UInt8 struct { +// Float is a label.Key for floating-point values. +type Float struct { name string description string } -// NewUInt8 creates a new Key for uint8 values. -func NewUInt8(name, description string) *UInt8 { - return &UInt8{name: name, description: description} +// NewFloat creates a new [label.Key] for floating-point values. +func NewFloat(name, description string) *Float { + return &Float{name: name, description: description} } -func (k *UInt8) Name() string { return k.name } -func (k *UInt8) Description() string { return k.description } +func (k *Float) Name() string { return k.name } +func (k *Float) Description() string { return k.description } -func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) +func (k *Float) Append(buf []byte, l label.Label) []byte { + return strconv.AppendFloat(buf, k.From(l), 'E', -1, 64) } // Of creates a new Label with this key and the supplied value. -func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt8) Get(lm label.Map) uint8 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) } - -// UInt16 represents a key -type UInt16 struct { - name string - description string -} - -// NewUInt16 creates a new Key for uint16 values. -func NewUInt16(name, description string) *UInt16 { - return &UInt16{name: name, description: description} -} - -func (k *UInt16) Name() string { return k.name } -func (k *UInt16) Description() string { return k.description } - -func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt16) Get(lm label.Map) uint16 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) } - -// UInt32 represents a key -type UInt32 struct { - name string - description string -} - -// NewUInt32 creates a new Key for uint32 values. -func NewUInt32(name, description string) *UInt32 { - return &UInt32{name: name, description: description} -} - -func (k *UInt32) Name() string { return k.name } -func (k *UInt32) Description() string { return k.description } - -func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt32) Get(lm label.Map) uint32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) } - -// UInt64 represents a key -type UInt64 struct { - name string - description string -} - -// NewUInt64 creates a new Key for uint64 values. -func NewUInt64(name, description string) *UInt64 { - return &UInt64{name: name, description: description} -} - -func (k *UInt64) Name() string { return k.name } -func (k *UInt64) Description() string { return k.description } - -func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendUint(buf, k.From(l), 10)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) } - -// Get can be used to get a label for the key from a label.Map. -func (k *UInt64) Get(lm label.Map) uint64 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() } - -// Float32 represents a key -type Float32 struct { - name string - description string -} - -// NewFloat32 creates a new Key for float32 values. -func NewFloat32(name, description string) *Float32 { - return &Float32{name: name, description: description} -} - -func (k *Float32) Name() string { return k.name } -func (k *Float32) Description() string { return k.description } - -func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Float32) Of(v float32) label.Label { - return label.Of64(k, uint64(math.Float32bits(v))) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Float32) Get(lm label.Map) float32 { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return 0 -} - -// From can be used to get a value from a Label. -func (k *Float32) From(t label.Label) float32 { - return math.Float32frombits(uint32(t.Unpack64())) -} - -// Float64 represents a key -type Float64 struct { - name string - description string -} - -// NewFloat64 creates a new Key for int64 values. -func NewFloat64(name, description string) *Float64 { - return &Float64{name: name, description: description} -} - -func (k *Float64) Name() string { return k.name } -func (k *Float64) Description() string { return k.description } - -func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64)) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Float64) Of(v float64) label.Label { +func (k *Float) Of(v float64) label.Label { return label.Of64(k, math.Float64bits(v)) } -// Get can be used to get a label for the key from a label.Map. -func (k *Float64) Get(lm label.Map) float64 { +// Get returns the label for the key of a label.Map. +func (k *Float) Get(lm label.Map) float64 { if t := lm.Find(k); t.Valid() { return k.From(t) } return 0 } -// From can be used to get a value from a Label. -func (k *Float64) From(t label.Label) float64 { +// From returns the value of a Label. +func (k *Float) From(t label.Label) float64 { return math.Float64frombits(t.Unpack64()) } @@ -473,14 +183,14 @@ func NewString(name, description string) *String { func (k *String) Name() string { return k.name } func (k *String) Description() string { return k.description } -func (k *String) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendQuote(buf, k.From(l))) +func (k *String) Append(buf []byte, l label.Label) []byte { + return strconv.AppendQuote(buf, k.From(l)) } // Of creates a new Label with this key and the supplied value. func (k *String) Of(v string) label.Label { return label.OfString(k, v) } -// Get can be used to get a label for the key from a label.Map. +// Get returns the label for the key of a label.Map. func (k *String) Get(lm label.Map) string { if t := lm.Find(k); t.Valid() { return k.From(t) @@ -488,53 +198,16 @@ func (k *String) Get(lm label.Map) string { return "" } -// From can be used to get a value from a Label. +// From returns the value of a Label. func (k *String) From(t label.Label) string { return t.UnpackString() } -// Boolean represents a key -type Boolean struct { - name string - description string -} - -// NewBoolean creates a new Key for bool values. -func NewBoolean(name, description string) *Boolean { - return &Boolean{name: name, description: description} -} - -func (k *Boolean) Name() string { return k.name } -func (k *Boolean) Description() string { return k.description } - -func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) { - w.Write(strconv.AppendBool(buf, k.From(l))) -} - -// Of creates a new Label with this key and the supplied value. -func (k *Boolean) Of(v bool) label.Label { - if v { - return label.Of64(k, 1) - } - return label.Of64(k, 0) -} - -// Get can be used to get a label for the key from a label.Map. -func (k *Boolean) Get(lm label.Map) bool { - if t := lm.Find(k); t.Valid() { - return k.From(t) - } - return false -} - -// From can be used to get a value from a Label. -func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 } - // Error represents a key type Error struct { name string description string } -// NewError creates a new Key for int64 values. +// NewError returns a new [label.Key] for error values. func NewError(name, description string) *Error { return &Error{name: name, description: description} } @@ -542,14 +215,14 @@ func NewError(name, description string) *Error { func (k *Error) Name() string { return k.name } func (k *Error) Description() string { return k.description } -func (k *Error) Format(w io.Writer, buf []byte, l label.Label) { - io.WriteString(w, k.From(l).Error()) +func (k *Error) Append(buf []byte, l label.Label) []byte { + return append(buf, k.From(l).Error()...) } -// Of creates a new Label with this key and the supplied value. +// Of returns a new Label with this key and the supplied value. func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) } -// Get can be used to get a label for the key from a label.Map. +// Get returns the label for the key of a label.Map. func (k *Error) Get(lm label.Map) error { if t := lm.Find(k); t.Valid() { return k.From(t) @@ -557,7 +230,7 @@ func (k *Error) Get(lm label.Map) error { return nil } -// From can be used to get a value from a Label. +// From returns the value of a Label. func (k *Error) From(t label.Label) error { err, _ := t.UnpackValue().(error) return err diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go index c37584af9..e84226f87 100644 --- a/vendor/golang.org/x/tools/internal/event/label/label.go +++ b/vendor/golang.org/x/tools/internal/event/label/label.go @@ -19,12 +19,8 @@ type Key interface { Name() string // Description returns a string that can be used to describe the value. Description() string - - // Format is used in formatting to append the value of the label to the - // supplied buffer. - // The formatter may use the supplied buf as a scratch area to avoid - // allocations. - Format(w io.Writer, buf []byte, l Label) + // Append appends the formatted value of the label to the supplied buffer. + Append(buf []byte, l Label) []byte } // Label holds a key and value pair. @@ -131,8 +127,7 @@ func (t Label) Format(f fmt.State, r rune) { } io.WriteString(f, t.Key().Name()) io.WriteString(f, "=") - var buf [128]byte - t.Key().Format(f, buf[:0], t) + f.Write(t.Key().Append(nil, t)) // ignore error } func (l *list) Valid(index int) bool { diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go index 2bef2b058..4c9450f4e 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go @@ -242,7 +242,6 @@ import ( "strings" "golang.org/x/tools/go/types/objectpath" - "golang.org/x/tools/internal/aliases" ) // IExportShallow encodes "shallow" export data for the specified package. @@ -767,11 +766,11 @@ func (p *iexporter) doDecl(obj types.Object) { } if obj.IsAlias() { - alias, materialized := t.(*types.Alias) // may fail when aliases are not enabled + alias, materialized := t.(*types.Alias) // perhaps false for certain built-ins? var tparams *types.TypeParamList if materialized { - tparams = aliases.TypeParams(alias) + tparams = alias.TypeParams() } if tparams.Len() == 0 { w.tag(aliasTag) @@ -785,7 +784,7 @@ func (p *iexporter) doDecl(obj types.Object) { if materialized { // Preserve materialized aliases, // even of non-exported types. - t = aliases.Rhs(alias) + t = alias.Rhs() } w.typ(t, obj.Pkg()) break @@ -1011,11 +1010,11 @@ func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) { } switch t := t.(type) { case *types.Alias: - if targs := aliases.TypeArgs(t); targs.Len() > 0 { + if targs := t.TypeArgs(); targs.Len() > 0 { w.startType(instanceType) w.pos(t.Obj().Pos()) w.typeList(targs, pkg) - w.typ(aliases.Origin(t), pkg) + w.typ(t.Origin(), pkg) return } w.startType(aliasType) diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go index 4d6d50094..1ee4e9354 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go @@ -210,7 +210,6 @@ func iimportCommon(fset *token.FileSet, getPackages GetPackagesFunc, data []byte p := iimporter{ version: int(version), ipath: path, - aliases: aliases.Enabled(), shallow: shallow, reportf: reportf, @@ -370,7 +369,6 @@ type iimporter struct { version int ipath string - aliases bool shallow bool reportf ReportFunc // if non-nil, used to report bugs @@ -576,7 +574,7 @@ func (r *importReader) obj(pkg *types.Package, name string) { tparams = r.tparamList() } typ := r.typ() - obj := aliases.NewAlias(r.p.aliases, pos, pkg, name, typ, tparams) + obj := aliases.New(pos, pkg, name, typ, tparams) markBlack(obj) // workaround for golang/go#69912 r.declare(obj) diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader.go similarity index 88% rename from vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go rename to vendor/golang.org/x/tools/internal/gcimporter/ureader.go index 37b4a39e9..3db62b890 100644 --- a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go +++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader.go @@ -26,7 +26,6 @@ type pkgReader struct { ctxt *types.Context imports map[string]*types.Package // previously imported packages, indexed by path - aliases bool // create types.Alias nodes // lazily initialized arrays corresponding to the unified IR // PosBase, Pkg, and Type sections, respectively. @@ -36,6 +35,10 @@ type pkgReader struct { // laterFns holds functions that need to be invoked at the end of // import reading. + // + // TODO(mdempsky): Is it safe to have a single "later" slice or do + // we need to have multiple passes? See comments on CL 386002 and + // go.dev/issue/52104. laterFns []func() // laterFors is used in case of 'type A B' to ensure that B is processed before A. laterFors map[types.Type]int @@ -98,7 +101,6 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st ctxt: ctxt, imports: imports, - aliases: aliases.Enabled(), posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), @@ -160,12 +162,11 @@ type reader struct { // A readerDict holds the state for type parameters that parameterize // the current unified IR element. type readerDict struct { - // bounds is a slice of typeInfos corresponding to the underlying - // bounds of the element's type parameters. - bounds []typeInfo + rtbounds []typeInfo // contains constraint types for each parameter in rtparams + rtparams []*types.TypeParam // contains receiver type parameters for an element - // tparams is a slice of the constructed TypeParams for the element. - tparams []*types.TypeParam + tbounds []typeInfo // contains constraint types for each parameter in tparams + tparams []*types.TypeParam // contains type parameters for an element // derived is a slice of types derived from tparams, which may be // instantiated while reading the current element. @@ -355,7 +356,11 @@ func (r *reader) doTyp() (res types.Type) { return name.Type() case pkgbits.TypeTypeParam: - return r.dict.tparams[r.Len()] + n := r.Len() + if n < len(r.dict.rtbounds) { + return r.dict.rtparams[n] + } + return r.dict.tparams[n-len(r.dict.rtbounds)] case pkgbits.TypeArray: len := int64(r.Uint64()) @@ -536,10 +541,10 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { pos := r.pos() var tparams []*types.TypeParam if r.Version().Has(pkgbits.AliasTypeParamNames) { - tparams = r.typeParamNames() + tparams = r.typeParamNames(false) } typ := r.typ() - declare(aliases.NewAlias(r.p.aliases, pos, objPkg, objName, typ, tparams)) + declare(aliases.New(pos, objPkg, objName, typ, tparams)) case pkgbits.ObjConst: pos := r.pos() @@ -549,8 +554,15 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { case pkgbits.ObjFunc: pos := r.pos() - tparams := r.typeParamNames() - sig := r.signature(nil, nil, tparams) + var rtparams []*types.TypeParam + var recv *types.Var + if r.Version().Has(pkgbits.GenericMethods) && r.Bool() { + r.selector() + rtparams = r.typeParamNames(true) + recv = r.param() + } + tparams := r.typeParamNames(false) + sig := r.signature(recv, rtparams, tparams) declare(types.NewFunc(pos, objPkg, objName, sig)) case pkgbits.ObjType: @@ -560,7 +572,7 @@ func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { named := types.NewNamed(obj, nil, nil) declare(obj) - named.SetTypeParams(r.typeParamNames()) + named.SetTypeParams(r.typeParamNames(false)) setUnderlying := func(underlying types.Type) { // If the underlying type is an interface, we need to @@ -640,9 +652,20 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { errorf("unexpected object with %v implicit type parameter(s)", implicits) } - dict.bounds = make([]typeInfo, r.Len()) - for i := range dict.bounds { - dict.bounds[i] = r.typInfo() + nreceivers := 0 + if r.Version().Has(pkgbits.GenericMethods) && r.Bool() { + nreceivers = r.Len() + } + nexplicits := r.Len() + + dict.rtbounds = make([]typeInfo, nreceivers) + for i := range dict.rtbounds { + dict.rtbounds[i] = r.typInfo() + } + + dict.tbounds = make([]typeInfo, nexplicits) + for i := range dict.tbounds { + dict.tbounds[i] = r.typInfo() } dict.derived = make([]derivedInfo, r.Len()) @@ -661,15 +684,24 @@ func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { return &dict } -func (r *reader) typeParamNames() []*types.TypeParam { +func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam { r.Sync(pkgbits.SyncTypeParamNames) - // Note: This code assumes it only processes objects without - // implement type parameters. This is currently fine, because - // reader is only used to read in exported declarations, which are - // always package scoped. + // Note: This code assumes there are no implicit type parameters. + // This is fine since it only reads exported declarations, which + // never have implicits. - if len(r.dict.bounds) == 0 { + var in []typeInfo + var out *[]*types.TypeParam + if isGenMeth { + in = r.dict.rtbounds + out = &r.dict.rtparams + } else { + in = r.dict.tbounds + out = &r.dict.tparams + } + + if len(in) == 0 { return nil } @@ -678,40 +710,34 @@ func (r *reader) typeParamNames() []*types.TypeParam { // create all the TypeNames and TypeParams, then we construct and // set the bound type. - r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds)) - for i := range r.dict.bounds { + // We have to save tparams outside of the closure, because typeParamNames + // can be called multiple times with the same dictionary instance. + tparams := make([]*types.TypeParam, len(in)) + *out = tparams + + for i := range in { pos := r.pos() pkg, name := r.localIdent() tname := types.NewTypeName(pos, pkg, name, nil) - r.dict.tparams[i] = types.NewTypeParam(tname, nil) + tparams[i] = types.NewTypeParam(tname, nil) } - typs := make([]types.Type, len(r.dict.bounds)) - for i, bound := range r.dict.bounds { - typs[i] = r.p.typIdx(bound, r.dict) + // The reader dictionary will continue mutating before we have time + // to call delayed functions; make a local copy of the constraints. + types := make([]types.Type, len(in)) + for i, info := range in { + types[i] = r.p.typIdx(info, r.dict) } - // TODO(mdempsky): This is subtle, elaborate further. - // - // We have to save tparams outside of the closure, because - // typeParamNames() can be called multiple times with the same - // dictionary instance. - // - // Also, this needs to happen later to make sure SetUnderlying has - // been called. - // - // TODO(mdempsky): Is it safe to have a single "later" slice or do - // we need to have multiple passes? See comments on CL 386002 and - // go.dev/issue/52104. - tparams := r.dict.tparams + // This needs to happen later to make sure SetUnderlying has been called. r.p.later(func() { - for i, typ := range typs { + for i, typ := range types { tparams[i].SetConstraint(typ) } }) - return r.dict.tparams + return tparams } func (r *reader) method() *types.Func { @@ -719,7 +745,7 @@ func (r *reader) method() *types.Func { pos := r.pos() pkg, name := r.selector() - rparams := r.typeParamNames() + rparams := r.typeParamNames(false) sig := r.signature(r.param(), rparams, nil) _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go index 446c5846a..cce290c41 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/version.go +++ b/vendor/golang.org/x/tools/internal/gocommand/version.go @@ -26,6 +26,9 @@ func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { inv.BuildFlags = nil // This is not a build command. inv.ModFlag = "" inv.ModFile = "" + // Set GO111MODULE=off so that we are immune to errors in go.{work,mod}. + // Unfortunately, this breaks the Go 1.21+ toolchain directive and + // may affect the set of ReleaseTags; see #68495. inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off") stdoutBytes, err := r.Run(ctx, inv) diff --git a/vendor/golang.org/x/tools/internal/pkgbits/version.go b/vendor/golang.org/x/tools/internal/pkgbits/version.go index 53af9df22..0db965274 100644 --- a/vendor/golang.org/x/tools/internal/pkgbits/version.go +++ b/vendor/golang.org/x/tools/internal/pkgbits/version.go @@ -28,6 +28,15 @@ const ( // - remove derived info "needed" bool V2 + // V3: introduces a more compact format for composite literal element lists + // - negative lengths indicate that (some) elements may have keys + // - positive lengths indicate that no element has a key + // - a negative struct field index indicates an embedded field + V3 + + // V4: encodes generic methods as standalone function objects + V4 + numVersions = iota ) @@ -61,6 +70,12 @@ const ( // whether a type was a derived type. DerivedInfoNeeded + // Composite literals use a more compact format for element lists. + CompactCompLiterals + + // Generic methods may appear as standalone function objects. + GenericMethods + numFields = iota ) @@ -68,6 +83,8 @@ const ( var introduced = [numFields]Version{ Flags: V1, AliasTypeParamNames: V2, + CompactCompLiterals: V3, + GenericMethods: V4, } // removed is the version a field was removed in or 0 for fields diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go index f41431c94..dacfc1dff 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/deps.go +++ b/vendor/golang.org/x/tools/internal/stdlib/deps.go @@ -307,7 +307,7 @@ var deps = [...]pkginfo{ {"net/textproto", "\x02\x01q\x03\x83\x01\f\n-\x01\x02\x15"}, {"net/url", "t\x03Fc\v\x10\x02\x01\x17"}, {"os", "t+\x01\x19\x03\x10\x14\x01\x03\x01\x05\x10\x018\b\x05\x01\x01\r\x06"}, - {"os/exec", "\x03\ngI'\x01\x15\x01+\x06\a\n\x01\x04\r"}, + {"os/exec", "\x03\ngI'\x01\x15\x01+\x06\a\n\x01\x03\x01\r"}, {"os/exec/internal/fdtest", "\xc2\x02"}, {"os/signal", "\r\x99\x02\x15\x05\x02"}, {"os/user", "\x02\x01q\x03\x83\x01,\r\n\x01\x02"}, diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go index 27a2b1792..2e05de464 100644 --- a/vendor/golang.org/x/tools/internal/typeparams/coretype.go +++ b/vendor/golang.org/x/tools/internal/typeparams/coretype.go @@ -11,7 +11,9 @@ import ( // CoreType returns the core type of T or nil if T does not have a core type. // -// See https://go.dev/ref/spec#Core_types for the definition of a core type. +// As of Go1.25, the notion of a core type has been removed from the language spec. +// See https://go.dev/blog/coretypes for more details. +// TODO(mkalil): We should eventually consider removing all uses of CoreType. func CoreType(T types.Type) types.Type { U := T.Underlying() if _, ok := U.(*types.Interface); !ok { @@ -34,7 +36,7 @@ func CoreType(T types.Type) types.Type { } if identical == len(terms) { - // https://go.dev/ref/spec#Core_types + // From the deprecated core types spec: // "There is a single type U which is the underlying type of all types in the type set of T" return U } @@ -42,7 +44,7 @@ func CoreType(T types.Type) types.Type { if !ok { return nil // no core type as identical < len(terms) and U is not a channel. } - // https://go.dev/ref/spec#Core_types + // From the deprecated core types spec: // "the type chan E if T contains only bidirectional channels, or the type chan<- E or // <-chan E depending on the direction of the directional channels present." for chans := identical; chans < len(terms); chans++ { diff --git a/vendor/golang.org/x/tools/internal/typeparams/free.go b/vendor/golang.org/x/tools/internal/typeparams/free.go index 709d2fc14..4c391876e 100644 --- a/vendor/golang.org/x/tools/internal/typeparams/free.go +++ b/vendor/golang.org/x/tools/internal/typeparams/free.go @@ -6,8 +6,6 @@ package typeparams import ( "go/types" - - "golang.org/x/tools/internal/aliases" ) // Free is a memoization of the set of free type parameters within a @@ -38,7 +36,7 @@ func (w *Free) Has(typ types.Type) (res bool) { break case *types.Alias: - if aliases.TypeParams(t).Len() > aliases.TypeArgs(t).Len() { + if t.TypeParams().Len() > t.TypeArgs().Len() { return true // This is an uninstantiated Alias. } // The expansion of an alias can have free type parameters, diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go index 51001666e..6582cc81f 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -25,7 +25,6 @@ import ( "reflect" "golang.org/x/tools/go/ast/inspector" - "golang.org/x/tools/internal/aliases" ) func SetUsesCgo(conf *types.Config) bool { @@ -142,7 +141,7 @@ var ( func Origin(t NamedOrAlias) NamedOrAlias { switch t := t.(type) { case *types.Alias: - return aliases.Origin(t) + return t.Origin() case *types.Named: return t.Origin() } @@ -195,3 +194,51 @@ func Imports(pkg *types.Package, path string) bool { } return false } + +// ObjectKind returns a description of the object's kind. +// +// from objectKind in go/types +func ObjectKind(obj types.Object) string { + switch obj := obj.(type) { + case *types.PkgName: + return "package name" + case *types.Const: + return "constant" + case *types.TypeName: + if obj.IsAlias() { + return "type alias" + } else if _, ok := obj.Type().(*types.TypeParam); ok { + return "type parameter" + } else { + return "defined type" + } + case *types.Var: + switch obj.Kind() { + case PackageVar: + return "package-level variable" + case LocalVar: + return "local variable" + case RecvVar: + return "receiver" + case ParamVar: + return "parameter" + case ResultVar: + return "result variable" + case FieldVar: + return "struct field" + } + case *types.Func: + if obj.Signature().Recv() != nil { + return "method" + } else { + return "function" + } + case *types.Label: + return "label" + case *types.Builtin: + return "built-in function" + case *types.Nil: + return "untyped nil" + } + return "unknown symbol" +} diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go index cdd36c388..360a5b552 100644 --- a/vendor/golang.org/x/tools/internal/versions/features.go +++ b/vendor/golang.org/x/tools/internal/versions/features.go @@ -19,6 +19,7 @@ const ( Go1_24 = "go1.24" Go1_25 = "go1.25" Go1_26 = "go1.26" + Go1_27 = "go1.27" ) // Future is an invalid unknown Go version sometime in the future. diff --git a/vendor/modules.txt b/vendor/modules.txt index 3f3a456bc..17cf09239 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -15,7 +15,7 @@ github.com/Microsoft/go-winio/internal/socket github.com/Microsoft/go-winio/internal/stringbuffer github.com/Microsoft/go-winio/pkg/guid github.com/Microsoft/go-winio/vhd -# github.com/Microsoft/hcsshim v0.14.0 +# github.com/Microsoft/hcsshim v0.14.1 ## explicit; go 1.23.0 github.com/Microsoft/hcsshim github.com/Microsoft/hcsshim/computestorage @@ -49,7 +49,7 @@ github.com/Microsoft/hcsshim/osversion # github.com/alexflint/go-filemutex v1.3.0 ## explicit; go 1.13 github.com/alexflint/go-filemutex -# github.com/buger/jsonparser v1.1.2 +# github.com/buger/jsonparser v1.2.0 ## explicit; go 1.13 github.com/buger/jsonparser # github.com/containerd/cgroups/v3 v3.0.5 @@ -122,7 +122,7 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 +# github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 ## explicit; go 1.24.0 github.com/google/pprof/profile # github.com/insomniacslk/dhcp v0.0.0-20240829085014-a3a4c1f04475 @@ -135,7 +135,7 @@ github.com/insomniacslk/dhcp/rfc1035label # github.com/josharian/native v1.1.0 ## explicit; go 1.13 github.com/josharian/native -# github.com/mattn/go-shellwords v1.0.12 +# github.com/mattn/go-shellwords v1.0.13 ## explicit; go 1.13 github.com/mattn/go-shellwords # github.com/mdlayher/packet v1.1.2 @@ -150,8 +150,8 @@ github.com/networkplumbing/go-nft/nft github.com/networkplumbing/go-nft/nft/config github.com/networkplumbing/go-nft/nft/exec github.com/networkplumbing/go-nft/nft/schema -# github.com/onsi/ginkgo/v2 v2.28.1 -## explicit; go 1.24.0 +# github.com/onsi/ginkgo/v2 v2.29.0 +## explicit; go 1.25.0 github.com/onsi/ginkgo/v2 github.com/onsi/ginkgo/v2/config github.com/onsi/ginkgo/v2/formatter @@ -174,7 +174,7 @@ github.com/onsi/ginkgo/v2/internal/reporters github.com/onsi/ginkgo/v2/internal/testingtproxy github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/types -# github.com/onsi/gomega v1.39.1 +# github.com/onsi/gomega v1.40.0 ## explicit; go 1.24.0 github.com/onsi/gomega github.com/onsi/gomega/format @@ -189,8 +189,8 @@ github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node github.com/onsi/gomega/matchers/support/goraph/util github.com/onsi/gomega/types -# github.com/opencontainers/selinux v1.13.1 -## explicit; go 1.19 +# github.com/opencontainers/selinux v1.15.0 +## explicit; go 1.22 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/pkg/pwalkdir # github.com/pierrec/lz4/v4 v4.1.21 @@ -230,25 +230,25 @@ go.opencensus.io/trace/tracestate # go.yaml.in/yaml/v3 v3.0.4 ## explicit; go 1.16 go.yaml.in/yaml/v3 -# golang.org/x/mod v0.32.0 -## explicit; go 1.24.0 +# golang.org/x/mod v0.35.0 +## explicit; go 1.25.0 golang.org/x/mod/semver -# golang.org/x/net v0.49.0 -## explicit; go 1.24.0 +# golang.org/x/net v0.53.0 +## explicit; go 1.25.0 golang.org/x/net/bpf golang.org/x/net/html golang.org/x/net/html/atom golang.org/x/net/html/charset -# golang.org/x/sync v0.19.0 -## explicit; go 1.24.0 +# golang.org/x/sync v0.20.0 +## explicit; go 1.25.0 golang.org/x/sync/errgroup -# golang.org/x/sys v0.42.0 +# golang.org/x/sys v0.43.0 ## explicit; go 1.25.0 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/text v0.33.0 -## explicit; go 1.24.0 +# golang.org/x/text v0.36.0 +## explicit; go 1.25.0 golang.org/x/text/encoding golang.org/x/text/encoding/charmap golang.org/x/text/encoding/htmlindex @@ -266,8 +266,8 @@ golang.org/x/text/internal/utf8internal golang.org/x/text/language golang.org/x/text/runes golang.org/x/text/transform -# golang.org/x/tools v0.41.0 -## explicit; go 1.24.0 +# golang.org/x/tools v0.44.0 +## explicit; go 1.25.0 golang.org/x/tools/cover golang.org/x/tools/go/ast/edge golang.org/x/tools/go/ast/inspector