Update continuity, go-winio and hcsshim

Update dependencies and remove the local bindfilter files. Those have
been moved to go-winio.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2023-02-28 10:58:50 -08:00
parent 00efd3e6d8
commit db32798592
32 changed files with 581 additions and 400 deletions

8
go.mod
View File

@ -5,13 +5,13 @@ go 1.19
require ( require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652
github.com/Microsoft/go-winio v0.6.0 github.com/Microsoft/go-winio v0.6.1-0.20230228163719-dd5de6900b62
github.com/Microsoft/hcsshim v0.10.0-rc.7 github.com/Microsoft/hcsshim v0.10.0-rc.7
github.com/container-orchestrated-devices/container-device-interface v0.5.4 github.com/container-orchestrated-devices/container-device-interface v0.5.4
github.com/containerd/btrfs/v2 v2.0.0 github.com/containerd/btrfs/v2 v2.0.0
github.com/containerd/cgroups/v3 v3.0.1 github.com/containerd/cgroups/v3 v3.0.1
github.com/containerd/console v1.0.3 github.com/containerd/console v1.0.3
github.com/containerd/continuity v0.3.0 github.com/containerd/continuity v0.3.1-0.20230206102841-68f7b34f5e11
github.com/containerd/fifo v1.1.0 github.com/containerd/fifo v1.1.0
github.com/containerd/go-cni v1.1.9 github.com/containerd/go-cni v1.1.9
github.com/containerd/go-runc v1.0.0 github.com/containerd/go-runc v1.0.0
@ -125,13 +125,13 @@ require (
go.opentelemetry.io/otel/metric v0.37.0 // indirect go.opentelemetry.io/otel/metric v0.37.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect
golang.org/x/crypto v0.1.0 // indirect golang.org/x/crypto v0.1.0 // indirect
golang.org/x/mod v0.7.0 // indirect golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/term v0.5.0 // indirect golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
golang.org/x/tools v0.5.0 // indirect golang.org/x/tools v0.6.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect

16
go.sum
View File

@ -75,8 +75,8 @@ github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JP
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.1-0.20230228163719-dd5de6900b62 h1:PNDnNt0QOfCBd3bmdl9bhAt4+/PRCZpthE3PL0CMMtI=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/go-winio v0.6.1-0.20230228163719-dd5de6900b62/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
@ -232,8 +232,8 @@ github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.1-0.20230206102841-68f7b34f5e11 h1:NKxa3JMWvOvsU7ZgHwd9CZupl/692lPy/MBcumAAHsI=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/continuity v0.3.1-0.20230206102841-68f7b34f5e11/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
@ -1115,8 +1115,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1405,8 +1405,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -22,9 +22,10 @@ require (
golang.org/x/sys v0.6.0 golang.org/x/sys v0.6.0
) )
require github.com/Microsoft/go-winio v0.6.1-0.20230228163719-dd5de6900b62
require ( require (
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/cilium/ebpf v0.9.1 // indirect github.com/cilium/ebpf v0.9.1 // indirect
github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/cgroups v1.1.0 // indirect
github.com/containerd/console v1.0.3 // indirect github.com/containerd/console v1.0.3 // indirect
@ -55,11 +56,11 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect
golang.org/x/mod v0.7.0 // indirect golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.7.0 // indirect golang.org/x/net v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sync v0.1.0 // indirect
golang.org/x/text v0.7.0 // indirect golang.org/x/text v0.7.0 // indirect
golang.org/x/tools v0.5.0 // indirect golang.org/x/tools v0.6.0 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.53.0 // indirect google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect

View File

@ -538,8 +538,9 @@ github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JP
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/Microsoft/go-winio v0.6.1-0.20230228163719-dd5de6900b62 h1:PNDnNt0QOfCBd3bmdl9bhAt4+/PRCZpthE3PL0CMMtI=
github.com/Microsoft/go-winio v0.6.1-0.20230228163719-dd5de6900b62/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
@ -652,8 +653,9 @@ github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8a
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/continuity v0.3.1-0.20230206102841-68f7b34f5e11 h1:NKxa3JMWvOvsU7ZgHwd9CZupl/692lPy/MBcumAAHsI=
github.com/containerd/continuity v0.3.1-0.20230206102841-68f7b34f5e11/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=
github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
@ -1521,8 +1523,9 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1878,8 +1881,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -16,6 +16,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package client package client
import ( import (

View File

@ -23,8 +23,11 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"github.com/Microsoft/go-winio/pkg/bindfilter"
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
"golang.org/x/sys/windows"
) )
const sourceStreamName = "containerd.io-source" const sourceStreamName = "containerd.io-source"
@ -45,7 +48,7 @@ func (m *Mount) mount(target string) error {
} }
if m.Type == "bind" { if m.Type == "bind" {
if err := ApplyFileBinding(target, m.Source, readOnly); err != nil { if err := bindfilter.ApplyFileBinding(target, m.Source, readOnly); err != nil {
return fmt.Errorf("failed to bind-mount to %s: %w", target, err) return fmt.Errorf("failed to bind-mount to %s: %w", target, err)
} }
return nil return nil
@ -89,12 +92,12 @@ func (m *Mount) mount(target string) error {
return fmt.Errorf("failed to get volume path for layer %s: %w", m.Source, err) return fmt.Errorf("failed to get volume path for layer %s: %w", m.Source, err)
} }
if err = ApplyFileBinding(target, volume, readOnly); err != nil { if err = bindfilter.ApplyFileBinding(target, volume, readOnly); err != nil {
return fmt.Errorf("failed to set volume mount path for layer %s: %w", m.Source, err) return fmt.Errorf("failed to set volume mount path for layer %s: %w", m.Source, err)
} }
defer func() { defer func() {
if err != nil { if err != nil {
RemoveFileBinding(target) bindfilter.RemoveFileBinding(target)
} }
}() }()
@ -128,29 +131,7 @@ func (m *Mount) GetParentPaths() ([]string, error) {
// Unmount the mount at the provided path // Unmount the mount at the provided path
func Unmount(mount string, flags int) error { func Unmount(mount string, flags int) error {
var err error
mount = filepath.Clean(mount) mount = filepath.Clean(mount)
// This should expand paths like ADMINI~1 and PROGRA~1 to long names.
mount, err = getFinalPath(mount)
if err != nil {
return fmt.Errorf("fetching real path: %w", err)
}
mounts, err := GetBindMappings(mount)
if err != nil {
return fmt.Errorf("fetching bind mappings: %w", err)
}
found := false
for _, mnt := range mounts {
if mnt.MountPoint == mount {
found = true
break
}
}
if !found {
// not a mount point
return nil
}
adsFile := mount + ":" + sourceStreamName adsFile := mount + ":" + sourceStreamName
var layerPath string var layerPath string
@ -162,7 +143,11 @@ func Unmount(mount string, flags int) error {
layerPath = string(layerPathb) layerPath = string(layerPathb)
} }
if err := RemoveFileBinding(mount); err != nil { if err := bindfilter.RemoveFileBinding(mount); err != nil {
if errno, ok := errors.Unwrap(err).(syscall.Errno); ok && errno == windows.ERROR_INVALID_PARAMETER {
// not a mount point
return nil
}
return fmt.Errorf("removing mount: %w", err) return fmt.Errorf("removing mount: %w", err)
} }

View File

@ -1,75 +0,0 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mount
// Simple wrappers around SetVolumeMountPoint and DeleteVolumeMountPoint
import (
"fmt"
"path/filepath"
"strings"
"syscall"
"github.com/containerd/containerd/errdefs"
"golang.org/x/sys/windows"
)
// Mount volumePath (in format '\\?\Volume{GUID}' at targetPath.
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setvolumemountpointw
func setVolumeMountPoint(targetPath string, volumePath string) error {
if !strings.HasPrefix(volumePath, "\\\\?\\Volume{") {
return fmt.Errorf("unable to mount non-volume path %s: %w", volumePath, errdefs.ErrInvalidArgument)
}
// Both must end in a backslash
slashedTarget := filepath.Clean(targetPath) + string(filepath.Separator)
slashedVolume := volumePath + string(filepath.Separator)
targetP, err := syscall.UTF16PtrFromString(slashedTarget)
if err != nil {
return fmt.Errorf("unable to utf16-ise %s: %w", slashedTarget, err)
}
volumeP, err := syscall.UTF16PtrFromString(slashedVolume)
if err != nil {
return fmt.Errorf("unable to utf16-ise %s: %w", slashedVolume, err)
}
if err := windows.SetVolumeMountPoint(targetP, volumeP); err != nil {
return fmt.Errorf("failed calling SetVolumeMount('%s', '%s'): %w", slashedTarget, slashedVolume, err)
}
return nil
}
// Remove the volume mount at targetPath
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-deletevolumemountpointa
func deleteVolumeMountPoint(targetPath string) error {
// Must end in a backslash
slashedTarget := filepath.Clean(targetPath) + string(filepath.Separator)
targetP, err := syscall.UTF16PtrFromString(slashedTarget)
if err != nil {
return fmt.Errorf("unable to utf16-ise %s: %w", slashedTarget, err)
}
if err := windows.DeleteVolumeMountPoint(targetP); err != nil {
return fmt.Errorf("failed calling DeleteVolumeMountPoint('%s'): %w", slashedTarget, err)
}
return nil
}

View File

@ -8,12 +8,8 @@ linters:
- containedctx # struct contains a context - containedctx # struct contains a context
- dupl # duplicate code - dupl # duplicate code
- errname # erorrs are named correctly - errname # erorrs are named correctly
- goconst # strings that should be constants
- godot # comments end in a period
- misspell
- nolintlint # "//nolint" directives are properly explained - nolintlint # "//nolint" directives are properly explained
- revive # golint replacement - revive # golint replacement
- stylecheck # golint replacement, less configurable than revive
- unconvert # unnecessary conversions - unconvert # unnecessary conversions
- wastedassign - wastedassign
@ -23,10 +19,7 @@ linters:
- exhaustive # check exhaustiveness of enum switch statements - exhaustive # check exhaustiveness of enum switch statements
- gofmt # files are gofmt'ed - gofmt # files are gofmt'ed
- gosec # security - gosec # security
- nestif # deeply nested ifs
- nilerr # returns nil even with non-nil error - nilerr # returns nil even with non-nil error
- prealloc # slices that can be pre-allocated
- structcheck # unused struct fields
- unparam # unused function params - unparam # unused function params
issues: issues:
@ -56,6 +49,8 @@ issues:
linters-settings: linters-settings:
exhaustive:
default-signifies-exhaustive: true
govet: govet:
enable-all: true enable-all: true
disable: disable:
@ -98,6 +93,8 @@ linters-settings:
disabled: true disabled: true
- name: flag-parameter # excessive, and a common idiom we use - name: flag-parameter # excessive, and a common idiom we use
disabled: true disabled: true
- name: unhandled-error # warns over common fmt.Print* and io.Close; rely on errcheck instead
disabled: true
# general config # general config
- name: line-length-limit - name: line-length-limit
arguments: arguments:
@ -138,7 +135,3 @@ linters-settings:
- VPCI - VPCI
- WCOW - WCOW
- WIM - WIM
stylecheck:
checks:
- "all"
- "-ST1003" # use revive's var naming

View File

@ -1,4 +1,7 @@
package mount //go:build windows
// +build windows
package bindfilter
import ( import (
"bytes" "bytes"
@ -9,43 +12,28 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"syscall" "syscall"
"unicode/utf16"
"unsafe" "unsafe"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
) )
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./*.go //go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./bind_filter.go
//sys BfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath *uint16, virtTargetPath *uint16, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) = bindfltapi.BfSetupFilter? //sys bfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath string, virtTargetPath string, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) = bindfltapi.BfSetupFilter?
//sys BfRemoveMapping(jobHandle windows.Handle, virtRootPath *uint16) (hr error) = bindfltapi.BfRemoveMapping? //sys bfRemoveMapping(jobHandle windows.Handle, virtRootPath string) (hr error) = bindfltapi.BfRemoveMapping?
//sys BfGetMappings(flags uint32, jobHandle windows.Handle, virtRootPath *uint16, sid *windows.SID, bufferSize *uint32, outBuffer uintptr) (hr error) = bindfltapi.BfGetMappings? //sys bfGetMappings(flags uint32, jobHandle windows.Handle, virtRootPath *uint16, sid *windows.SID, bufferSize *uint32, outBuffer *byte) (hr error) = bindfltapi.BfGetMappings?
// BfSetupFilter flags. See: // BfSetupFilter flags. See:
// https://github.com/microsoft/BuildXL/blob/a6dce509f0d4f774255e5fbfb75fa6d5290ed163/Public/Src/Utilities/Native/Processes/Windows/NativeContainerUtilities.cs#L193-L240 // https://github.com/microsoft/BuildXL/blob/a6dce509f0d4f774255e5fbfb75fa6d5290ed163/Public/Src/Utilities/Native/Processes/Windows/NativeContainerUtilities.cs#L193-L240
//
//nolint:revive // var-naming: ALL_CAPS
const ( const (
BINDFLT_FLAG_READ_ONLY_MAPPING uint32 = 0x00000001 BINDFLT_FLAG_READ_ONLY_MAPPING uint32 = 0x00000001
// Generates a merged binding, mapping target entries to the virtualization root.
BINDFLT_FLAG_MERGED_BIND_MAPPING uint32 = 0x00000002
// Use the binding mapping attached to the mapped-in job object (silo) instead of the default global mapping.
BINDFLT_FLAG_USE_CURRENT_SILO_MAPPING uint32 = 0x00000004
BINDFLT_FLAG_REPARSE_ON_FILES uint32 = 0x00000008
// Skips checks on file/dir creation inside a non-merged, read-only mapping.
// Only usable when READ_ONLY_MAPPING is set.
BINDFLT_FLAG_SKIP_SHARING_CHECK uint32 = 0x00000010
BINDFLT_FLAG_CLOUD_FILES_ECPS uint32 = 0x00000020
// Tells bindflt to fail mapping with STATUS_INVALID_PARAMETER if a mapping produces // Tells bindflt to fail mapping with STATUS_INVALID_PARAMETER if a mapping produces
// multiple targets. // multiple targets.
BINDFLT_FLAG_NO_MULTIPLE_TARGETS uint32 = 0x00000040 BINDFLT_FLAG_NO_MULTIPLE_TARGETS uint32 = 0x00000040
// Turns on caching by asserting that the backing store for name mappings is immutable.
BINDFLT_FLAG_IMMUTABLE_BACKING uint32 = 0x00000080
BINDFLT_FLAG_PREVENT_CASE_SENSITIVE_BINDING uint32 = 0x00000100
// Tells bindflt to fail with STATUS_OBJECT_PATH_NOT_FOUND when a mapping is being added
// but its parent paths (ancestors) have not already been added.
BINDFLT_FLAG_EMPTY_VIRT_ROOT uint32 = 0x00000200
BINDFLT_FLAG_NO_REPARSE_ON_ROOT uint32 = 0x10000000
BINDFLT_FLAG_BATCHED_REMOVE_MAPPINGS uint32 = 0x20000000
) )
//nolint:revive // var-naming: ALL_CAPS
const ( const (
BINDFLT_GET_MAPPINGS_FLAG_VOLUME uint32 = 0x00000001 BINDFLT_GET_MAPPINGS_FLAG_VOLUME uint32 = 0x00000001
BINDFLT_GET_MAPPINGS_FLAG_SILO uint32 = 0x00000002 BINDFLT_GET_MAPPINGS_FLAG_SILO uint32 = 0x00000002
@ -73,26 +61,17 @@ func ApplyFileBinding(root, source string, readOnly bool) error {
source = source + "\\" source = source + "\\"
} }
rootPtr, err := windows.UTF16PtrFromString(root)
if err != nil {
return err
}
targetPtr, err := windows.UTF16PtrFromString(source)
if err != nil {
return err
}
flags := BINDFLT_FLAG_NO_MULTIPLE_TARGETS flags := BINDFLT_FLAG_NO_MULTIPLE_TARGETS
if readOnly { if readOnly {
flags |= BINDFLT_FLAG_READ_ONLY_MAPPING flags |= BINDFLT_FLAG_READ_ONLY_MAPPING
} }
// Set the job handle to 0 to create a global mount. // Set the job handle to 0 to create a global mount.
if err := BfSetupFilter( if err := bfSetupFilter(
0, 0,
flags, flags,
rootPtr, root,
targetPtr, source,
nil, nil,
0, 0,
); err != nil { ); err != nil {
@ -101,18 +80,70 @@ func ApplyFileBinding(root, source string, readOnly bool) error {
return nil return nil
} }
// RemoveFileBinding removes a mount from the root path.
func RemoveFileBinding(root string) error { func RemoveFileBinding(root string) error {
rootPtr, err := windows.UTF16PtrFromString(root) if err := bfRemoveMapping(0, root); err != nil {
if err != nil {
return fmt.Errorf("converting path to utf-16: %w", err)
}
if err := BfRemoveMapping(0, rootPtr); err != nil {
return fmt.Errorf("removing file binding: %w", err) return fmt.Errorf("removing file binding: %w", err)
} }
return nil return nil
} }
// GetBindMappings returns a list of bind mappings that have their root on a
// particular volume. The volumePath parameter can be any path that exists on
// a volume. For example, if a number of mappings are created in C:\ProgramData\test,
// to get a list of those mappings, the volumePath parameter would have to be set to
// C:\ or the VOLUME_NAME_GUID notation of C:\ (\\?\Volume{GUID}\), or any child
// path that exists.
func GetBindMappings(volumePath string) ([]BindMapping, error) {
rootPtr, err := windows.UTF16PtrFromString(volumePath)
if err != nil {
return nil, err
}
flags := BINDFLT_GET_MAPPINGS_FLAG_VOLUME
// allocate a large buffer for results
var outBuffSize uint32 = 256 * 1024
buf := make([]byte, outBuffSize)
if err := bfGetMappings(flags, 0, rootPtr, nil, &outBuffSize, &buf[0]); err != nil {
return nil, err
}
if outBuffSize < 12 {
return nil, fmt.Errorf("invalid buffer returned")
}
result := buf[:outBuffSize]
// The first 12 bytes are the three uint32 fields in getMappingsResponseHeader{}
headerBuffer := result[:12]
// The alternative to using unsafe and casting it to the above defined structures, is to manually
// parse the fields. Not too terrible, but not sure it'd worth the trouble.
header := *(*getMappingsResponseHeader)(unsafe.Pointer(&headerBuffer[0]))
if header.MappingCount == 0 {
// no mappings
return []BindMapping{}, nil
}
mappingsBuffer := result[12 : int(unsafe.Sizeof(mappingEntry{}))*int(header.MappingCount)]
// Get a pointer to the first mapping in the slice
mappingsPointer := (*mappingEntry)(unsafe.Pointer(&mappingsBuffer[0]))
// Get slice of mappings
mappings := unsafe.Slice(mappingsPointer, header.MappingCount)
mappingEntries := make([]BindMapping, header.MappingCount)
for i := 0; i < int(header.MappingCount); i++ {
bindMapping, err := getBindMappingFromBuffer(result, mappings[i])
if err != nil {
return nil, fmt.Errorf("fetching bind mappings: %w", err)
}
mappingEntries[i] = bindMapping
}
return mappingEntries, nil
}
// mappingEntry holds information about where in the response buffer we can // mappingEntry holds information about where in the response buffer we can
// find information about the virtual root (the mount point) and the targets (sources) // find information about the virtual root (the mount point) and the targets (sources)
// that get mounted, as well as the flags used to bind the targets to the virtual root. // that get mounted, as well as the flags used to bind the targets to the virtual root.
@ -150,7 +181,7 @@ func decodeEntry(buffer []byte) (string, error) {
if err != nil { if err != nil {
return "", fmt.Errorf("decoding name: %w", err) return "", fmt.Errorf("decoding name: %w", err)
} }
return string(utf16.Decode(name)), nil return windows.UTF16ToString(name), nil
} }
func getTargetsFromBuffer(buffer []byte, offset, count int) ([]string, error) { func getTargetsFromBuffer(buffer []byte, offset, count int) ([]string, error) {
@ -165,7 +196,7 @@ func getTargetsFromBuffer(buffer []byte, offset, count int) ([]string, error) {
if len(buffer) < int(tgt.TargetRootOffset)+int(tgt.TargetRootLength) { if len(buffer) < int(tgt.TargetRootOffset)+int(tgt.TargetRootLength) {
return nil, fmt.Errorf("invalid buffer") return nil, fmt.Errorf("invalid buffer")
} }
decoded, err := decodeEntry(buffer[tgt.TargetRootOffset : uint32(tgt.TargetRootOffset)+uint32(tgt.TargetRootLength)]) decoded, err := decodeEntry(buffer[tgt.TargetRootOffset : tgt.TargetRootOffset+tgt.TargetRootLength])
if err != nil { if err != nil {
return nil, fmt.Errorf("decoding name: %w", err) return nil, fmt.Errorf("decoding name: %w", err)
} }
@ -187,15 +218,18 @@ func getFinalPath(pth string) (string, error) {
pth = `\\.\GLOBALROOT` + pth pth = `\\.\GLOBALROOT` + pth
} }
han, err := getFileHandle(pth) han, err := openPath(pth)
if err != nil { if err != nil {
return "", fmt.Errorf("fetching file handle: %w", err) return "", fmt.Errorf("fetching file handle: %w", err)
} }
defer func() {
_ = windows.CloseHandle(han)
}()
buf := make([]uint16, 100) buf := make([]uint16, 100)
var flags uint32 = 0x0 var flags uint32 = 0x0
for { for {
n, err := windows.GetFinalPathNameByHandle(windows.Handle(han), &buf[0], uint32(len(buf)), flags) n, err := windows.GetFinalPathNameByHandle(han, &buf[0], uint32(len(buf)), flags)
if err != nil { if err != nil {
// if we mounted a volume that does not also have a drive letter assigned, attempting to // if we mounted a volume that does not also have a drive letter assigned, attempting to
// fetch the VOLUME_NAME_DOS will fail with os.ErrNotExist. Attempt to get the VOLUME_NAME_GUID. // fetch the VOLUME_NAME_DOS will fail with os.ErrNotExist. Attempt to get the VOLUME_NAME_GUID.
@ -229,7 +263,7 @@ func getBindMappingFromBuffer(buffer []byte, entry mappingEntry) (BindMapping, e
return BindMapping{}, fmt.Errorf("invalid buffer") return BindMapping{}, fmt.Errorf("invalid buffer")
} }
src, err := decodeEntry(buffer[entry.VirtRootOffset : entry.VirtRootOffset+uint32(entry.VirtRootLength)]) src, err := decodeEntry(buffer[entry.VirtRootOffset : entry.VirtRootOffset+entry.VirtRootLength])
if err != nil { if err != nil {
return BindMapping{}, fmt.Errorf("decoding entry: %w", err) return BindMapping{}, fmt.Errorf("decoding entry: %w", err)
} }
@ -250,78 +284,25 @@ func getBindMappingFromBuffer(buffer []byte, entry mappingEntry) (BindMapping, e
}, nil }, nil
} }
func getFileHandle(pth string) (syscall.Handle, error) { func openPath(path string) (windows.Handle, error) {
info, err := os.Lstat(pth) u16, err := windows.UTF16PtrFromString(path)
if err != nil {
return 0, fmt.Errorf("accessing file: %w", err)
}
p, err := syscall.UTF16PtrFromString(pth)
if err != nil { if err != nil {
return 0, err return 0, err
} }
attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS) h, err := windows.CreateFile(
if info.Mode()&os.ModeSymlink != 0 { u16,
attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT 0,
} windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE|windows.FILE_SHARE_DELETE,
h, err := syscall.CreateFile(p, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0) nil,
windows.OPEN_EXISTING,
windows.FILE_FLAG_BACKUP_SEMANTICS, // Needed to open a directory handle.
0)
if err != nil { if err != nil {
return 0, err return 0, &os.PathError{
Op: "CreateFile",
Path: path,
Err: err,
}
} }
return h, nil return h, nil
} }
// GetBindMappings returns a list of bind mappings that have their root on a
// particular volume. The volumePath parameter can be any path that exists on
// a volume. For example, if a number of mappings are created in C:\ProgramData\test,
// to get a list of those mappings, the volumePath parameter would have to be set to
// C:\ or the VOLUME_NAME_GUID notation of C:\ (\\?\Volume{GUID}\), or any child
// path that exists.
func GetBindMappings(volumePath string) ([]BindMapping, error) {
rootPtr, err := windows.UTF16PtrFromString(volumePath)
if err != nil {
return nil, err
}
var flags uint32 = BINDFLT_GET_MAPPINGS_FLAG_VOLUME
// allocate a large buffer for results
var outBuffSize uint32 = 256 * 1024
buf := make([]byte, outBuffSize)
if err := BfGetMappings(flags, 0, rootPtr, nil, &outBuffSize, uintptr(unsafe.Pointer(&buf[0]))); err != nil {
return nil, err
}
if outBuffSize < 12 {
return nil, fmt.Errorf("invalid buffer returned")
}
result := buf[:outBuffSize]
// The first 12 bytes are the three uint32 fields in getMappingsResponseHeader{}
headerBuffer := result[:12]
// The alternative to using unsafe and casting it to the above defined structures, is to manually
// parse the fields. Not too terrible, but not sure it'd worth the trouble.
header := *(*getMappingsResponseHeader)(unsafe.Pointer(&headerBuffer[0]))
if header.MappingCount == 0 {
// no mappings
return []BindMapping{}, nil
}
mappingsBuffer := result[12 : int(unsafe.Sizeof(mappingEntry{}))*int(header.MappingCount)]
// Get a pointer to the first mapping in the slice
mappingsPointer := (*mappingEntry)(unsafe.Pointer(&mappingsBuffer[0]))
// Get slice of mappings
mappings := unsafe.Slice(mappingsPointer, header.MappingCount)
mappingEntries := make([]BindMapping, header.MappingCount)
for i := 0; i < int(header.MappingCount); i++ {
bindMapping, err := getBindMappingFromBuffer(result, mappings[i])
if err != nil {
return nil, fmt.Errorf("fetching bind mappings: %w", err)
}
mappingEntries[i] = bindMapping
}
return mappingEntries, nil
}

View File

@ -2,7 +2,7 @@
// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT. // Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT.
package mount package bindfilter
import ( import (
"syscall" "syscall"
@ -47,12 +47,12 @@ var (
procBfSetupFilter = modbindfltapi.NewProc("BfSetupFilter") procBfSetupFilter = modbindfltapi.NewProc("BfSetupFilter")
) )
func BfGetMappings(flags uint32, jobHandle windows.Handle, virtRootPath *uint16, sid *windows.SID, bufferSize *uint32, outBuffer uintptr) (hr error) { func bfGetMappings(flags uint32, jobHandle windows.Handle, virtRootPath *uint16, sid *windows.SID, bufferSize *uint32, outBuffer *byte) (hr error) {
hr = procBfGetMappings.Find() hr = procBfGetMappings.Find()
if hr != nil { if hr != nil {
return return
} }
r0, _, _ := syscall.Syscall6(procBfGetMappings.Addr(), 6, uintptr(flags), uintptr(jobHandle), uintptr(unsafe.Pointer(virtRootPath)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(bufferSize)), uintptr(outBuffer)) r0, _, _ := syscall.Syscall6(procBfGetMappings.Addr(), 6, uintptr(flags), uintptr(jobHandle), uintptr(unsafe.Pointer(virtRootPath)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(bufferSize)), uintptr(unsafe.Pointer(outBuffer)))
if int32(r0) < 0 { if int32(r0) < 0 {
if r0&0x1fff0000 == 0x00070000 { if r0&0x1fff0000 == 0x00070000 {
r0 &= 0xffff r0 &= 0xffff
@ -62,7 +62,16 @@ func BfGetMappings(flags uint32, jobHandle windows.Handle, virtRootPath *uint16,
return return
} }
func BfRemoveMapping(jobHandle windows.Handle, virtRootPath *uint16) (hr error) { func bfRemoveMapping(jobHandle windows.Handle, virtRootPath string) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(virtRootPath)
if hr != nil {
return
}
return _bfRemoveMapping(jobHandle, _p0)
}
func _bfRemoveMapping(jobHandle windows.Handle, virtRootPath *uint16) (hr error) {
hr = procBfRemoveMapping.Find() hr = procBfRemoveMapping.Find()
if hr != nil { if hr != nil {
return return
@ -77,7 +86,21 @@ func BfRemoveMapping(jobHandle windows.Handle, virtRootPath *uint16) (hr error)
return return
} }
func BfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath *uint16, virtTargetPath *uint16, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) { func bfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath string, virtTargetPath string, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) {
var _p0 *uint16
_p0, hr = syscall.UTF16PtrFromString(virtRootPath)
if hr != nil {
return
}
var _p1 *uint16
_p1, hr = syscall.UTF16PtrFromString(virtTargetPath)
if hr != nil {
return
}
return _bfSetupFilter(jobHandle, flags, _p0, _p1, virtExceptions, virtExceptionPathCount)
}
func _bfSetupFilter(jobHandle windows.Handle, flags uint32, virtRootPath *uint16, virtTargetPath *uint16, virtExceptions **uint16, virtExceptionPathCount uint32) (hr error) {
hr = procBfSetupFilter.Find() hr = procBfSetupFilter.Find()
if hr != nil { if hr != nil {
return return

View File

@ -1,7 +1,5 @@
linters: linters:
enable: enable:
- structcheck
- varcheck
- staticcheck - staticcheck
- unconvert - unconvert
- gofmt - gofmt

View File

@ -18,6 +18,7 @@ package continuity
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -151,7 +152,7 @@ func (c *context) Resource(p string, fi os.FileInfo) (Resource, error) {
} }
base.xattrs, err = c.resolveXAttrs(fp, fi, base) base.xattrs, err = c.resolveXAttrs(fp, fi, base)
if err != nil && err != ErrNotSupported { if err != nil && !errors.Is(err, ErrNotSupported) {
return nil, err return nil, err
} }
@ -410,7 +411,7 @@ func (c *context) Apply(resource Resource) error {
return fmt.Errorf("resource %v escapes root", resource) return fmt.Errorf("resource %v escapes root", resource)
} }
var chmod = true chmod := true
fi, err := c.driver.Lstat(fp) fi, err := c.driver.Lstat(fp)
if err != nil { if err != nil {
if !os.IsNotExist(err) { if !os.IsNotExist(err) {

View File

@ -56,7 +56,7 @@ func WriteFile(r Driver, filename string, data []byte, perm os.FileMode) error {
return nil return nil
} }
// ReadDir works the same as ioutil.ReadDir with the Driver abstraction // ReadDir works the same as os.ReadDir with the Driver abstraction
func ReadDir(r Driver, dirname string) ([]os.FileInfo, error) { func ReadDir(r Driver, dirname string) ([]os.FileInfo, error) {
f, err := r.Open(dirname) f, err := r.Open(dirname)
if err != nil { if err != nil {

View File

@ -18,7 +18,6 @@ package fs
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
@ -111,7 +110,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
} }
} }
fis, err := ioutil.ReadDir(src) entries, err := os.ReadDir(src)
if err != nil { if err != nil {
return fmt.Errorf("failed to read %s: %w", src, err) return fmt.Errorf("failed to read %s: %w", src, err)
} }
@ -124,18 +123,23 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
return fmt.Errorf("failed to copy xattrs: %w", err) return fmt.Errorf("failed to copy xattrs: %w", err)
} }
for _, fi := range fis { for _, entry := range entries {
source := filepath.Join(src, fi.Name()) source := filepath.Join(src, entry.Name())
target := filepath.Join(dst, fi.Name()) target := filepath.Join(dst, entry.Name())
fileInfo, err := entry.Info()
if err != nil {
return fmt.Errorf("failed to get file info for %s: %w", entry.Name(), err)
}
switch { switch {
case fi.IsDir(): case entry.IsDir():
if err := copyDirectory(target, source, inodes, o); err != nil { if err := copyDirectory(target, source, inodes, o); err != nil {
return err return err
} }
continue continue
case (fi.Mode() & os.ModeType) == 0: case (fileInfo.Mode() & os.ModeType) == 0:
link, err := getLinkSource(target, fi, inodes) link, err := getLinkSource(target, fileInfo, inodes)
if err != nil { if err != nil {
return fmt.Errorf("failed to get hardlink: %w", err) return fmt.Errorf("failed to get hardlink: %w", err)
} }
@ -146,7 +150,7 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
} else if err := CopyFile(target, source); err != nil { } else if err := CopyFile(target, source); err != nil {
return fmt.Errorf("failed to copy files: %w", err) return fmt.Errorf("failed to copy files: %w", err)
} }
case (fi.Mode() & os.ModeSymlink) == os.ModeSymlink: case (fileInfo.Mode() & os.ModeSymlink) == os.ModeSymlink:
link, err := os.Readlink(source) link, err := os.Readlink(source)
if err != nil { if err != nil {
return fmt.Errorf("failed to read link: %s: %w", source, err) return fmt.Errorf("failed to read link: %s: %w", source, err)
@ -154,18 +158,18 @@ func copyDirectory(dst, src string, inodes map[uint64]string, o *copyDirOpts) er
if err := os.Symlink(link, target); err != nil { if err := os.Symlink(link, target); err != nil {
return fmt.Errorf("failed to create symlink: %s: %w", target, err) return fmt.Errorf("failed to create symlink: %s: %w", target, err)
} }
case (fi.Mode() & os.ModeDevice) == os.ModeDevice, case (fileInfo.Mode() & os.ModeDevice) == os.ModeDevice,
(fi.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe, (fileInfo.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe,
(fi.Mode() & os.ModeSocket) == os.ModeSocket: (fileInfo.Mode() & os.ModeSocket) == os.ModeSocket:
if err := copyIrregular(target, fi); err != nil { if err := copyIrregular(target, fileInfo); err != nil {
return fmt.Errorf("failed to create irregular file: %w", err) return fmt.Errorf("failed to create irregular file: %w", err)
} }
default: default:
logrus.Warnf("unsupported mode: %s: %s", source, fi.Mode()) logrus.Warnf("unsupported mode: %s: %s", source, fileInfo.Mode())
continue continue
} }
if err := copyFileInfo(fi, source, target); err != nil { if err := copyFileInfo(fileInfo, source, target); err != nil {
return fmt.Errorf("failed to copy file info: %w", err) return fmt.Errorf("failed to copy file info: %w", err)
} }

View File

@ -49,7 +49,6 @@ func copyFileInfo(fi os.FileInfo, src, name string) error {
secInfo, err := windows.GetNamedSecurityInfo( secInfo, err := windows.GetNamedSecurityInfo(
src, windows.SE_FILE_OBJECT, src, windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION) windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION)
if err != nil { if err != nil {
return err return err
} }
@ -68,7 +67,6 @@ func copyFileInfo(fi os.FileInfo, src, name string) error {
name, windows.SE_FILE_OBJECT, name, windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION,
sid, nil, dacl, nil); err != nil { sid, nil, dacl, nil); err != nil {
return err return err
} }
return nil return nil

View File

@ -80,6 +80,7 @@ type ChangeFunc func(ChangeKind, string, os.FileInfo, error) error
// //
// The change callback is called by the order of path names and // The change callback is called by the order of path names and
// should be appliable in that order. // should be appliable in that order.
//
// Due to this apply ordering, the following is true // Due to this apply ordering, the following is true
// - Removed directory trees only create a single change for the root // - Removed directory trees only create a single change for the root
// directory removed. Remaining changes are implied. // directory removed. Remaining changes are implied.

View File

@ -21,14 +21,13 @@ package fs
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"syscall" "syscall"
"unsafe" "unsafe"
) )
func locateDummyIfEmpty(path string) (string, error) { func locateDummyIfEmpty(path string) (string, error) {
children, err := ioutil.ReadDir(path) children, err := os.ReadDir(path)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -28,6 +28,7 @@ import (
// blocksUnitSize is the unit used by `st_blocks` in `stat` in bytes. // blocksUnitSize is the unit used by `st_blocks` in `stat` in bytes.
// See https://man7.org/linux/man-pages/man2/stat.2.html // See https://man7.org/linux/man-pages/man2/stat.2.html
//
// st_blocks // st_blocks
// This field indicates the number of blocks allocated to the // This field indicates the number of blocks allocated to the
// file, in 512-byte units. (This may be smaller than // file, in 512-byte units. (This may be smaller than
@ -48,7 +49,6 @@ func newInode(stat *syscall.Stat_t) inode {
} }
func diskUsage(ctx context.Context, roots ...string) (Usage, error) { func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
var ( var (
size int64 size int64
inodes = map[inode]struct{}{} // expensive! inodes = map[inode]struct{}{} // expensive!

View File

@ -26,9 +26,7 @@ import (
) )
func diskUsage(ctx context.Context, roots ...string) (Usage, error) { func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
var ( var size int64
size int64
)
// TODO(stevvooe): Support inodes (or equivalent) for windows. // TODO(stevvooe): Support inodes (or equivalent) for windows.
@ -57,9 +55,7 @@ func diskUsage(ctx context.Context, roots ...string) (Usage, error) {
} }
func diffUsage(ctx context.Context, a, b string) (Usage, error) { func diffUsage(ctx context.Context, a, b string) (Usage, error) {
var ( var size int64
size int64
)
if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error { if err := Changes(ctx, a, b, func(kind ChangeKind, _ string, fi os.FileInfo, err error) error {
if err != nil { if err != nil {

View File

@ -16,9 +16,15 @@
package fstest package fstest
// TODO: Any more metadata files generated by Windows layers?
// TODO: Also skip Recycle Bin contents in Windows layers which is used to store deleted files in some cases
var metadataFiles = map[string]bool{ var metadataFiles = map[string]bool{
"\\System Volume Information": true, "\\System Volume Information": true,
"\\WcSandboxState": true, "\\WcSandboxState": true,
"\\Windows": true,
"\\Windows\\System32": true,
"\\Windows\\System32\\config": true,
"\\Windows\\System32\\config\\DEFAULT": true,
"\\Windows\\System32\\config\\SAM": true,
"\\Windows\\System32\\config\\SECURITY": true,
"\\Windows\\System32\\config\\SOFTWARE": true,
"\\Windows\\System32\\config\\SYSTEM": true,
} }

View File

@ -129,7 +129,6 @@ func compareResource(r1, r2 continuity.Resource) bool {
// TODO(dmcgowan): Check if is XAttrer // TODO(dmcgowan): Check if is XAttrer
return compareResourceTypes(r1, r2) return compareResourceTypes(r1, r2)
} }
func compareResourceTypes(r1, r2 continuity.Resource) bool { func compareResourceTypes(r1, r2 continuity.Resource) bool {

View File

@ -32,13 +32,13 @@ func Lchtimes(name string, atime, mtime time.Time) Applier {
// that the filter will mount. It is used for testing the snapshotter // that the filter will mount. It is used for testing the snapshotter
func Base() Applier { func Base() Applier {
return Apply( return Apply(
CreateDir("Windows", 0755), CreateDir("Windows", 0o755),
CreateDir("Windows/System32", 0755), CreateDir("Windows/System32", 0o755),
CreateDir("Windows/System32/Config", 0755), CreateDir("Windows/System32/Config", 0o755),
CreateFile("Windows/System32/Config/SYSTEM", []byte("foo\n"), 0777), CreateFile("Windows/System32/Config/SYSTEM", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/SOFTWARE", []byte("foo\n"), 0777), CreateFile("Windows/System32/Config/SOFTWARE", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/SAM", []byte("foo\n"), 0777), CreateFile("Windows/System32/Config/SAM", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/SECURITY", []byte("foo\n"), 0777), CreateFile("Windows/System32/Config/SECURITY", []byte("foo\n"), 0o777),
CreateFile("Windows/System32/Config/DEFAULT", []byte("foo\n"), 0777), CreateFile("Windows/System32/Config/DEFAULT", []byte("foo\n"), 0o777),
) )
} }

View File

@ -81,14 +81,14 @@ var (
// baseApplier creates a basic filesystem layout // baseApplier creates a basic filesystem layout
// with multiple types of files for basic tests. // with multiple types of files for basic tests.
baseApplier = Apply( baseApplier = Apply(
CreateDir("/etc/", 0755), CreateDir("/etc/", 0o755),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0644), CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0o644),
Link("/etc/hosts", "/etc/hosts.allow"), Link("/etc/hosts", "/etc/hosts.allow"),
CreateDir("/usr/local/lib", 0755), CreateDir("/usr/local/lib", 0o755),
CreateFile("/usr/local/lib/libnothing.so", []byte{0x00, 0x00}, 0755), CreateFile("/usr/local/lib/libnothing.so", []byte{0x00, 0x00}, 0o755),
Symlink("libnothing.so", "/usr/local/lib/libnothing.so.2"), Symlink("libnothing.so", "/usr/local/lib/libnothing.so.2"),
CreateDir("/home", 0755), CreateDir("/home", 0o755),
CreateDir("/home/derek", 0700), CreateDir("/home/derek", 0o700),
// TODO: CreateSocket: how should Sockets be handled in continuity? // TODO: CreateSocket: how should Sockets be handled in continuity?
) )
@ -96,10 +96,10 @@ var (
basicTest = []Applier{ basicTest = []Applier{
baseApplier, baseApplier,
Apply( Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644), CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
CreateFile("/etc/fstab", []byte("/dev/sda1\t/\text4\tdefaults 1 1\n"), 0600), CreateFile("/etc/fstab", []byte("/dev/sda1\t/\text4\tdefaults 1 1\n"), 0o600),
CreateFile("/etc/badfile", []byte(""), 0666), CreateFile("/etc/badfile", []byte(""), 0o666),
CreateFile("/home/derek/.zshrc", []byte("#ZSH is just better\n"), 0640), CreateFile("/home/derek/.zshrc", []byte("#ZSH is just better\n"), 0o640),
), ),
Apply( Apply(
Remove("/etc/badfile"), Remove("/etc/badfile"),
@ -111,8 +111,8 @@ var (
), ),
Apply( Apply(
RemoveAll("/home"), RemoveAll("/home"),
CreateDir("/home/derek", 0700), CreateDir("/home/derek", 0o700),
CreateFile("/home/derek/.bashrc", []byte("#not going away\n"), 0640), CreateFile("/home/derek/.bashrc", []byte("#not going away\n"), 0o640),
Link("/etc/hosts", "/etc/hosts.allow"), Link("/etc/hosts", "/etc/hosts.allow"),
), ),
} }
@ -121,58 +121,58 @@ var (
// deletions are properly picked up and applied // deletions are properly picked up and applied
deletionTest = []Applier{ deletionTest = []Applier{
Apply( Apply(
CreateDir("/test/somedir", 0755), CreateDir("/test/somedir", 0o755),
CreateDir("/lib", 0700), CreateDir("/lib", 0o700),
CreateFile("/lib/hidden", []byte{}, 0644), CreateFile("/lib/hidden", []byte{}, 0o644),
), ),
Apply( Apply(
CreateFile("/test/a", []byte{}, 0644), CreateFile("/test/a", []byte{}, 0o644),
CreateFile("/test/b", []byte{}, 0644), CreateFile("/test/b", []byte{}, 0o644),
CreateDir("/test/otherdir", 0755), CreateDir("/test/otherdir", 0o755),
CreateFile("/test/otherdir/.empty", []byte{}, 0644), CreateFile("/test/otherdir/.empty", []byte{}, 0o644),
RemoveAll("/lib"), RemoveAll("/lib"),
CreateDir("/lib", 0700), CreateDir("/lib", 0o700),
CreateFile("/lib/not-hidden", []byte{}, 0644), CreateFile("/lib/not-hidden", []byte{}, 0o644),
), ),
Apply( Apply(
Remove("/test/a"), Remove("/test/a"),
Remove("/test/b"), Remove("/test/b"),
RemoveAll("/test/otherdir"), RemoveAll("/test/otherdir"),
CreateFile("/lib/newfile", []byte{}, 0644), CreateFile("/lib/newfile", []byte{}, 0o644),
), ),
} }
// updateTest covers file updates for content and permission // updateTest covers file updates for content and permission
updateTest = []Applier{ updateTest = []Applier{
Apply( Apply(
CreateDir("/d1", 0755), CreateDir("/d1", 0o755),
CreateDir("/d2", 0700), CreateDir("/d2", 0o700),
CreateFile("/d1/f1", []byte("something..."), 0644), CreateFile("/d1/f1", []byte("something..."), 0o644),
CreateFile("/d1/f2", []byte("else..."), 0644), CreateFile("/d1/f2", []byte("else..."), 0o644),
CreateFile("/d1/f3", []byte("entirely..."), 0644), CreateFile("/d1/f3", []byte("entirely..."), 0o644),
), ),
Apply( Apply(
CreateFile("/d1/f1", []byte("file content of a different length"), 0664), CreateFile("/d1/f1", []byte("file content of a different length"), 0o664),
Remove("/d1/f3"), Remove("/d1/f3"),
CreateFile("/d1/f3", []byte("updated content"), 0664), CreateFile("/d1/f3", []byte("updated content"), 0o664),
Chmod("/d1/f2", 0766), Chmod("/d1/f2", 0o766),
Chmod("/d2", 0777), Chmod("/d2", 0o777),
), ),
} }
// directoryPermissionsTest covers directory permissions on update // directoryPermissionsTest covers directory permissions on update
directoryPermissionsTest = []Applier{ directoryPermissionsTest = []Applier{
Apply( Apply(
CreateDir("/d1", 0700), CreateDir("/d1", 0o700),
CreateDir("/d2", 0751), CreateDir("/d2", 0o751),
CreateDir("/d3", 0777), CreateDir("/d3", 0o777),
), ),
Apply( Apply(
CreateFile("/d1/f", []byte("irrelevant"), 0644), CreateFile("/d1/f", []byte("irrelevant"), 0o644),
CreateDir("/d1/d", 0700), CreateDir("/d1/d", 0o700),
CreateFile("/d1/d/f", []byte("irrelevant"), 0644), CreateFile("/d1/d/f", []byte("irrelevant"), 0o644),
CreateFile("/d2/f", []byte("irrelevant"), 0644), CreateFile("/d2/f", []byte("irrelevant"), 0o644),
CreateFile("/d3/f", []byte("irrelevant"), 0644), CreateFile("/d3/f", []byte("irrelevant"), 0o644),
), ),
} }
@ -180,28 +180,28 @@ var (
// files // files
parentDirectoryPermissionsTest = []Applier{ parentDirectoryPermissionsTest = []Applier{
Apply( Apply(
CreateDir("/d1", 0700), CreateDir("/d1", 0o700),
CreateDir("/d1/a", 0700), CreateDir("/d1/a", 0o700),
CreateDir("/d1/a/b", 0700), CreateDir("/d1/a/b", 0o700),
CreateDir("/d1/a/b/c", 0700), CreateDir("/d1/a/b/c", 0o700),
CreateFile("/d1/a/b/f", []byte("content1"), 0644), CreateFile("/d1/a/b/f", []byte("content1"), 0o644),
CreateDir("/d2", 0751), CreateDir("/d2", 0o751),
CreateDir("/d2/a/b", 0751), CreateDir("/d2/a/b", 0o751),
CreateDir("/d2/a/b/c", 0751), CreateDir("/d2/a/b/c", 0o751),
CreateFile("/d2/a/b/f", []byte("content1"), 0644), CreateFile("/d2/a/b/f", []byte("content1"), 0o644),
), ),
Apply( Apply(
CreateFile("/d1/a/b/f", []byte("content1"), 0644), CreateFile("/d1/a/b/f", []byte("content1"), 0o644),
Chmod("/d1/a/b/c", 0700), Chmod("/d1/a/b/c", 0o700),
CreateFile("/d2/a/b/f", []byte("content2"), 0644), CreateFile("/d2/a/b/f", []byte("content2"), 0o644),
Chmod("/d2/a/b/c", 0751), Chmod("/d2/a/b/c", 0o751),
), ),
} }
hardlinkUnmodified = []Applier{ hardlinkUnmodified = []Applier{
baseApplier, baseApplier,
Apply( Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644), CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
), ),
Apply( Apply(
Link("/etc/hosts", "/etc/hosts.deny"), Link("/etc/hosts", "/etc/hosts.deny"),
@ -213,7 +213,7 @@ var (
hardlinkBeforeUnmodified = []Applier{ hardlinkBeforeUnmodified = []Applier{
baseApplier, baseApplier,
Apply( Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644), CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
), ),
Apply( Apply(
Link("/etc/hosts", "/etc/before-hosts"), Link("/etc/hosts", "/etc/before-hosts"),
@ -225,11 +225,11 @@ var (
hardlinkBeforeModified = []Applier{ hardlinkBeforeModified = []Applier{
baseApplier, baseApplier,
Apply( Apply(
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0644), CreateFile("/etc/hosts", []byte("127.0.0.1 localhost.localdomain"), 0o644),
), ),
Apply( Apply(
Remove("/etc/hosts"), Remove("/etc/hosts"),
CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0644), CreateFile("/etc/hosts", []byte("127.0.0.1 localhost"), 0o644),
Link("/etc/hosts", "/etc/before-hosts"), Link("/etc/hosts", "/etc/before-hosts"),
), ),
} }

View File

@ -25,9 +25,7 @@ import (
"path/filepath" "path/filepath"
) )
var ( var errTooManyLinks = errors.New("too many links")
errTooManyLinks = errors.New("too many links")
)
type currentPath struct { type currentPath struct {
path string path string

View File

@ -21,9 +21,7 @@ import (
"os" "os"
) )
var ( var errNotAHardLink = fmt.Errorf("invalid hardlink")
errNotAHardLink = fmt.Errorf("invalid hardlink")
)
type hardlinkManager struct { type hardlinkManager struct {
hardlinks map[hardlinkKey][]Resource hardlinks map[hardlinkKey][]Resource

View File

@ -878,12 +878,19 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
// never has to create a types.Package for an indirect dependency, // never has to create a types.Package for an indirect dependency,
// which would then require that such created packages be explicitly // which would then require that such created packages be explicitly
// inserted back into the Import graph as a final step after export data loading. // inserted back into the Import graph as a final step after export data loading.
// (Hence this return is after the Types assignment.)
// The Diamond test exercises this case. // The Diamond test exercises this case.
if !lpkg.needtypes && !lpkg.needsrc { if !lpkg.needtypes && !lpkg.needsrc {
return return
} }
if !lpkg.needsrc { if !lpkg.needsrc {
ld.loadFromExportData(lpkg) if err := ld.loadFromExportData(lpkg); err != nil {
lpkg.Errors = append(lpkg.Errors, Error{
Pos: "-",
Msg: err.Error(),
Kind: UnknownError, // e.g. can't find/open/parse export data
})
}
return // not a source package, don't get syntax trees return // not a source package, don't get syntax trees
} }
@ -970,7 +977,8 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
// The config requested loading sources and types, but sources are missing. // The config requested loading sources and types, but sources are missing.
// Add an error to the package and fall back to loading from export data. // Add an error to the package and fall back to loading from export data.
appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError})
ld.loadFromExportData(lpkg) _ = ld.loadFromExportData(lpkg) // ignore any secondary errors
return // can't get syntax trees for this package return // can't get syntax trees for this package
} }
@ -1194,9 +1202,10 @@ func sameFile(x, y string) bool {
return false return false
} }
// loadFromExportData returns type information for the specified // loadFromExportData ensures that type information is present for the specified
// package, loading it from an export data file on the first request. // package, loading it from an export data file on the first request.
func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error) { // On success it sets lpkg.Types to a new Package.
func (ld *loader) loadFromExportData(lpkg *loaderPackage) error {
if lpkg.PkgPath == "" { if lpkg.PkgPath == "" {
log.Fatalf("internal error: Package %s has no PkgPath", lpkg) log.Fatalf("internal error: Package %s has no PkgPath", lpkg)
} }
@ -1207,8 +1216,8 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
// must be sequential. (Finer-grained locking would require // must be sequential. (Finer-grained locking would require
// changes to the gcexportdata API.) // changes to the gcexportdata API.)
// //
// The exportMu lock guards the Package.Pkg field and the // The exportMu lock guards the lpkg.Types field and the
// types.Package it points to, for each Package in the graph. // types.Package it points to, for each loaderPackage in the graph.
// //
// Not all accesses to Package.Pkg need to be protected by exportMu: // Not all accesses to Package.Pkg need to be protected by exportMu:
// graph ordering ensures that direct dependencies of source // graph ordering ensures that direct dependencies of source
@ -1217,18 +1226,18 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
defer ld.exportMu.Unlock() defer ld.exportMu.Unlock()
if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() {
return tpkg, nil // cache hit return nil // cache hit
} }
lpkg.IllTyped = true // fail safe lpkg.IllTyped = true // fail safe
if lpkg.ExportFile == "" { if lpkg.ExportFile == "" {
// Errors while building export data will have been printed to stderr. // Errors while building export data will have been printed to stderr.
return nil, fmt.Errorf("no export data file") return fmt.Errorf("no export data file")
} }
f, err := os.Open(lpkg.ExportFile) f, err := os.Open(lpkg.ExportFile)
if err != nil { if err != nil {
return nil, err return err
} }
defer f.Close() defer f.Close()
@ -1240,7 +1249,7 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
// queries.) // queries.)
r, err := gcexportdata.NewReader(f) r, err := gcexportdata.NewReader(f)
if err != nil { if err != nil {
return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
} }
// Build the view. // Build the view.
@ -1284,7 +1293,7 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
// (May modify incomplete packages in view but not create new ones.) // (May modify incomplete packages in view but not create new ones.)
tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
} }
if _, ok := view["go.shape"]; ok { if _, ok := view["go.shape"]; ok {
// Account for the pseudopackage "go.shape" that gets // Account for the pseudopackage "go.shape" that gets
@ -1297,8 +1306,7 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
lpkg.Types = tpkg lpkg.Types = tpkg
lpkg.IllTyped = false lpkg.IllTyped = false
return nil
return tpkg, nil
} }
// impliedLoadMode returns loadMode with its dependencies. // impliedLoadMode returns loadMode with its dependencies.

View File

@ -22,6 +22,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"golang.org/x/tools/internal/tokeninternal"
"golang.org/x/tools/internal/typeparams" "golang.org/x/tools/internal/typeparams"
) )
@ -138,6 +139,17 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, ver
p.doDecl(p.declTodo.popHead()) p.doDecl(p.declTodo.popHead())
} }
// Produce index of offset of each file record in files.
var files intWriter
var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i
if p.shallow {
fileOffset = make([]uint64, len(p.fileInfos))
for i, info := range p.fileInfos {
fileOffset[i] = uint64(files.Len())
p.encodeFile(&files, info.file, info.needed)
}
}
// Append indices to data0 section. // Append indices to data0 section.
dataLen := uint64(p.data0.Len()) dataLen := uint64(p.data0.Len())
w := p.newWriter() w := p.newWriter()
@ -163,16 +175,75 @@ func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, ver
} }
hdr.uint64(uint64(p.version)) hdr.uint64(uint64(p.version))
hdr.uint64(uint64(p.strings.Len())) hdr.uint64(uint64(p.strings.Len()))
if p.shallow {
hdr.uint64(uint64(files.Len()))
hdr.uint64(uint64(len(fileOffset)))
for _, offset := range fileOffset {
hdr.uint64(offset)
}
}
hdr.uint64(dataLen) hdr.uint64(dataLen)
// Flush output. // Flush output.
io.Copy(out, &hdr) io.Copy(out, &hdr)
io.Copy(out, &p.strings) io.Copy(out, &p.strings)
if p.shallow {
io.Copy(out, &files)
}
io.Copy(out, &p.data0) io.Copy(out, &p.data0)
return nil return nil
} }
// encodeFile writes to w a representation of the file sufficient to
// faithfully restore position information about all needed offsets.
// Mutates the needed array.
func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) {
_ = needed[0] // precondition: needed is non-empty
w.uint64(p.stringOff(file.Name()))
size := uint64(file.Size())
w.uint64(size)
// Sort the set of needed offsets. Duplicates are harmless.
sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] })
lines := tokeninternal.GetLines(file) // byte offset of each line start
w.uint64(uint64(len(lines)))
// Rather than record the entire array of line start offsets,
// we save only a sparse list of (index, offset) pairs for
// the start of each line that contains a needed position.
var sparse [][2]int // (index, offset) pairs
outer:
for i, lineStart := range lines {
lineEnd := size
if i < len(lines)-1 {
lineEnd = uint64(lines[i+1])
}
// Does this line contains a needed offset?
if needed[0] < lineEnd {
sparse = append(sparse, [2]int{i, lineStart})
for needed[0] < lineEnd {
needed = needed[1:]
if len(needed) == 0 {
break outer
}
}
}
}
// Delta-encode the columns.
w.uint64(uint64(len(sparse)))
var prev [2]int
for _, pair := range sparse {
w.uint64(uint64(pair[0] - prev[0]))
w.uint64(uint64(pair[1] - prev[1]))
prev = pair
}
}
// writeIndex writes out an object index. mainIndex indicates whether // writeIndex writes out an object index. mainIndex indicates whether
// we're writing out the main index, which is also read by // we're writing out the main index, which is also read by
// non-compiler tools and includes a complete package description // non-compiler tools and includes a complete package description
@ -255,6 +326,12 @@ type iexporter struct {
strings intWriter strings intWriter
stringIndex map[string]uint64 stringIndex map[string]uint64
// In shallow mode, object positions are encoded as (file, offset).
// Each file is recorded as a line-number table.
// Only the lines of needed positions are saved faithfully.
fileInfo map[*token.File]uint64 // value is index in fileInfos
fileInfos []*filePositions
data0 intWriter data0 intWriter
declIndex map[types.Object]uint64 declIndex map[types.Object]uint64
tparamNames map[types.Object]string // typeparam->exported name tparamNames map[types.Object]string // typeparam->exported name
@ -263,6 +340,11 @@ type iexporter struct {
indent int // for tracing support indent int // for tracing support
} }
type filePositions struct {
file *token.File
needed []uint64 // unordered list of needed file offsets
}
func (p *iexporter) trace(format string, args ...interface{}) { func (p *iexporter) trace(format string, args ...interface{}) {
if !trace { if !trace {
// Call sites should also be guarded, but having this check here allows // Call sites should also be guarded, but having this check here allows
@ -286,6 +368,25 @@ func (p *iexporter) stringOff(s string) uint64 {
return off return off
} }
// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it.
func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) {
index, ok := p.fileInfo[file]
if !ok {
index = uint64(len(p.fileInfo))
p.fileInfos = append(p.fileInfos, &filePositions{file: file})
if p.fileInfo == nil {
p.fileInfo = make(map[*token.File]uint64)
}
p.fileInfo[file] = index
}
// Record each needed offset.
info := p.fileInfos[index]
offset := uint64(file.Offset(pos))
info.needed = append(info.needed, offset)
return index, offset
}
// pushDecl adds n to the declaration work queue, if not already present. // pushDecl adds n to the declaration work queue, if not already present.
func (p *iexporter) pushDecl(obj types.Object) { func (p *iexporter) pushDecl(obj types.Object) {
// Package unsafe is known to the compiler and predeclared. // Package unsafe is known to the compiler and predeclared.
@ -346,8 +447,14 @@ func (p *iexporter) doDecl(obj types.Object) {
case *types.Func: case *types.Func:
sig, _ := obj.Type().(*types.Signature) sig, _ := obj.Type().(*types.Signature)
if sig.Recv() != nil { if sig.Recv() != nil {
// We shouldn't see methods in the package scope,
// but the type checker may repair "func () F() {}"
// to "func (Invalid) F()" and then treat it like "func F()",
// so allow that. See golang/go#57729.
if sig.Recv().Type() != types.Typ[types.Invalid] {
panic(internalErrorf("unexpected method: %v", sig)) panic(internalErrorf("unexpected method: %v", sig))
} }
}
// Function. // Function.
if typeparams.ForSignature(sig).Len() == 0 { if typeparams.ForSignature(sig).Len() == 0 {
@ -458,13 +565,30 @@ func (w *exportWriter) tag(tag byte) {
} }
func (w *exportWriter) pos(pos token.Pos) { func (w *exportWriter) pos(pos token.Pos) {
if w.p.version >= iexportVersionPosCol { if w.p.shallow {
w.posV2(pos)
} else if w.p.version >= iexportVersionPosCol {
w.posV1(pos) w.posV1(pos)
} else { } else {
w.posV0(pos) w.posV0(pos)
} }
} }
// posV2 encoding (used only in shallow mode) records positions as
// (file, offset), where file is the index in the token.File table
// (which records the file name and newline offsets) and offset is a
// byte offset. It effectively ignores //line directives.
func (w *exportWriter) posV2(pos token.Pos) {
if pos == token.NoPos {
w.uint64(0)
return
}
file := w.p.fset.File(pos) // fset must be non-nil
index, offset := w.p.fileIndexAndOffset(file, pos)
w.uint64(1 + index)
w.uint64(offset)
}
func (w *exportWriter) posV1(pos token.Pos) { func (w *exportWriter) posV1(pos token.Pos) {
if w.p.fset == nil { if w.p.fset == nil {
w.int64(0) w.int64(0)

View File

@ -137,12 +137,23 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
} }
sLen := int64(r.uint64()) sLen := int64(r.uint64())
var fLen int64
var fileOffset []uint64
if insert != nil {
// Shallow mode uses a different position encoding.
fLen = int64(r.uint64())
fileOffset = make([]uint64, r.uint64())
for i := range fileOffset {
fileOffset[i] = r.uint64()
}
}
dLen := int64(r.uint64()) dLen := int64(r.uint64())
whence, _ := r.Seek(0, io.SeekCurrent) whence, _ := r.Seek(0, io.SeekCurrent)
stringData := data[whence : whence+sLen] stringData := data[whence : whence+sLen]
declData := data[whence+sLen : whence+sLen+dLen] fileData := data[whence+sLen : whence+sLen+fLen]
r.Seek(sLen+dLen, io.SeekCurrent) declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen]
r.Seek(sLen+fLen+dLen, io.SeekCurrent)
p := iimporter{ p := iimporter{
version: int(version), version: int(version),
@ -151,6 +162,9 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
stringData: stringData, stringData: stringData,
stringCache: make(map[uint64]string), stringCache: make(map[uint64]string),
fileOffset: fileOffset,
fileData: fileData,
fileCache: make([]*token.File, len(fileOffset)),
pkgCache: make(map[uint64]*types.Package), pkgCache: make(map[uint64]*types.Package),
declData: declData, declData: declData,
@ -280,6 +294,9 @@ type iimporter struct {
stringData []byte stringData []byte
stringCache map[uint64]string stringCache map[uint64]string
fileOffset []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i
fileData []byte
fileCache []*token.File // memoized decoding of file encoded as i
pkgCache map[uint64]*types.Package pkgCache map[uint64]*types.Package
declData []byte declData []byte
@ -352,6 +369,55 @@ func (p *iimporter) stringAt(off uint64) string {
return s return s
} }
func (p *iimporter) fileAt(index uint64) *token.File {
file := p.fileCache[index]
if file == nil {
off := p.fileOffset[index]
file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath})
p.fileCache[index] = file
}
return file
}
func (p *iimporter) decodeFile(rd intReader) *token.File {
filename := p.stringAt(rd.uint64())
size := int(rd.uint64())
file := p.fake.fset.AddFile(filename, -1, size)
// SetLines requires a nondecreasing sequence.
// Because it is common for clients to derive the interval
// [start, start+len(name)] from a start position, and we
// want to ensure that the end offset is on the same line,
// we fill in the gaps of the sparse encoding with values
// that strictly increase by the largest possible amount.
// This allows us to avoid having to record the actual end
// offset of each needed line.
lines := make([]int, int(rd.uint64()))
var index, offset int
for i, n := 0, int(rd.uint64()); i < n; i++ {
index += int(rd.uint64())
offset += int(rd.uint64())
lines[index] = offset
// Ensure monotonicity between points.
for j := index - 1; j > 0 && lines[j] == 0; j-- {
lines[j] = lines[j+1] - 1
}
}
// Ensure monotonicity after last point.
for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- {
size--
lines[j] = size
}
if !file.SetLines(lines) {
errorf("SetLines failed: %d", lines) // can't happen
}
return file
}
func (p *iimporter) pkgAt(off uint64) *types.Package { func (p *iimporter) pkgAt(off uint64) *types.Package {
if pkg, ok := p.pkgCache[off]; ok { if pkg, ok := p.pkgCache[off]; ok {
return pkg return pkg
@ -645,6 +711,9 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) {
} }
func (r *importReader) pos() token.Pos { func (r *importReader) pos() token.Pos {
if r.p.insert != nil { // shallow mode
return r.posv2()
}
if r.p.version >= iexportVersionPosCol { if r.p.version >= iexportVersionPosCol {
r.posv1() r.posv1()
} else { } else {
@ -681,6 +750,15 @@ func (r *importReader) posv1() {
} }
} }
func (r *importReader) posv2() token.Pos {
file := r.uint64()
if file == 0 {
return token.NoPos
}
tf := r.p.fileAt(file - 1)
return tf.Pos(int(r.uint64()))
}
func (r *importReader) typ() types.Type { func (r *importReader) typ() types.Type {
return r.p.typAt(r.uint64(), nil) return r.p.typAt(r.uint64(), nil)
} }

View File

@ -373,7 +373,7 @@ func (r *Decoder) Int64() int64 {
return r.rawVarint() return r.rawVarint()
} }
// Int64 decodes and returns a uint64 value from the element bitstream. // Uint64 decodes and returns a uint64 value from the element bitstream.
func (r *Decoder) Uint64() uint64 { func (r *Decoder) Uint64() uint64 {
r.Sync(SyncUint64) r.Sync(SyncUint64)
return r.rawUvarint() return r.rawUvarint()

View File

@ -293,7 +293,7 @@ func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) }
// Int encodes and writes an int value into the element bitstream. // Int encodes and writes an int value into the element bitstream.
func (w *Encoder) Int(x int) { w.Int64(int64(x)) } func (w *Encoder) Int(x int) { w.Int64(int64(x)) }
// Len encodes and writes a uint value into the element bitstream. // Uint encodes and writes a uint value into the element bitstream.
func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) }
// Reloc encodes and writes a relocation for the given (section, // Reloc encodes and writes a relocation for the given (section,

View File

@ -0,0 +1,59 @@
// Copyright 2023 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 tokeninternal provides access to some internal features of the token
// package.
package tokeninternal
import (
"go/token"
"sync"
"unsafe"
)
// GetLines returns the table of line-start offsets from a token.File.
func GetLines(file *token.File) []int {
// token.File has a Lines method on Go 1.21 and later.
if file, ok := (interface{})(file).(interface{ Lines() []int }); ok {
return file.Lines()
}
// This declaration must match that of token.File.
// This creates a risk of dependency skew.
// For now we check that the size of the two
// declarations is the same, on the (fragile) assumption
// that future changes would add fields.
type tokenFile119 struct {
_ string
_ int
_ int
mu sync.Mutex // we're not complete monsters
lines []int
_ []struct{}
}
type tokenFile118 struct {
_ *token.FileSet // deleted in go1.19
tokenFile119
}
type uP = unsafe.Pointer
switch unsafe.Sizeof(*file) {
case unsafe.Sizeof(tokenFile118{}):
var ptr *tokenFile118
*(*uP)(uP(&ptr)) = uP(file)
ptr.mu.Lock()
defer ptr.mu.Unlock()
return ptr.lines
case unsafe.Sizeof(tokenFile119{}):
var ptr *tokenFile119
*(*uP)(uP(&ptr)) = uP(file)
ptr.mu.Lock()
defer ptr.mu.Unlock()
return ptr.lines
default:
panic("unexpected token.File size")
}
}

10
vendor/modules.txt vendored
View File

@ -4,11 +4,12 @@ github.com/AdaLogics/go-fuzz-headers
# github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652 # github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652
## explicit; go 1.18 ## explicit; go 1.18
github.com/AdamKorcz/go-118-fuzz-build/testing github.com/AdamKorcz/go-118-fuzz-build/testing
# github.com/Microsoft/go-winio v0.6.0 # github.com/Microsoft/go-winio v0.6.1-0.20230228163719-dd5de6900b62
## explicit; go 1.17 ## explicit; go 1.17
github.com/Microsoft/go-winio github.com/Microsoft/go-winio
github.com/Microsoft/go-winio/backuptar github.com/Microsoft/go-winio/backuptar
github.com/Microsoft/go-winio/internal/socket github.com/Microsoft/go-winio/internal/socket
github.com/Microsoft/go-winio/pkg/bindfilter
github.com/Microsoft/go-winio/pkg/etw github.com/Microsoft/go-winio/pkg/etw
github.com/Microsoft/go-winio/pkg/etwlogrus github.com/Microsoft/go-winio/pkg/etwlogrus
github.com/Microsoft/go-winio/pkg/fs github.com/Microsoft/go-winio/pkg/fs
@ -97,7 +98,7 @@ github.com/containerd/cgroups/v3/cgroup2/stats
# github.com/containerd/console v1.0.3 # github.com/containerd/console v1.0.3
## explicit; go 1.13 ## explicit; go 1.13
github.com/containerd/console github.com/containerd/console
# github.com/containerd/continuity v0.3.0 # github.com/containerd/continuity v0.3.1-0.20230206102841-68f7b34f5e11
## explicit; go 1.17 ## explicit; go 1.17
github.com/containerd/continuity github.com/containerd/continuity
github.com/containerd/continuity/devices github.com/containerd/continuity/devices
@ -496,7 +497,7 @@ golang.org/x/crypto/openpgp/errors
golang.org/x/crypto/openpgp/packet golang.org/x/crypto/openpgp/packet
golang.org/x/crypto/openpgp/s2k golang.org/x/crypto/openpgp/s2k
golang.org/x/crypto/pbkdf2 golang.org/x/crypto/pbkdf2
# golang.org/x/mod v0.7.0 # golang.org/x/mod v0.8.0
## explicit; go 1.17 ## explicit; go 1.17
golang.org/x/mod/semver golang.org/x/mod/semver
# golang.org/x/net v0.7.0 # golang.org/x/net v0.7.0
@ -544,7 +545,7 @@ golang.org/x/text/unicode/norm
# golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 # golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
## explicit ## explicit
golang.org/x/time/rate golang.org/x/time/rate
# golang.org/x/tools v0.5.0 # golang.org/x/tools v0.6.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/tools/cmd/stringer golang.org/x/tools/cmd/stringer
golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/gcexportdata
@ -558,6 +559,7 @@ golang.org/x/tools/internal/gcimporter
golang.org/x/tools/internal/gocommand golang.org/x/tools/internal/gocommand
golang.org/x/tools/internal/packagesinternal golang.org/x/tools/internal/packagesinternal
golang.org/x/tools/internal/pkgbits golang.org/x/tools/internal/pkgbits
golang.org/x/tools/internal/tokeninternal
golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal golang.org/x/tools/internal/typesinternal
# google.golang.org/appengine v1.6.7 # google.golang.org/appengine v1.6.7