[Vendor] Update directly used dependencys (#15593)

* update github.com/blevesearch/bleve v2.0.2 -> v2.0.3

* github.com/denisenkom/go-mssqldb v0.9.0 -> v0.10.0

* github.com/editorconfig/editorconfig-core-go v2.4.1 -> v2.4.2

* github.com/go-chi/cors v1.1.1 -> v1.2.0

* github.com/go-git/go-billy v5.0.0 -> v5.1.0

* github.com/go-git/go-git v5.2.0 -> v5.3.0

* github.com/go-ldap/ldap v3.2.4 -> v3.3.0

* github.com/go-redis/redis v8.6.0 -> v8.8.2

* github.com/go-sql-driver/mysql v1.5.0 -> v1.6.0

* github.com/go-swagger/go-swagger v0.26.1 -> v0.27.0

* github.com/lib/pq v1.9.0 -> v1.10.1

* github.com/mattn/go-sqlite3 v1.14.6 -> v1.14.7

* github.com/go-testfixtures/testfixtures v3.5.0 -> v3.6.0

* github.com/issue9/identicon v1.0.1 -> v1.2.0

* github.com/klauspost/compress v1.11.8 -> v1.12.1

* github.com/mgechev/revive v1.0.3 -> v1.0.6

* github.com/microcosm-cc/bluemonday v1.0.7 -> v1.0.8

* github.com/niklasfasching/go-org v1.4.0 -> v1.5.0

* github.com/olivere/elastic v7.0.22 -> v7.0.24

* github.com/pelletier/go-toml v1.8.1 -> v1.9.0

* github.com/prometheus/client_golang v1.9.0 -> v1.10.0

* github.com/xanzy/go-gitlab v0.44.0 -> v0.48.0

* github.com/yuin/goldmark v1.3.3 -> v1.3.5

* github.com/6543/go-version v1.2.4 -> v1.3.1

* do github.com/lib/pq v1.10.0 -> v1.10.1 again ...
mj-v1.18.3
6543 3 years ago committed by GitHub
parent 834fc74873
commit 792b4dba2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,81 +11,74 @@ require (
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee
gitea.com/lunny/levelqueue v0.3.0 gitea.com/lunny/levelqueue v0.3.0
github.com/Microsoft/go-winio v0.4.16 // indirect github.com/Microsoft/go-winio v0.4.18 // indirect
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/PuerkitoBio/goquery v1.5.1 github.com/PuerkitoBio/goquery v1.5.1
github.com/RoaringBitmap/roaring v0.5.5 // indirect github.com/RoaringBitmap/roaring v0.6.0 // indirect
github.com/alecthomas/chroma v0.8.2 github.com/alecthomas/chroma v0.8.2
github.com/andybalholm/brotli v1.0.1 // indirect github.com/andybalholm/brotli v1.0.1 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/blevesearch/bleve/v2 v2.0.2 github.com/blevesearch/bleve/v2 v2.0.3
github.com/boombuler/barcode v1.0.1 // indirect github.com/boombuler/barcode v1.0.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b // indirect
github.com/caddyserver/certmagic v0.13.0 github.com/caddyserver/certmagic v0.13.0
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af // indirect
github.com/chi-middleware/proxy v1.1.1 github.com/chi-middleware/proxy v1.1.1
github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 // indirect github.com/couchbase/go-couchbase v0.0.0-20210224140812-5740cd35f448 // indirect
github.com/couchbase/gomemcached v0.1.2 // indirect github.com/couchbase/gomemcached v0.1.2 // indirect
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/denisenkom/go-mssqldb v0.10.0
github.com/denisenkom/go-mssqldb v0.9.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dlclark/regexp2 v1.4.0 // indirect github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/dustin/go-humanize v1.0.0 github.com/dustin/go-humanize v1.0.0
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1 github.com/editorconfig/editorconfig-core-go/v2 v2.4.2
github.com/emirpasic/gods v1.12.0 github.com/emirpasic/gods v1.12.0
github.com/ethantkoenig/rupture v1.0.0 github.com/ethantkoenig/rupture v1.0.0
github.com/gliderlabs/ssh v0.3.2 github.com/gliderlabs/ssh v0.3.2
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect github.com/go-asn1-ber/asn1-ber v1.5.3 // indirect
github.com/go-chi/chi v1.5.4 github.com/go-chi/chi v1.5.4
github.com/go-chi/cors v1.1.1 github.com/go-chi/cors v1.2.0
github.com/go-enry/go-enry/v2 v2.6.1 github.com/go-enry/go-enry/v2 v2.6.1
github.com/go-git/go-billy/v5 v5.0.0 github.com/go-git/go-billy/v5 v5.1.0
github.com/go-git/go-git/v5 v5.2.0 github.com/go-git/go-git/v5 v5.3.0
github.com/go-ldap/ldap/v3 v3.2.4 github.com/go-ldap/ldap/v3 v3.3.0
github.com/go-openapi/errors v0.20.0 // indirect github.com/go-redis/redis/v8 v8.8.2
github.com/go-openapi/validate v0.20.2 // indirect github.com/go-sql-driver/mysql v1.6.0
github.com/go-redis/redis/v8 v8.6.0 github.com/go-swagger/go-swagger v0.27.0
github.com/go-sql-driver/mysql v1.5.0 github.com/go-testfixtures/testfixtures/v3 v3.6.0
github.com/go-swagger/go-swagger v0.26.1
github.com/go-testfixtures/testfixtures/v3 v3.5.0
github.com/gobwas/glob v0.2.3 github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28 github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang/snappy v0.0.3 // indirect
github.com/google/go-github/v32 v32.1.0 github.com/google/go-github/v32 v32.1.0
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.2.0 github.com/google/uuid v1.2.0
github.com/gorilla/context v1.1.1 github.com/gorilla/context v1.1.1
github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/sessions v1.2.1 // indirect github.com/gorilla/sessions v1.2.1 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect github.com/hashicorp/go-version v1.3.1
github.com/hashicorp/go-version v1.2.1
github.com/huandu/xstrings v1.3.2 github.com/huandu/xstrings v1.3.2
github.com/imdario/mergo v0.3.11 // indirect github.com/issue9/identicon v1.2.0
github.com/issue9/assert v1.3.2 // indirect
github.com/issue9/identicon v1.0.1
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7
github.com/json-iterator/go v1.1.10 github.com/json-iterator/go v1.1.10
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/kevinburke/ssh_config v1.1.0 // indirect
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
github.com/klauspost/compress v1.11.8 github.com/klauspost/compress v1.12.1
github.com/klauspost/pgzip v1.2.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect
github.com/lafriks/xormstore v1.4.0 github.com/lafriks/xormstore v1.4.0
github.com/lib/pq v1.9.0 github.com/lib/pq v1.10.1
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
github.com/mailru/easyjson v0.7.7 // indirect
github.com/markbates/goth v1.67.1 github.com/markbates/goth v1.67.1
github.com/mattn/go-isatty v0.0.12 github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-runewidth v0.0.10 // indirect github.com/mattn/go-runewidth v0.0.12 // indirect
github.com/mattn/go-sqlite3 v1.14.6 github.com/mattn/go-sqlite3 v1.14.7
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81
github.com/mgechev/revive v1.0.3 github.com/mgechev/revive v1.0.6
github.com/mholt/archiver/v3 v3.5.0 github.com/mholt/archiver/v3 v3.5.0
github.com/microcosm-cc/bluemonday v1.0.7 github.com/microcosm-cc/bluemonday v1.0.8
github.com/miekg/dns v1.1.41 // indirect github.com/miekg/dns v1.1.40 // indirect
github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.0.10 github.com/minio/minio-go/v7 v7.0.10
github.com/minio/sha256-simd v1.0.0 // indirect github.com/minio/sha256-simd v1.0.0 // indirect
@ -93,28 +86,23 @@ require (
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
github.com/msteinert/pam v0.0.0-20201130170657-e61372126161 github.com/msteinert/pam v0.0.0-20201130170657-e61372126161
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/niklasfasching/go-org v1.4.0 github.com/niklasfasching/go-org v1.5.0
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/oliamb/cutter v0.2.2 github.com/oliamb/cutter v0.2.2
github.com/olivere/elastic/v7 v7.0.22 github.com/olivere/elastic/v7 v7.0.24
github.com/pelletier/go-toml v1.8.1 github.com/pelletier/go-toml v1.9.0
github.com/pierrec/lz4/v4 v4.1.3 // indirect github.com/pierrec/lz4/v4 v4.1.3 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pquerna/otp v1.3.0 github.com/pquerna/otp v1.3.0
github.com/prometheus/client_golang v1.9.0 github.com/prometheus/client_golang v1.10.0
github.com/prometheus/common v0.18.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/quasoft/websspi v1.0.0 github.com/quasoft/websspi v1.0.0
github.com/rivo/uniseg v0.2.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.1.0 github.com/sergi/go-diff v1.2.0
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546
github.com/spf13/afero v1.5.1 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.0 github.com/syndtr/goleveldb v1.0.0
github.com/tinylib/msgp v1.1.5 // indirect
github.com/tstranex/u2f v1.0.0 github.com/tstranex/u2f v1.0.0
github.com/ulikunitz/xz v0.5.10 // indirect github.com/ulikunitz/xz v0.5.10 // indirect
github.com/unknwon/com v1.0.1 github.com/unknwon/com v1.0.1
@ -123,10 +111,9 @@ require (
github.com/unrolled/render v1.1.0 github.com/unrolled/render v1.1.0
github.com/urfave/cli v1.22.5 github.com/urfave/cli v1.22.5
github.com/willf/bitset v1.1.11 // indirect github.com/willf/bitset v1.1.11 // indirect
github.com/xanzy/go-gitlab v0.44.0 github.com/xanzy/go-gitlab v0.48.0
github.com/xanzy/ssh-agent v0.3.0 // indirect
github.com/yohcop/openid-go v1.0.0 github.com/yohcop/openid-go v1.0.0
github.com/yuin/goldmark v1.3.3 github.com/yuin/goldmark v1.3.5
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
github.com/yuin/goldmark-meta v1.0.0 github.com/yuin/goldmark-meta v1.0.0
go.jolheiser.com/hcaptcha v0.0.4 go.jolheiser.com/hcaptcha v0.0.4
@ -135,7 +122,7 @@ require (
go.uber.org/zap v1.16.0 // indirect go.uber.org/zap v1.16.0 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 golang.org/x/net v0.0.0-20210421230115-4e50805a0758
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 golang.org/x/sys v0.0.0-20210421221651-33663a62ff08
golang.org/x/text v0.3.6 golang.org/x/text v0.3.6
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
@ -150,4 +137,4 @@ require (
xorm.io/xorm v1.0.7 xorm.io/xorm v1.0.7
) )
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.2.4 replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1

248
go.sum

@ -53,8 +53,8 @@ gitea.com/lunny/levelqueue v0.3.0 h1:MHn1GuSZkxvVEDMyAPqlc7A3cOW+q8RcGhRgH/xtm6I
gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
github.com/6543/go-version v1.2.4 h1:MPsSnqNrM0HwA9tnmWNnsMdQMg4/u4fflARjwomoof4= github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
github.com/6543/go-version v1.2.4/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo= github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
@ -64,8 +64,9 @@ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.4.18 h1:yjwCO1nhWEShaA5qsmPOBzAOjRCa2PRLsDNZ5yBWXpg=
github.com/Microsoft/go-winio v0.4.18/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@ -77,8 +78,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
github.com/RoaringBitmap/roaring v0.5.5 h1:naNqvO1mNnghk2UvcsqnzHDBn9DRbCIRy94GmDTRVTQ= github.com/RoaringBitmap/roaring v0.6.0 h1:tZcn2nJpUrZf+xQY8x+9QY7BxSETMjkdNG4Ts5zahyU=
github.com/RoaringBitmap/roaring v0.5.5/go.mod h1:puNo5VdzwbaIQxSiDIwfXl4Hnc+fbovcX4IW/dSTtUk= github.com/RoaringBitmap/roaring v0.6.0/go.mod h1:WZ83fjBF/7uBHi6QoFyfGL4+xuV4Qn+xFkm4+vSzrhE=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
@ -127,12 +128,13 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:l
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go v1.35.20/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go v1.38.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
@ -144,8 +146,8 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/blevesearch/bleve/v2 v2.0.1/go.mod h1:OBP2Pktqik8vEiUlGhuWjYx7KiO4zD542+DHqICwM5w= github.com/blevesearch/bleve/v2 v2.0.1/go.mod h1:OBP2Pktqik8vEiUlGhuWjYx7KiO4zD542+DHqICwM5w=
github.com/blevesearch/bleve/v2 v2.0.2 h1:D93VfhOiR6wALovgjsK5XNPeDRrZQlUEIq4YWFeaiTw= github.com/blevesearch/bleve/v2 v2.0.3 h1:mDrwrsRIA4PDYkfUNjoh5zGECvquuJIA3MJU5ivaO8E=
github.com/blevesearch/bleve/v2 v2.0.2/go.mod h1:ip+4iafiEq2gCY5rJXe87bT6LkF/OJMCjQEYIfTBfW8= github.com/blevesearch/bleve/v2 v2.0.3/go.mod h1:ip+4iafiEq2gCY5rJXe87bT6LkF/OJMCjQEYIfTBfW8=
github.com/blevesearch/bleve_index_api v1.0.0 h1:Ds3XeuTxjXCkG6pgIwWDRyooJKNIuOKemnN0N0IkhTU= github.com/blevesearch/bleve_index_api v1.0.0 h1:Ds3XeuTxjXCkG6pgIwWDRyooJKNIuOKemnN0N0IkhTU=
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
@ -194,6 +196,9 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chavacava/garif v0.0.0-20210405163807-87a70f3d418b/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af h1:spmv8nSH9h5oCQf40jt/ufBCt9j0/58u4G+rkeMqXGI=
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ= github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ=
github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0= github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@ -248,8 +253,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk= github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
@ -270,8 +275,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1 h1:ELDiPZji50x20Wvf9FnP4pb7fE3PV/DNhNd6MRlhgfI= github.com/editorconfig/editorconfig-core-go/v2 v2.4.2 h1:1lkDpSoAaFLrgYTVJ/eNCV+lkDSv/j9Wm0jcvDfVVEo=
github.com/editorconfig/editorconfig-core-go/v2 v2.4.1/go.mod h1:UHV4+gECABtht7ALQkPdc5gzP77D+4WDUOZAfx8ifx8= github.com/editorconfig/editorconfig-core-go/v2 v2.4.2/go.mod h1:IXeWRVO4LZRoNunhHh/oP6BQvTs94nB2pNvbw32l8tQ=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
@ -308,9 +313,6 @@ github.com/gliderlabs/ssh v0.3.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aev
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96 h1:rCXyLrgJ598XNj7KTqPzAvwTzlyvI+clqasoNfLQStE=
github.com/glycerine/go-unsnap-stream v0.0.0-20210130063903-47dfef350d96/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag= github.com/go-asn1-ber/asn1-ber v1.5.3 h1:u7utq56RUFiynqUzgVMFDymapcOtQ/MZkh3H4QYkxag=
@ -320,28 +322,29 @@ github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg= github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg=
github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo= github.com/go-chi/chi/v5 v5.0.1 h1:ALxjCrTf1aflOlkhMnCUP86MubbWFrzB3gkRPReLpTo=
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.1.1 h1:eHuqxsIw89iXcWnWUN8R72JMibABJTN/4IOYI5WERvw= github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
github.com/go-chi/cors v1.1.1/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I= github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-enry/go-enry/v2 v2.6.1 h1:ckFkMVj2NeHpaQDFDiSjanVjNy2IiuMNivhXDB4c5Q0= github.com/go-enry/go-enry/v2 v2.6.1 h1:ckFkMVj2NeHpaQDFDiSjanVjNy2IiuMNivhXDB4c5Q0=
github.com/go-enry/go-enry/v2 v2.6.1/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-enry/v2 v2.6.1/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTYahk=
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
github.com/go-ldap/ldap/v3 v3.2.4 h1:PFavAq2xTgzo/loE8qNXcQaofAaqIpI4WgaLdv+1l3E= github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ=
github.com/go-ldap/ldap/v3 v3.2.4/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg= github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
@ -388,7 +391,6 @@ github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2e
github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc=
github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4=
github.com/go-openapi/loads v0.20.1/go.mod h1:/6LfFL8fDvTSX8ypmYXIq3U9Q7nfniSOStW22m864WM=
github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc= github.com/go-openapi/loads v0.20.2 h1:z5p5Xf5wujMxS1y8aP+vxwW5qYT2zdJBbXKmQUG3lcc=
github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
@ -397,8 +399,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g
github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo=
github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98=
github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk=
github.com/go-openapi/runtime v0.19.26 h1:K/6PoVNj5WJXUnMk+VEbELeXjtBkCS1UxTDa04tdXE0= github.com/go-openapi/runtime v0.19.27 h1:4zrQCJoP7rqNCUaApDv1MdPkaa5TuPfO05Lq5WLhX9I=
github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= github.com/go-openapi/runtime v0.19.27/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
@ -408,7 +410,6 @@ github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHK
github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU=
github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ=
github.com/go-openapi/spec v0.20.2/go.mod h1:RW6Xcbs6LOyWLU/mXGdzn2Qc+3aj+ASfI7rvSZh1Vls=
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ= github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
@ -419,8 +420,9 @@ github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6
github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/strfmt v0.20.0 h1:l2omNtmNbMc39IGptl9BuXBEKcZfS8zjrTsPKTiJiDM=
github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc=
github.com/go-openapi/strfmt v0.20.1 h1:1VgxvehFne1mbChGeCmZ5pc0LxUf6yaACVSIYAR91Xc=
github.com/go-openapi/strfmt v0.20.1/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
@ -429,8 +431,9 @@ github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfT
github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M=
github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
@ -443,20 +446,21 @@ github.com/go-openapi/validate v0.20.2/go.mod h1:e7OJoKNgd0twXZwIn0A43tHbvIcr/rZ
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M= github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M=
github.com/go-redis/redis/v8 v8.6.0 h1:swqbqOrxaPztsj2Hf1p94M3YAgl7hYEpcw21z299hh8= github.com/go-redis/redis/v8 v8.8.2 h1:O/NcHqobw7SEptA0yA6up6spZVFtwE06SXM8rgLtsP8=
github.com/go-redis/redis/v8 v8.6.0/go.mod h1:DQ9q4Rk2HtwkrwVrdgmphoOQDMfpvcd/nHEwRsicg8s= github.com/go-redis/redis/v8 v8.8.2/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-swagger/go-swagger v0.26.1 h1:1XUWLnH6hKxHzeKjJfA2gHkSqcT1Zgi4q/PZp2hDdN8= github.com/go-swagger/go-swagger v0.27.0 h1:K7+nkBuf4oS1jTBrdvWqYFpqD69V5CN8HamZzCDDhAI=
github.com/go-swagger/go-swagger v0.26.1/go.mod h1:zlf/LHplZpdtU2mYXg9Ajd3+9TgHYltv5f/pEM6LjnI= github.com/go-swagger/go-swagger v0.27.0/go.mod h1:WodZVysInJilkW7e6IRw+dZGp5yW6rlMFZ4cb+THl9A=
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
github.com/go-testfixtures/testfixtures/v3 v3.5.0 h1:fFJGHhFdcwy48oTLHvr0WRQ09rGiZE+as9ElvbRWS+c= github.com/go-testfixtures/testfixtures/v3 v3.6.0 h1:fHrJWcZ0TOHA0UcExV0Nwx+5MR9QXVDWYdVfwe4DfmM=
github.com/go-testfixtures/testfixtures/v3 v3.5.0/go.mod h1:P4L3WxgOsCLbAeUC50qX5rdj1ULZfUMqgCbqah3OH5U= github.com/go-testfixtures/testfixtures/v3 v3.6.0/go.mod h1:YUBpgqvleDRhkx4MQbzdA7A3G5ca2wLtf9bHbDqNaRQ=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
@ -523,8 +527,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@ -541,12 +547,14 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II= github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI= github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -614,7 +622,6 @@ github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs= github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
@ -637,16 +644,14 @@ github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio= github.com/issue9/assert v1.4.1 h1:gUtOpMTeaE4JTe9kACma5foOHBvVt1p5XTFrULDwdXI=
github.com/issue9/assert v1.3.2 h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0= github.com/issue9/assert v1.4.1/go.mod h1:Yktk83hAVl1SPSYtd9kjhBizuiBIqUQyj+D5SE2yjVY=
github.com/issue9/assert v1.3.2/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio= github.com/issue9/identicon v1.2.0 h1:ek+UcTTyMW/G0iNbLOAlrPC13eSzXTWhbJSs8PHhHGQ=
github.com/issue9/identicon v1.0.1 h1:pCDfjMDM6xWK0Chxo8Lif+ST/nOEtmXgMITgV1YA9Og= github.com/issue9/identicon v1.2.0/go.mod h1:A9toNT0ky/1WP5iNFyDmrkNiYH6eX3HcN5V6uH0g0ec=
github.com/issue9/identicon v1.0.1/go.mod h1:UKNVkUFI68RPz/RlLhsAr1aX6bBSaYEWRHVfdjrMUmk=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
@ -693,8 +698,9 @@ github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 h1:g0fAGBisHaE
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
@ -720,9 +726,9 @@ github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaR
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+mdNo/o=
github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4= github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4=
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@ -731,8 +737,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.8 h1:difgzQsp5mdAz9v8lm3P/I+EpDKMU/6uTMw1y1FObuo= github.com/klauspost/compress v1.12.1 h1:/+xsCsk06wE38cyiqOR/o7U2fSftcH72xD+BQXmja/g=
github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.5/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4= github.com/klauspost/cpuid v1.2.5/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
@ -765,10 +771,10 @@ github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/Y
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo=
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libdns/libdns v0.2.0 h1:ewg3ByWrdUrxrje8ChPVMBNcotg7H9LQYg+u5De2RzI= github.com/libdns/libdns v0.2.0 h1:ewg3ByWrdUrxrje8ChPVMBNcotg7H9LQYg+u5De2RzI=
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
@ -780,8 +786,8 @@ github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VOb
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@ -810,30 +816,29 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM= github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81 h1:QASJXOGm2RZ5Ardbc86qNFvby9AqkLDibfChMtAg5QM=
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
github.com/mgechev/revive v1.0.3 h1:z3FL6IFFN3JKzHYHD8O1ExH9g/4lAGJ5x1+9rPZgsFg= github.com/mgechev/revive v1.0.6 h1:MgRQ3ys2uQCyVjelaDhVs8oSvOPYInzGA/nNGMa+MNU=
github.com/mgechev/revive v1.0.3/go.mod h1:POGGZagSo/0frdr7VeAifzS5Uka0d0GPiM35MsTO8nE= github.com/mgechev/revive v1.0.6/go.mod h1:Lj5gIVxjBlH8REa3icEOkdfchwYc291nShzZ4QYWyMo=
github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk= github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk=
github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM= github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE= github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE=
github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc= github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc=
github.com/microcosm-cc/bluemonday v1.0.7 h1:6yAQfk4XT+PI/dk1ZeBp1gr3Q2Hd1DR0O3aEyPUJVTE= github.com/microcosm-cc/bluemonday v1.0.8 h1:JGc6zQRHqlp+UlLrsbUbbp0mOaJLV44vvQmBSU0Sfj0=
github.com/microcosm-cc/bluemonday v1.0.7/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI= github.com/microcosm-cc/bluemonday v1.0.8/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
@ -882,10 +887,9 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/niklasfasching/go-org v1.4.0 h1:qPy4VEdX55f5QcLiaD3X7N/tY5XOgk4y2uEyQa02i7A= github.com/niklasfasching/go-org v1.5.0 h1:V8IwoSPm/d61bceyWFxxnQLtlvNT+CjiYIhtZLdnMF0=
github.com/niklasfasching/go-org v1.4.0/go.mod h1:4FWT4U/Anir9ewjwNpbZIzMjG5RaXFafkyWZNEPRdk8= github.com/niklasfasching/go-org v1.5.0/go.mod h1:sSb8ylwnAG+h8MGFDB3R1D5bxf8wA08REfhjShg3kjA=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ= github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
@ -893,15 +897,15 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k= github.com/oliamb/cutter v0.2.2 h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=
github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU= github.com/oliamb/cutter v0.2.2/go.mod h1:4BenG2/4GuRBDbVm/OPahDVqbrOemzpPiG5mi1iryBU=
github.com/olivere/elastic/v7 v7.0.22 h1:esBA6JJwvYgfms0EVlH7Z+9J4oQ/WUADF2y/nCNDw7s= github.com/olivere/elastic/v7 v7.0.24 h1:9ZcCQP3Pvgese7TaypYiVAL49sCEphyIwkVxtRf8jb8=
github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8= github.com/olivere/elastic/v7 v7.0.24/go.mod h1:OuWmD2DiuYhddWegBKPWQuelVKBLrW0fa/VUYgxuGTY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -932,12 +936,11 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0=
github.com/pelletier/go-toml v1.9.0/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ=
github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@ -953,7 +956,7 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ= github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac/go.mod h1:hoLfEwdY11HjRfKFH6KqnPsfxlo3BP6bJehpDv8t6sQ=
github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs=
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@ -962,8 +965,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU= github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg=
github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@ -977,7 +980,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y=
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@ -986,7 +988,6 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
@ -1016,8 +1017,9 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
@ -1034,6 +1036,7 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck= github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck=
@ -1048,14 +1051,14 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
@ -1064,6 +1067,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
@ -1090,15 +1094,12 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.1.5 h1:2gXmtWueD2HefZHQe1QOy9HVzmFrLOVvsXwXBQ0ayy0=
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ= github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ= github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo= github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
@ -1123,11 +1124,13 @@ github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
github.com/xanzy/go-gitlab v0.44.0 h1:cEiGhqu7EpFGuei2a2etAwB+x6403E5CvpLn35y+GPs= github.com/xanzy/go-gitlab v0.48.0 h1:RP9r4pMDIwE2fbtc+QYiC1euDsPGHcAjPkhje4X3QPU=
github.com/xanzy/go-gitlab v0.44.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xanzy/go-gitlab v0.48.0/go.mod h1:UW8JJbyBbqtOyBYNHRo261IRdHUFJr2m0y0z1xUiu+E=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
@ -1136,13 +1139,14 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yohcop/openid-go v1.0.0 h1:EciJ7ZLETHR3wOtxBvKXx9RV6eyHZpCaSZ1inbBaUXE= github.com/yohcop/openid-go v1.0.0 h1:EciJ7ZLETHR3wOtxBvKXx9RV6eyHZpCaSZ1inbBaUXE=
github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI= github.com/yohcop/openid-go v1.0.0/go.mod h1:/408xiwkeItSPJZSTPF7+VtZxPkPrRRpRNK2vjGh6yI=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.22/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.3 h1:37BdQwPx8VOSic8eDSWee6QL9mRpZRm9VJp/QugNrW0= github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
github.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio= github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo= github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM= github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
@ -1164,9 +1168,9 @@ go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS
go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.5/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.4.6 h1:rh7GdYmDrb8AQSkF8yteAus8qYOgOASWDOv1BWqBXkU=
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI=
go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@ -1175,15 +1179,16 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw= go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
go.opentelemetry.io/otel v0.17.0 h1:6MKOu8WY4hmfpQ4oQn34u6rYhnf2sWf1LXYO/UFm71U= go.opentelemetry.io/otel v0.19.0 h1:Lenfy7QHRXPZVsw/12CWpxX6d/JkrX8wrx2vO8G80Ng=
go.opentelemetry.io/otel v0.17.0/go.mod h1:Oqtdxmf7UtEvL037ohlgnaYa1h7GtMh0NcSd9eqkC9s= go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
go.opentelemetry.io/otel/metric v0.17.0 h1:t+5EioN8YFXQ2EH+1j6FHCKMUj+57zIDSnSGr/mWuug= go.opentelemetry.io/otel/metric v0.19.0 h1:dtZ1Ju44gkJkYvo+3qGqVXmf88tc+a42edOywypengg=
go.opentelemetry.io/otel/metric v0.17.0/go.mod h1:hUz9lH1rNXyEwWAhIWCMFWKhYtpASgSnObJFnU26dJ0= go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
go.opentelemetry.io/otel/oteltest v0.17.0 h1:TyAihUowTDLqb4+m5ePAsR71xPJaTBJl4KDArIdi9k4= go.opentelemetry.io/otel/oteltest v0.19.0 h1:YVfA0ByROYqTwOxqHVZYZExzEpfZor+MU1rU+ip2v9Q=
go.opentelemetry.io/otel/oteltest v0.17.0/go.mod h1:JT/LGFxPwpN+nlsTiinSYjdIx3hZIGqHCpChcIZmdoE= go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
go.opentelemetry.io/otel/trace v0.17.0 h1:SBOj64/GAOyWzs5F680yW1ITIfJkm6cJWL2YAvuL9xY= go.opentelemetry.io/otel/trace v0.19.0 h1:1ucYlenXIDA1OlHVLDZKX0ObXV5RLaq06DtUKz5e5zc=
go.opentelemetry.io/otel/trace v0.17.0/go.mod h1:bIujpqg6ZL6xUTubIUgziI1jSaUPthmabA/ygf/6Cfg= go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@ -1226,7 +1231,7 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1262,8 +1267,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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.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 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
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 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/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-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=
@ -1318,6 +1324,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY= golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
@ -1331,8 +1339,9 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 h1:alLDrZkL34Y2bnGHfvC1CYBRBXCXgx8AC2vY4MRtYX4= golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78 h1:rPRtHfUb0UKZeZ6GH4K4Nt4YRbE9V1u+QZX5upZXqJQ=
golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1343,9 +1352,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1358,7 +1366,6 @@ golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1409,20 +1416,19 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 h1:qyN5bV+96OX8pL78eXDuz6YlDPzCYgdW74H5yE9BoSU= golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 h1:qyN5bV+96OX8pL78eXDuz6YlDPzCYgdW74H5yE9BoSU=
golang.org/x/sys v0.0.0-20210421221651-33663a62ff08/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210421221651-33663a62ff08/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1502,9 +1508,7 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@ -1617,16 +1621,19 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@ -1651,7 +1658,6 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=

@ -0,0 +1 @@
* @microsoft/containerplat

@ -5,21 +5,14 @@ package winio
import ( import (
"os" "os"
"runtime" "runtime"
"syscall"
"unsafe" "unsafe"
)
//sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx
//sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle
const ( "golang.org/x/sys/windows"
fileBasicInfo = 0
fileIDInfo = 0x12
) )
// FileBasicInfo contains file access time and file attributes information. // FileBasicInfo contains file access time and file attributes information.
type FileBasicInfo struct { type FileBasicInfo struct {
CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime
FileAttributes uint32 FileAttributes uint32
pad uint32 // padding pad uint32 // padding
} }
@ -27,7 +20,7 @@ type FileBasicInfo struct {
// GetFileBasicInfo retrieves times and attributes for a file. // GetFileBasicInfo retrieves times and attributes for a file.
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
bi := &FileBasicInfo{} bi := &FileBasicInfo{}
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
} }
runtime.KeepAlive(f) runtime.KeepAlive(f)
@ -36,13 +29,32 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
// SetFileBasicInfo sets times and attributes for a file. // SetFileBasicInfo sets times and attributes for a file.
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error { func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { if err := windows.SetFileInformationByHandle(windows.Handle(f.Fd()), windows.FileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil {
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err} return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
} }
runtime.KeepAlive(f) runtime.KeepAlive(f)
return nil return nil
} }
// FileStandardInfo contains extended information for the file.
// FILE_STANDARD_INFO in WinBase.h
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info
type FileStandardInfo struct {
AllocationSize, EndOfFile int64
NumberOfLinks uint32
DeletePending, Directory bool
}
// GetFileStandardInfo retrieves ended information for the file.
func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) {
si := &FileStandardInfo{}
if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileStandardInfo, (*byte)(unsafe.Pointer(si)), uint32(unsafe.Sizeof(*si))); err != nil {
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
}
runtime.KeepAlive(f)
return si, nil
}
// FileIDInfo contains the volume serial number and file ID for a file. This pair should be // FileIDInfo contains the volume serial number and file ID for a file. This pair should be
// unique on a system. // unique on a system.
type FileIDInfo struct { type FileIDInfo struct {
@ -53,7 +65,7 @@ type FileIDInfo struct {
// GetFileID retrieves the unique (volume, file ID) pair for a file. // GetFileID retrieves the unique (volume, file ID) pair for a file.
func GetFileID(f *os.File) (*FileIDInfo, error) { func GetFileID(f *os.File) (*FileIDInfo, error) {
fileID := &FileIDInfo{} fileID := &FileIDInfo{}
if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil { if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), windows.FileIdInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil {
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
} }
runtime.KeepAlive(f) runtime.KeepAlive(f)

@ -4,6 +4,6 @@ go 1.12
require ( require (
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.4.1 github.com/sirupsen/logrus v1.7.0
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
) )

@ -1,16 +1,14 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

@ -1,3 +1,5 @@
// +build windows
package winio package winio
import ( import (

@ -1,3 +1,5 @@
// +build windows
// Package guid provides a GUID type. The backing structure for a GUID is // Package guid provides a GUID type. The backing structure for a GUID is
// identical to that used by the golang.org/x/sys/windows GUID type. // identical to that used by the golang.org/x/sys/windows GUID type.
// There are two main binary encodings used for a GUID, the big-endian encoding, // There are two main binary encodings used for a GUID, the big-endian encoding,

@ -28,8 +28,9 @@ const (
ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300 ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
SeBackupPrivilege = "SeBackupPrivilege" SeBackupPrivilege = "SeBackupPrivilege"
SeRestorePrivilege = "SeRestorePrivilege" SeRestorePrivilege = "SeRestorePrivilege"
SeSecurityPrivilege = "SeSecurityPrivilege"
) )
const ( const (

@ -1,3 +1,3 @@
package winio package winio
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go //go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go hvsock.go

@ -19,6 +19,7 @@ const (
var ( var (
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
errERROR_EINVAL error = syscall.EINVAL
) )
// errnoErr returns common boxed Errno values, to prevent // errnoErr returns common boxed Errno values, to prevent
@ -26,7 +27,7 @@ var (
func errnoErr(e syscall.Errno) error { func errnoErr(e syscall.Errno) error {
switch e { switch e {
case 0: case 0:
return nil return errERROR_EINVAL
case errnoERROR_IO_PENDING: case errnoERROR_IO_PENDING:
return errERROR_IO_PENDING return errERROR_IO_PENDING
} }
@ -37,514 +38,382 @@ func errnoErr(e syscall.Errno) error {
} }
var ( var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll") modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
modntdll = windows.NewLazySystemDLL("ntdll.dll") modntdll = windows.NewLazySystemDLL("ntdll.dll")
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
procCancelIoEx = modkernel32.NewProc("CancelIoEx") procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
procCreateFileW = modkernel32.NewProc("CreateFileW")
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
procLocalFree = modkernel32.NewProc("LocalFree")
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength") procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
procRevertToSelf = modadvapi32.NewProc("RevertToSelf") procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW") procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
procBackupRead = modkernel32.NewProc("BackupRead") procBackupRead = modkernel32.NewProc("BackupRead")
procBackupWrite = modkernel32.NewProc("BackupWrite") procBackupWrite = modkernel32.NewProc("BackupWrite")
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
procCreateFileW = modkernel32.NewProc("CreateFileW")
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
procLocalFree = modkernel32.NewProc("LocalFree")
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
procbind = modws2_32.NewProc("bind") procbind = modws2_32.NewProc("bind")
) )
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) var _p0 uint32
if r1 == 0 { if releaseAll {
if e1 != 0 { _p0 = 1
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
} success = r0 != 0
if true {
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { err = errnoErr(e1)
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
newport = syscall.Handle(r0)
if newport == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { func convertSidToStringSid(sid *byte, str **uint16) (err error) {
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) { func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
var _p0 uint32 var _p0 *uint16
if wait { _p0, err = syscall.UTF16PtrFromString(str)
_p0 = 1 if err != nil {
} else { return
_p0 = 0
} }
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0) return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
}
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { func getSecurityDescriptorLength(sd uintptr) (len uint32) {
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
len = uint32(r0)
return
}
func impersonateSelf(level uint32) (err error) {
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
var _p0 *uint16 var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(name) _p0, err = syscall.UTF16PtrFromString(accountName)
if err != nil { if err != nil {
return return
} }
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)
} }
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
handle = syscall.Handle(r0) if r1 == 0 {
if handle == syscall.InvalidHandle { err = errnoErr(e1)
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
var _p0 *uint16 var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(name) _p0, err = syscall.UTF16PtrFromString(systemName)
if err != nil { if err != nil {
return return
} }
return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile) return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
} }
func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
handle = syscall.Handle(r0) if r1 == 0 {
if handle == syscall.InvalidHandle { err = errnoErr(e1)
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) var _p0 *uint16
if r1 == 0 { _p0, err = syscall.UTF16PtrFromString(systemName)
if e1 != 0 { if err != nil {
err = errnoErr(e1) return
} else {
err = syscall.EINVAL
}
} }
return return _lookupPrivilegeName(_p0, luid, buffer, size)
} }
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) { func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0) var _p0 *uint16
ptr = uintptr(r0) _p0, err = syscall.UTF16PtrFromString(systemName)
return if err != nil {
return
}
var _p1 *uint16
_p1, err = syscall.UTF16PtrFromString(name)
if err != nil {
return
}
return _lookupPrivilegeValue(_p0, _p1, luid)
} }
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) { func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0) r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
status = ntstatus(r0) if r1 == 0 {
err = errnoErr(e1)
}
return return
} }
func rtlNtStatusToDosError(status ntstatus) (winerr error) { func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0) var _p0 uint32
if r0 != 0 { if openAsSelf {
winerr = syscall.Errno(r0) _p0 = 1
}
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
} }
return return
} }
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) { func revertToSelf() (err error) {
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0) r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
status = ntstatus(r0) if r1 == 0 {
err = errnoErr(e1)
}
return return
} }
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) { func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0) var _p0 *byte
status = ntstatus(r0) if len(b) > 0 {
_p0 = &b[0]
}
var _p1 uint32
if abort {
_p1 = 1
}
var _p2 uint32
if processSecurity {
_p2 = 1
}
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return return
} }
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
var _p0 *uint16 var _p0 *byte
_p0, err = syscall.UTF16PtrFromString(accountName) if len(b) > 0 {
if err != nil { _p0 = &b[0]
return
} }
return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse) var _p1 uint32
if abort {
_p1 = 1
}
var _p2 uint32
if processSecurity {
_p2 = 1
}
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
} }
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func convertSidToStringSid(sid *byte, str **uint16) (err error) { func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0) r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) { func createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
var _p0 *uint16 var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(str) _p0, err = syscall.UTF16PtrFromString(name)
if err != nil { if err != nil {
return return
} }
return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size) return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile)
} }
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) { func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) {
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
if r1 == 0 { handle = syscall.Handle(r0)
if e1 != 0 { if handle == syscall.InvalidHandle {
err = errnoErr(e1) err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) { func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0) r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
if r1 == 0 { newport = syscall.Handle(r0)
if e1 != 0 { if newport == 0 {
err = errnoErr(e1) err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func localFree(mem uintptr) { func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0) var _p0 *uint16
return _p0, err = syscall.UTF16PtrFromString(name)
} if err != nil {
return
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
len = uint32(r0)
return
}
func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0)
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
} }
func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) { func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
if r1 == 0 { handle = syscall.Handle(r0)
if e1 != 0 { if handle == syscall.InvalidHandle {
err = errnoErr(e1) err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { func getCurrentThread() (h syscall.Handle) {
var _p0 uint32 r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
if releaseAll { h = syscall.Handle(r0)
_p0 = 1
} else {
_p0 = 0
}
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
success = r0 != 0
if true {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return return
} }
func impersonateSelf(level uint32) (err error) { func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0) r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func revertToSelf() (err error) { func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) { func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
var _p0 uint32 r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
if openAsSelf {
_p0 = 1
} else {
_p0 = 0
}
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func getCurrentThread() (h syscall.Handle) { func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
h = syscall.Handle(r0) ptr = uintptr(r0)
return return
} }
func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) { func localFree(mem uintptr) {
var _p0 *uint16 syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
_p0, err = syscall.UTF16PtrFromString(systemName) return
if err != nil {
return
}
var _p1 *uint16
_p1, err = syscall.UTF16PtrFromString(name)
if err != nil {
return
}
return _lookupPrivilegeValue(_p0, _p1, luid)
} }
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) { func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) { func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
var _p0 *uint16 r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
_p0, err = syscall.UTF16PtrFromString(systemName) status = ntstatus(r0)
if err != nil {
return
}
return _lookupPrivilegeName(_p0, luid, buffer, size)
}
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return return
} }
func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
var _p0 *uint16 r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
_p0, err = syscall.UTF16PtrFromString(systemName) status = ntstatus(r0)
if err != nil { return
return
}
return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)
} }
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0) r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
if r1 == 0 { status = ntstatus(r0)
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return return
} }
func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { func rtlNtStatusToDosError(status ntstatus) (winerr error) {
var _p0 *byte r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
if len(b) > 0 { if r0 != 0 {
_p0 = &b[0] winerr = syscall.Errno(r0)
}
var _p1 uint32
if abort {
_p1 = 1
} else {
_p1 = 0
}
var _p2 uint32
if processSecurity {
_p2 = 1
} else {
_p2 = 0
}
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
var _p0 *byte var _p0 uint32
if len(b) > 0 { if wait {
_p0 = &b[0] _p0 = 1
}
var _p1 uint32
if abort {
_p1 = 1
} else {
_p1 = 0
}
var _p2 uint32
if processSecurity {
_p2 = 1
} else {
_p2 = 0
} }
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
if r1 == 0 { if r1 == 0 {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }
@ -552,11 +421,7 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) { func bind(s syscall.Handle, name unsafe.Pointer, namelen int32) (err error) {
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
if r1 == socketError { if r1 == socketError {
if e1 != 0 { err = errnoErr(e1)
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
} }
return return
} }

@ -3,4 +3,3 @@ roaring-fuzz.zip
workdir workdir
coverage.out coverage.out
testdata/all3.classic testdata/all3.classic
testdata/all3.msgp.snappy

@ -17,7 +17,7 @@ branches:
only: only:
- master - master
script: script:
- goveralls -v -service travis-ci -ignore arraycontainer_gen.go,bitmapcontainer_gen.go,rle16_gen.go,rle_gen.go,roaringarray_gen.go,rle.go || go test - goveralls -v -service travis-ci -ignore rle16_gen.go,rle_gen.go,rle.go || go test
- go test -race -run TestConcurrent* - go test -race -run TestConcurrent*
- go build -tags appengine - go build -tags appengine
- go test -tags appengine - go test -tags appengine

@ -97,10 +97,6 @@ nuke:
rm -rf ./target rm -rf ./target
GOPATH=$(GOPATH) go clean -i ./... GOPATH=$(GOPATH) go clean -i ./...
ser:
go generate
cover: cover:
go test -coverprofile=coverage.out go test -coverprofile=coverage.out
go tool cover -html=coverage.out go tool cover -html=coverage.out

@ -4,8 +4,6 @@ import (
"fmt" "fmt"
) )
//go:generate msgp -unexported
type arrayContainer struct { type arrayContainer struct {
content []uint16 content []uint16
} }
@ -485,7 +483,7 @@ func (ac *arrayContainer) orArrayCardinality(value2 *arrayContainer) int {
func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container { func (ac *arrayContainer) lazyorArray(value2 *arrayContainer) container {
value1 := ac value1 := ac
maxPossibleCardinality := value1.getCardinality() + value2.getCardinality() maxPossibleCardinality := value1.getCardinality() + value2.getCardinality()
if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!^M if maxPossibleCardinality > arrayLazyLowerBound { // it could be a bitmap!
bc := newBitmapContainer() bc := newBitmapContainer()
for k := 0; k < len(value2.content); k++ { for k := 0; k < len(value2.content); k++ {
v := value2.content[k] v := value2.content[k]

@ -1,134 +0,0 @@
package roaring
// NOTE: THIS FILE WAS PRODUCED BY THE
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
// DO NOT EDIT
import "github.com/tinylib/msgp/msgp"
// Deprecated: DecodeMsg implements msgp.Decodable
func (z *arrayContainer) DecodeMsg(dc *msgp.Reader) (err error) {
var field []byte
_ = field
var zbzg uint32
zbzg, err = dc.ReadMapHeader()
if err != nil {
return
}
for zbzg > 0 {
zbzg--
field, err = dc.ReadMapKeyPtr()
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "content":
var zbai uint32
zbai, err = dc.ReadArrayHeader()
if err != nil {
return
}
if cap(z.content) >= int(zbai) {
z.content = (z.content)[:zbai]
} else {
z.content = make([]uint16, zbai)
}
for zxvk := range z.content {
z.content[zxvk], err = dc.ReadUint16()
if err != nil {
return
}
}
default:
err = dc.Skip()
if err != nil {
return
}
}
}
return
}
// Deprecated: EncodeMsg implements msgp.Encodable
func (z *arrayContainer) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 1
// write "content"
err = en.Append(0x81, 0xa7, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74)
if err != nil {
return err
}
err = en.WriteArrayHeader(uint32(len(z.content)))
if err != nil {
return
}
for zxvk := range z.content {
err = en.WriteUint16(z.content[zxvk])
if err != nil {
return
}
}
return
}
// Deprecated: MarshalMsg implements msgp.Marshaler
func (z *arrayContainer) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// map header, size 1
// string "content"
o = append(o, 0x81, 0xa7, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74)
o = msgp.AppendArrayHeader(o, uint32(len(z.content)))
for zxvk := range z.content {
o = msgp.AppendUint16(o, z.content[zxvk])
}
return
}
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
func (z *arrayContainer) UnmarshalMsg(bts []byte) (o []byte, err error) {
var field []byte
_ = field
var zcmr uint32
zcmr, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
return
}
for zcmr > 0 {
zcmr--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "content":
var zajw uint32
zajw, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
return
}
if cap(z.content) >= int(zajw) {
z.content = (z.content)[:zajw]
} else {
z.content = make([]uint16, zajw)
}
for zxvk := range z.content {
z.content[zxvk], bts, err = msgp.ReadUint16Bytes(bts)
if err != nil {
return
}
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
return
}
}
}
o = bts
return
}
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *arrayContainer) Msgsize() (s int) {
s = 1 + 8 + msgp.ArrayHeaderSize + (len(z.content) * (msgp.Uint16Size))
return
}

@ -5,8 +5,6 @@ import (
"unsafe" "unsafe"
) )
//go:generate msgp -unexported
type bitmapContainer struct { type bitmapContainer struct {
cardinality int cardinality int
bitmap []uint64 bitmap []uint64
@ -115,7 +113,7 @@ type bitmapContainerShortIterator struct {
func (bcsi *bitmapContainerShortIterator) next() uint16 { func (bcsi *bitmapContainerShortIterator) next() uint16 {
j := bcsi.i j := bcsi.i
bcsi.i = bcsi.ptr.NextSetBit(bcsi.i + 1) bcsi.i = bcsi.ptr.NextSetBit(uint(bcsi.i) + 1)
return uint16(j) return uint16(j)
} }
func (bcsi *bitmapContainerShortIterator) hasNext() bool { func (bcsi *bitmapContainerShortIterator) hasNext() bool {
@ -128,7 +126,7 @@ func (bcsi *bitmapContainerShortIterator) peekNext() uint16 {
func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) { func (bcsi *bitmapContainerShortIterator) advanceIfNeeded(minval uint16) {
if bcsi.hasNext() && bcsi.peekNext() < minval { if bcsi.hasNext() && bcsi.peekNext() < minval {
bcsi.i = bcsi.ptr.NextSetBit(int(minval)) bcsi.i = bcsi.ptr.NextSetBit(uint(minval))
} }
} }
@ -1009,20 +1007,23 @@ func (bc *bitmapContainer) fillArray(container []uint16) {
} }
} }
func (bc *bitmapContainer) NextSetBit(i int) int { func (bc *bitmapContainer) NextSetBit(i uint) int {
x := i / 64 var (
if x >= len(bc.bitmap) { x = i / 64
length = uint(len(bc.bitmap))
)
if x >= length {
return -1 return -1
} }
w := bc.bitmap[x] w := bc.bitmap[x]
w = w >> uint(i%64) w = w >> uint(i%64)
if w != 0 { if w != 0 {
return i + countTrailingZeros(w) return int(i) + countTrailingZeros(w)
} }
x++ x++
for ; x < len(bc.bitmap); x++ { for ; x < length; x++ {
if bc.bitmap[x] != 0 { if bc.bitmap[x] != 0 {
return (x * 64) + countTrailingZeros(bc.bitmap[x]) return int(x*64) + countTrailingZeros(bc.bitmap[x])
} }
} }
return -1 return -1

@ -1,415 +0,0 @@
package roaring
// NOTE: THIS FILE WAS PRODUCED BY THE
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
// DO NOT EDIT
import "github.com/tinylib/msgp/msgp"
// Deprecated: DecodeMsg implements msgp.Decodable
func (z *bitmapContainer) DecodeMsg(dc *msgp.Reader) (err error) {
var field []byte
_ = field
var zbzg uint32
zbzg, err = dc.ReadMapHeader()
if err != nil {
return
}
for zbzg > 0 {
zbzg--
field, err = dc.ReadMapKeyPtr()
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "cardinality":
z.cardinality, err = dc.ReadInt()
if err != nil {
return
}
case "bitmap":
var zbai uint32
zbai, err = dc.ReadArrayHeader()
if err != nil {
return
}
if cap(z.bitmap) >= int(zbai) {
z.bitmap = (z.bitmap)[:zbai]
} else {
z.bitmap = make([]uint64, zbai)
}
for zxvk := range z.bitmap {
z.bitmap[zxvk], err = dc.ReadUint64()
if err != nil {
return
}
}
default:
err = dc.Skip()
if err != nil {
return
}
}
}
return
}
// Deprecated: EncodeMsg implements msgp.Encodable
func (z *bitmapContainer) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 2
// write "cardinality"
err = en.Append(0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
if err != nil {
return err
}
err = en.WriteInt(z.cardinality)
if err != nil {
return
}
// write "bitmap"
err = en.Append(0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
if err != nil {
return err
}
err = en.WriteArrayHeader(uint32(len(z.bitmap)))
if err != nil {
return
}
for zxvk := range z.bitmap {
err = en.WriteUint64(z.bitmap[zxvk])
if err != nil {
return
}
}
return
}
// Deprecated: MarshalMsg implements msgp.Marshaler
func (z *bitmapContainer) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// map header, size 2
// string "cardinality"
o = append(o, 0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
o = msgp.AppendInt(o, z.cardinality)
// string "bitmap"
o = append(o, 0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
o = msgp.AppendArrayHeader(o, uint32(len(z.bitmap)))
for zxvk := range z.bitmap {
o = msgp.AppendUint64(o, z.bitmap[zxvk])
}
return
}
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
func (z *bitmapContainer) UnmarshalMsg(bts []byte) (o []byte, err error) {
var field []byte
_ = field
var zcmr uint32
zcmr, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
return
}
for zcmr > 0 {
zcmr--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "cardinality":
z.cardinality, bts, err = msgp.ReadIntBytes(bts)
if err != nil {
return
}
case "bitmap":
var zajw uint32
zajw, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
return
}
if cap(z.bitmap) >= int(zajw) {
z.bitmap = (z.bitmap)[:zajw]
} else {
z.bitmap = make([]uint64, zajw)
}
for zxvk := range z.bitmap {
z.bitmap[zxvk], bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
return
}
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
return
}
}
}
o = bts
return
}
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *bitmapContainer) Msgsize() (s int) {
s = 1 + 12 + msgp.IntSize + 7 + msgp.ArrayHeaderSize + (len(z.bitmap) * (msgp.Uint64Size))
return
}
// Deprecated: DecodeMsg implements msgp.Decodable
func (z *bitmapContainerShortIterator) DecodeMsg(dc *msgp.Reader) (err error) {
var field []byte
_ = field
var zhct uint32
zhct, err = dc.ReadMapHeader()
if err != nil {
return
}
for zhct > 0 {
zhct--
field, err = dc.ReadMapKeyPtr()
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "ptr":
if dc.IsNil() {
err = dc.ReadNil()
if err != nil {
return
}
z.ptr = nil
} else {
if z.ptr == nil {
z.ptr = new(bitmapContainer)
}
var zcua uint32
zcua, err = dc.ReadMapHeader()
if err != nil {
return
}
for zcua > 0 {
zcua--
field, err = dc.ReadMapKeyPtr()
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "cardinality":
z.ptr.cardinality, err = dc.ReadInt()
if err != nil {
return
}
case "bitmap":
var zxhx uint32
zxhx, err = dc.ReadArrayHeader()
if err != nil {
return
}
if cap(z.ptr.bitmap) >= int(zxhx) {
z.ptr.bitmap = (z.ptr.bitmap)[:zxhx]
} else {
z.ptr.bitmap = make([]uint64, zxhx)
}
for zwht := range z.ptr.bitmap {
z.ptr.bitmap[zwht], err = dc.ReadUint64()
if err != nil {
return
}
}
default:
err = dc.Skip()
if err != nil {
return
}
}
}
}
case "i":
z.i, err = dc.ReadInt()
if err != nil {
return
}
default:
err = dc.Skip()
if err != nil {
return
}
}
}
return
}
// Deprecated: EncodeMsg implements msgp.Encodable
func (z *bitmapContainerShortIterator) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 2
// write "ptr"
err = en.Append(0x82, 0xa3, 0x70, 0x74, 0x72)
if err != nil {
return err
}
if z.ptr == nil {
err = en.WriteNil()
if err != nil {
return
}
} else {
// map header, size 2
// write "cardinality"
err = en.Append(0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
if err != nil {
return err
}
err = en.WriteInt(z.ptr.cardinality)
if err != nil {
return
}
// write "bitmap"
err = en.Append(0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
if err != nil {
return err
}
err = en.WriteArrayHeader(uint32(len(z.ptr.bitmap)))
if err != nil {
return
}
for zwht := range z.ptr.bitmap {
err = en.WriteUint64(z.ptr.bitmap[zwht])
if err != nil {
return
}
}
}
// write "i"
err = en.Append(0xa1, 0x69)
if err != nil {
return err
}
err = en.WriteInt(z.i)
if err != nil {
return
}
return
}
// Deprecated: MarshalMsg implements msgp.Marshaler
func (z *bitmapContainerShortIterator) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// map header, size 2
// string "ptr"
o = append(o, 0x82, 0xa3, 0x70, 0x74, 0x72)
if z.ptr == nil {
o = msgp.AppendNil(o)
} else {
// map header, size 2
// string "cardinality"
o = append(o, 0x82, 0xab, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79)
o = msgp.AppendInt(o, z.ptr.cardinality)
// string "bitmap"
o = append(o, 0xa6, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70)
o = msgp.AppendArrayHeader(o, uint32(len(z.ptr.bitmap)))
for zwht := range z.ptr.bitmap {
o = msgp.AppendUint64(o, z.ptr.bitmap[zwht])
}
}
// string "i"
o = append(o, 0xa1, 0x69)
o = msgp.AppendInt(o, z.i)
return
}
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
func (z *bitmapContainerShortIterator) UnmarshalMsg(bts []byte) (o []byte, err error) {
var field []byte
_ = field
var zlqf uint32
zlqf, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
return
}
for zlqf > 0 {
zlqf--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "ptr":
if msgp.IsNil(bts) {
bts, err = msgp.ReadNilBytes(bts)
if err != nil {
return
}
z.ptr = nil
} else {
if z.ptr == nil {
z.ptr = new(bitmapContainer)
}
var zdaf uint32
zdaf, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
return
}
for zdaf > 0 {
zdaf--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "cardinality":
z.ptr.cardinality, bts, err = msgp.ReadIntBytes(bts)
if err != nil {
return
}
case "bitmap":
var zpks uint32
zpks, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
return
}
if cap(z.ptr.bitmap) >= int(zpks) {
z.ptr.bitmap = (z.ptr.bitmap)[:zpks]
} else {
z.ptr.bitmap = make([]uint64, zpks)
}
for zwht := range z.ptr.bitmap {
z.ptr.bitmap[zwht], bts, err = msgp.ReadUint64Bytes(bts)
if err != nil {
return
}
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
return
}
}
}
}
case "i":
z.i, bts, err = msgp.ReadIntBytes(bts)
if err != nil {
return
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
return
}
}
}
o = bts
return
}
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *bitmapContainerShortIterator) Msgsize() (s int) {
s = 1 + 4
if z.ptr == nil {
s += msgp.NilSize
} else {
s += 1 + 12 + msgp.IntSize + 7 + msgp.ArrayHeaderSize + (len(z.ptr.bitmap) * (msgp.Uint64Size))
}
s += 2 + msgp.IntSize
return
}

@ -1,161 +0,0 @@
package roaring
import (
"encoding/binary"
"io"
)
type byteInput interface {
// next returns a slice containing the next n bytes from the buffer,
// advancing the buffer as if the bytes had been returned by Read.
next(n int) ([]byte, error)
// readUInt32 reads uint32 with LittleEndian order
readUInt32() (uint32, error)
// readUInt16 reads uint16 with LittleEndian order
readUInt16() (uint16, error)
// getReadBytes returns read bytes
getReadBytes() int64
// skipBytes skips exactly n bytes
skipBytes(n int) error
}
func newByteInputFromReader(reader io.Reader) byteInput {
return &byteInputAdapter{
r: reader,
readBytes: 0,
}
}
func newByteInput(buf []byte) byteInput {
return &byteBuffer{
buf: buf,
off: 0,
}
}
type byteBuffer struct {
buf []byte
off int
}
// next returns a slice containing the next n bytes from the reader
// If there are fewer bytes than the given n, io.ErrUnexpectedEOF will be returned
func (b *byteBuffer) next(n int) ([]byte, error) {
m := len(b.buf) - b.off
if n > m {
return nil, io.ErrUnexpectedEOF
}
data := b.buf[b.off : b.off+n]
b.off += n
return data, nil
}
// readUInt32 reads uint32 with LittleEndian order
func (b *byteBuffer) readUInt32() (uint32, error) {
if len(b.buf)-b.off < 4 {
return 0, io.ErrUnexpectedEOF
}
v := binary.LittleEndian.Uint32(b.buf[b.off:])
b.off += 4
return v, nil
}
// readUInt16 reads uint16 with LittleEndian order
func (b *byteBuffer) readUInt16() (uint16, error) {
if len(b.buf)-b.off < 2 {
return 0, io.ErrUnexpectedEOF
}
v := binary.LittleEndian.Uint16(b.buf[b.off:])
b.off += 2
return v, nil
}
// getReadBytes returns read bytes
func (b *byteBuffer) getReadBytes() int64 {
return int64(b.off)
}
// skipBytes skips exactly n bytes
func (b *byteBuffer) skipBytes(n int) error {
m := len(b.buf) - b.off
if n > m {
return io.ErrUnexpectedEOF
}
b.off += n
return nil
}
// reset resets the given buffer with a new byte slice
func (b *byteBuffer) reset(buf []byte) {
b.buf = buf
b.off = 0
}
type byteInputAdapter struct {
r io.Reader
readBytes int
}
// next returns a slice containing the next n bytes from the buffer,
// advancing the buffer as if the bytes had been returned by Read.
func (b *byteInputAdapter) next(n int) ([]byte, error) {
buf := make([]byte, n)
m, err := io.ReadAtLeast(b.r, buf, n)
b.readBytes += m
if err != nil {
return nil, err
}
return buf, nil
}
// readUInt32 reads uint32 with LittleEndian order
func (b *byteInputAdapter) readUInt32() (uint32, error) {
buf, err := b.next(4)
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint32(buf), nil
}
// readUInt16 reads uint16 with LittleEndian order
func (b *byteInputAdapter) readUInt16() (uint16, error) {
buf, err := b.next(2)
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint16(buf), nil
}
// getReadBytes returns read bytes
func (b *byteInputAdapter) getReadBytes() int64 {
return int64(b.readBytes)
}
// skipBytes skips exactly n bytes
func (b *byteInputAdapter) skipBytes(n int) error {
_, err := b.next(n)
return err
}
// reset resets the given buffer with a new stream
func (b *byteInputAdapter) reset(stream io.Reader) {
b.r = stream
b.readBytes = 0
}

@ -11,7 +11,6 @@ require (
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae
github.com/philhofer/fwd v1.0.0 // indirect github.com/philhofer/fwd v1.0.0 // indirect
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/tinylib/msgp v1.1.0
github.com/willf/bitset v1.1.10 github.com/willf/bitset v1.1.10
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/tools v0.0.0-20200928182047-19e03678916f // indirect golang.org/x/tools v0.0.0-20200928182047-19e03678916f // indirect

@ -20,8 +20,6 @@ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU=
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc= github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

@ -0,0 +1,166 @@
package internal
import (
"encoding/binary"
"io"
)
// ByteInput typed interface around io.Reader or raw bytes
type ByteInput interface {
// Next returns a slice containing the next n bytes from the buffer,
// advancing the buffer as if the bytes had been returned by Read.
Next(n int) ([]byte, error)
// ReadUInt32 reads uint32 with LittleEndian order
ReadUInt32() (uint32, error)
// ReadUInt16 reads uint16 with LittleEndian order
ReadUInt16() (uint16, error)
// GetReadBytes returns read bytes
GetReadBytes() int64
// SkipBytes skips exactly n bytes
SkipBytes(n int) error
}
// NewByteInputFromReader creates reader wrapper
func NewByteInputFromReader(reader io.Reader) ByteInput {
return &ByteInputAdapter{
r: reader,
readBytes: 0,
}
}
// NewByteInput creates raw bytes wrapper
func NewByteInput(buf []byte) ByteInput {
return &ByteBuffer{
buf: buf,
off: 0,
}
}
// ByteBuffer raw bytes wrapper
type ByteBuffer struct {
buf []byte
off int
}
// Next returns a slice containing the next n bytes from the reader
// If there are fewer bytes than the given n, io.ErrUnexpectedEOF will be returned
func (b *ByteBuffer) Next(n int) ([]byte, error) {
m := len(b.buf) - b.off
if n > m {
return nil, io.ErrUnexpectedEOF
}
data := b.buf[b.off : b.off+n]
b.off += n
return data, nil
}
// ReadUInt32 reads uint32 with LittleEndian order
func (b *ByteBuffer) ReadUInt32() (uint32, error) {
if len(b.buf)-b.off < 4 {
return 0, io.ErrUnexpectedEOF
}
v := binary.LittleEndian.Uint32(b.buf[b.off:])
b.off += 4
return v, nil
}
// ReadUInt16 reads uint16 with LittleEndian order
func (b *ByteBuffer) ReadUInt16() (uint16, error) {
if len(b.buf)-b.off < 2 {
return 0, io.ErrUnexpectedEOF
}
v := binary.LittleEndian.Uint16(b.buf[b.off:])
b.off += 2
return v, nil
}
// GetReadBytes returns read bytes
func (b *ByteBuffer) GetReadBytes() int64 {
return int64(b.off)
}
// SkipBytes skips exactly n bytes
func (b *ByteBuffer) SkipBytes(n int) error {
m := len(b.buf) - b.off
if n > m {
return io.ErrUnexpectedEOF
}
b.off += n
return nil
}
// Reset resets the given buffer with a new byte slice
func (b *ByteBuffer) Reset(buf []byte) {
b.buf = buf
b.off = 0
}
// ByteInputAdapter reader wrapper
type ByteInputAdapter struct {
r io.Reader
readBytes int
}
// Next returns a slice containing the next n bytes from the buffer,
// advancing the buffer as if the bytes had been returned by Read.
func (b *ByteInputAdapter) Next(n int) ([]byte, error) {
buf := make([]byte, n)
m, err := io.ReadAtLeast(b.r, buf, n)
b.readBytes += m
if err != nil {
return nil, err
}
return buf, nil
}
// ReadUInt32 reads uint32 with LittleEndian order
func (b *ByteInputAdapter) ReadUInt32() (uint32, error) {
buf, err := b.Next(4)
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint32(buf), nil
}
// ReadUInt16 reads uint16 with LittleEndian order
func (b *ByteInputAdapter) ReadUInt16() (uint16, error) {
buf, err := b.Next(2)
if err != nil {
return 0, err
}
return binary.LittleEndian.Uint16(buf), nil
}
// GetReadBytes returns read bytes
func (b *ByteInputAdapter) GetReadBytes() int64 {
return int64(b.readBytes)
}
// SkipBytes skips exactly n bytes
func (b *ByteInputAdapter) SkipBytes(n int) error {
_, err := b.Next(n)
return err
}
// Reset resets the given buffer with a new stream
func (b *ByteInputAdapter) Reset(stream io.Reader) {
b.r = stream
b.readBytes = 0
}

@ -0,0 +1,21 @@
package internal
import (
"sync"
)
var (
// ByteInputAdapterPool shared pool
ByteInputAdapterPool = sync.Pool{
New: func() interface{} {
return &ByteInputAdapter{}
},
}
// ByteBufferPool shared pool
ByteBufferPool = sync.Pool{
New: func() interface{} {
return &ByteBuffer{}
},
}
)

@ -166,7 +166,6 @@ func appenderRoutine(bitmapChan chan<- *Bitmap, resultChan <-chan keyedContainer
make([]container, 0, expectedKeys), make([]container, 0, expectedKeys),
make([]bool, 0, expectedKeys), make([]bool, 0, expectedKeys),
false, false,
nil,
}, },
} }
for i := range keys { for i := range keys {

@ -11,7 +11,8 @@ import (
"fmt" "fmt"
"io" "io"
"strconv" "strconv"
"sync"
"github.com/RoaringBitmap/roaring/internal"
) )
// Bitmap represents a compressed bitmap where you can add integers. // Bitmap represents a compressed bitmap where you can add integers.
@ -52,27 +53,19 @@ func (rb *Bitmap) ToBytes() ([]byte, error) {
return rb.highlowcontainer.toBytes() return rb.highlowcontainer.toBytes()
} }
// Deprecated: WriteToMsgpack writes a msgpack2/snappy-streaming compressed serialized
// version of this bitmap to stream. The format is not
// compatible with the WriteTo() format, and is
// experimental: it may produce smaller on disk
// footprint and/or be faster to read, depending
// on your content. Currently only the Go roaring
// implementation supports this format.
func (rb *Bitmap) WriteToMsgpack(stream io.Writer) (int64, error) {
return 0, rb.highlowcontainer.writeToMsgpack(stream)
}
// ReadFrom reads a serialized version of this bitmap from stream. // ReadFrom reads a serialized version of this bitmap from stream.
// The format is compatible with other RoaringBitmap // The format is compatible with other RoaringBitmap
// implementations (Java, C) and is documented here: // implementations (Java, C) and is documented here:
// https://github.com/RoaringBitmap/RoaringFormatSpec // https://github.com/RoaringBitmap/RoaringFormatSpec
func (rb *Bitmap) ReadFrom(reader io.Reader) (p int64, err error) { // Since io.Reader is regarded as a stream and cannot be read twice.
stream := byteInputAdapterPool.Get().(*byteInputAdapter) // So add cookieHeader to accept the 4-byte data that has been read in roaring64.ReadFrom.
stream.reset(reader) // It is not necessary to pass cookieHeader when call roaring.ReadFrom to read the roaring32 data directly.
func (rb *Bitmap) ReadFrom(reader io.Reader, cookieHeader ...byte) (p int64, err error) {
stream := internal.ByteInputAdapterPool.Get().(*internal.ByteInputAdapter)
stream.Reset(reader)
p, err = rb.highlowcontainer.readFrom(stream) p, err = rb.highlowcontainer.readFrom(stream, cookieHeader...)
byteInputAdapterPool.Put(stream) internal.ByteInputAdapterPool.Put(stream)
return return
} }
@ -100,29 +93,15 @@ func (rb *Bitmap) ReadFrom(reader io.Reader) (p int64, err error) {
// call CloneCopyOnWriteContainers on all such bitmaps. // call CloneCopyOnWriteContainers on all such bitmaps.
// //
func (rb *Bitmap) FromBuffer(buf []byte) (p int64, err error) { func (rb *Bitmap) FromBuffer(buf []byte) (p int64, err error) {
stream := byteBufferPool.Get().(*byteBuffer) stream := internal.ByteBufferPool.Get().(*internal.ByteBuffer)
stream.reset(buf) stream.Reset(buf)
p, err = rb.highlowcontainer.readFrom(stream) p, err = rb.highlowcontainer.readFrom(stream)
byteBufferPool.Put(stream) internal.ByteBufferPool.Put(stream)
return return
} }
var (
byteBufferPool = sync.Pool{
New: func() interface{} {
return &byteBuffer{}
},
}
byteInputAdapterPool = sync.Pool{
New: func() interface{} {
return &byteInputAdapter{}
},
}
)
// RunOptimize attempts to further compress the runs of consecutive values found in the bitmap // RunOptimize attempts to further compress the runs of consecutive values found in the bitmap
func (rb *Bitmap) RunOptimize() { func (rb *Bitmap) RunOptimize() {
rb.highlowcontainer.runOptimize() rb.highlowcontainer.runOptimize()
@ -133,14 +112,6 @@ func (rb *Bitmap) HasRunCompression() bool {
return rb.highlowcontainer.hasRunCompression() return rb.highlowcontainer.hasRunCompression()
} }
// Deprecated: ReadFromMsgpack reads a msgpack2/snappy-streaming serialized
// version of this bitmap from stream. The format is
// expected is that written by the WriteToMsgpack()
// call; see additional notes there.
func (rb *Bitmap) ReadFromMsgpack(stream io.Reader) (int64, error) {
return 0, rb.highlowcontainer.readFromMsgpack(stream)
}
// MarshalBinary implements the encoding.BinaryMarshaler interface for the bitmap // MarshalBinary implements the encoding.BinaryMarshaler interface for the bitmap
// (same as ToBytes) // (same as ToBytes)
func (rb *Bitmap) MarshalBinary() ([]byte, error) { func (rb *Bitmap) MarshalBinary() ([]byte, error) {

@ -5,13 +5,9 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io" "io"
"github.com/RoaringBitmap/roaring/internal"
snappy "github.com/glycerine/go-unsnap-stream"
"github.com/tinylib/msgp/msgp"
) )
//go:generate msgp -unexported
type container interface { type container interface {
addOffset(uint16) []container addOffset(uint16) []container
@ -103,18 +99,6 @@ type roaringArray struct {
containers []container `msg:"-"` // don't try to serialize directly. containers []container `msg:"-"` // don't try to serialize directly.
needCopyOnWrite []bool needCopyOnWrite []bool
copyOnWrite bool copyOnWrite bool
// conserz is used at serialization time
// to serialize containers. Otherwise empty.
conserz []containerSerz
}
// containerSerz facilitates serializing container (tricky to
// serialize because it is an interface) by providing a
// light wrapper with a type identifier.
type containerSerz struct {
t contype `msg:"t"` // type
r msgp.Raw `msg:"r"` // Raw msgpack of the actual container type
} }
func newRoaringArray() *roaringArray { func newRoaringArray() *roaringArray {
@ -246,7 +230,6 @@ func (ra *roaringArray) resize(newsize int) {
func (ra *roaringArray) clear() { func (ra *roaringArray) clear() {
ra.resize(0) ra.resize(0)
ra.copyOnWrite = false ra.copyOnWrite = false
ra.conserz = nil
} }
func (ra *roaringArray) clone() *roaringArray { func (ra *roaringArray) clone() *roaringArray {
@ -566,11 +549,19 @@ func (ra *roaringArray) toBytes() ([]byte, error) {
return buf.Bytes(), err return buf.Bytes(), err
} }
func (ra *roaringArray) readFrom(stream byteInput) (int64, error) { func (ra *roaringArray) readFrom(stream internal.ByteInput, cookieHeader ...byte) (int64, error) {
cookie, err := stream.readUInt32() var cookie uint32
var err error
if err != nil { if len(cookieHeader) > 0 && len(cookieHeader) != 4 {
return stream.getReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err) return int64(len(cookieHeader)), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: incorrect size of cookie header")
}
if len(cookieHeader) == 4 {
cookie = binary.LittleEndian.Uint32(cookieHeader)
} else {
cookie, err = stream.ReadUInt32()
if err != nil {
return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err)
}
} }
var size uint32 var size uint32
@ -580,37 +571,36 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
size = uint32(uint16(cookie>>16) + 1) size = uint32(uint16(cookie>>16) + 1)
// create is-run-container bitmap // create is-run-container bitmap
isRunBitmapSize := (int(size) + 7) / 8 isRunBitmapSize := (int(size) + 7) / 8
isRunBitmap, err = stream.next(isRunBitmapSize) isRunBitmap, err = stream.Next(isRunBitmapSize)
if err != nil { if err != nil {
return stream.getReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err) return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err)
} }
} else if cookie == serialCookieNoRunContainer { } else if cookie == serialCookieNoRunContainer {
size, err = stream.readUInt32() size, err = stream.ReadUInt32()
if err != nil { if err != nil {
return stream.getReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err) return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err)
} }
} else { } else {
return stream.getReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header") return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header")
} }
if size > (1 << 16) { if size > (1 << 16) {
return stream.getReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers") return stream.GetReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers")
} }
// descriptive header // descriptive header
buf, err := stream.next(2 * 2 * int(size)) buf, err := stream.Next(2 * 2 * int(size))
if err != nil { if err != nil {
return stream.getReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err) return stream.GetReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err)
} }
keycard := byteSliceAsUint16Slice(buf) keycard := byteSliceAsUint16Slice(buf)
if isRunBitmap == nil || size >= noOffsetThreshold { if isRunBitmap == nil || size >= noOffsetThreshold {
if err := stream.skipBytes(int(size) * 4); err != nil { if err := stream.SkipBytes(int(size) * 4); err != nil {
return stream.getReadBytes(), fmt.Errorf("failed to skip bytes: %s", err) return stream.GetReadBytes(), fmt.Errorf("failed to skip bytes: %s", err)
} }
} }
@ -641,16 +631,16 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
if isRunBitmap != nil && isRunBitmap[i/8]&(1<<(i%8)) != 0 { if isRunBitmap != nil && isRunBitmap[i/8]&(1<<(i%8)) != 0 {
// run container // run container
nr, err := stream.readUInt16() nr, err := stream.ReadUInt16()
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to read runtime container size: %s", err) return 0, fmt.Errorf("failed to read runtime container size: %s", err)
} }
buf, err := stream.next(int(nr) * 4) buf, err := stream.Next(int(nr) * 4)
if err != nil { if err != nil {
return stream.getReadBytes(), fmt.Errorf("failed to read runtime container content: %s", err) return stream.GetReadBytes(), fmt.Errorf("failed to read runtime container content: %s", err)
} }
nb := runContainer16{ nb := runContainer16{
@ -661,10 +651,10 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
ra.containers[i] = &nb ra.containers[i] = &nb
} else if card > arrayDefaultMaxSize { } else if card > arrayDefaultMaxSize {
// bitmap container // bitmap container
buf, err := stream.next(arrayDefaultMaxSize * 2) buf, err := stream.Next(arrayDefaultMaxSize * 2)
if err != nil { if err != nil {
return stream.getReadBytes(), fmt.Errorf("failed to read bitmap container: %s", err) return stream.GetReadBytes(), fmt.Errorf("failed to read bitmap container: %s", err)
} }
nb := bitmapContainer{ nb := bitmapContainer{
@ -675,10 +665,10 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
ra.containers[i] = &nb ra.containers[i] = &nb
} else { } else {
// array container // array container
buf, err := stream.next(card * 2) buf, err := stream.Next(card * 2)
if err != nil { if err != nil {
return stream.getReadBytes(), fmt.Errorf("failed to read array container: %s", err) return stream.GetReadBytes(), fmt.Errorf("failed to read array container: %s", err)
} }
nb := arrayContainer{ nb := arrayContainer{
@ -689,7 +679,7 @@ func (ra *roaringArray) readFrom(stream byteInput) (int64, error) {
} }
} }
return stream.getReadBytes(), nil return stream.GetReadBytes(), nil
} }
func (ra *roaringArray) hasRunCompression() bool { func (ra *roaringArray) hasRunCompression() bool {
@ -702,84 +692,6 @@ func (ra *roaringArray) hasRunCompression() bool {
return false return false
} }
func (ra *roaringArray) writeToMsgpack(stream io.Writer) error {
ra.conserz = make([]containerSerz, len(ra.containers))
for i, v := range ra.containers {
switch cn := v.(type) {
case *bitmapContainer:
bts, err := cn.MarshalMsg(nil)
if err != nil {
return err
}
ra.conserz[i].t = bitmapContype
ra.conserz[i].r = bts
case *arrayContainer:
bts, err := cn.MarshalMsg(nil)
if err != nil {
return err
}
ra.conserz[i].t = arrayContype
ra.conserz[i].r = bts
case *runContainer16:
bts, err := cn.MarshalMsg(nil)
if err != nil {
return err
}
ra.conserz[i].t = run16Contype
ra.conserz[i].r = bts
default:
panic(fmt.Errorf("Unrecognized container implementation: %T", cn))
}
}
w := snappy.NewWriter(stream)
err := msgp.Encode(w, ra)
ra.conserz = nil
return err
}
func (ra *roaringArray) readFromMsgpack(stream io.Reader) error {
r := snappy.NewReader(stream)
err := msgp.Decode(r, ra)
if err != nil {
return err
}
if len(ra.containers) != len(ra.keys) {
ra.containers = make([]container, len(ra.keys))
}
for i, v := range ra.conserz {
switch v.t {
case bitmapContype:
c := &bitmapContainer{}
_, err = c.UnmarshalMsg(v.r)
if err != nil {
return err
}
ra.containers[i] = c
case arrayContype:
c := &arrayContainer{}
_, err = c.UnmarshalMsg(v.r)
if err != nil {
return err
}
ra.containers[i] = c
case run16Contype:
c := &runContainer16{}
_, err = c.UnmarshalMsg(v.r)
if err != nil {
return err
}
ra.containers[i] = c
default:
return fmt.Errorf("unrecognized contype serialization code: '%v'", v.t)
}
}
ra.conserz = nil
return nil
}
func (ra *roaringArray) advanceUntil(min uint16, pos int) int { func (ra *roaringArray) advanceUntil(min uint16, pos int) int {
lower := pos + 1 lower := pos + 1

@ -1,529 +0,0 @@
package roaring
// NOTE: THIS FILE WAS PRODUCED BY THE
// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
// DO NOT EDIT
import (
"github.com/tinylib/msgp/msgp"
)
// Deprecated: DecodeMsg implements msgp.Decodable
func (z *containerSerz) DecodeMsg(dc *msgp.Reader) (err error) {
var field []byte
_ = field
var zxvk uint32
zxvk, err = dc.ReadMapHeader()
if err != nil {
return
}
for zxvk > 0 {
zxvk--
field, err = dc.ReadMapKeyPtr()
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "t":
{
var zbzg uint8
zbzg, err = dc.ReadUint8()
z.t = contype(zbzg)
}
if err != nil {
return
}
case "r":
err = z.r.DecodeMsg(dc)
if err != nil {
return
}
default:
err = dc.Skip()
if err != nil {
return
}
}
}
return
}
// Deprecated: EncodeMsg implements msgp.Encodable
func (z *containerSerz) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 2
// write "t"
err = en.Append(0x82, 0xa1, 0x74)
if err != nil {
return err
}
err = en.WriteUint8(uint8(z.t))
if err != nil {
return
}
// write "r"
err = en.Append(0xa1, 0x72)
if err != nil {
return err
}
err = z.r.EncodeMsg(en)
if err != nil {
return
}
return
}
// Deprecated: MarshalMsg implements msgp.Marshaler
func (z *containerSerz) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// map header, size 2
// string "t"
o = append(o, 0x82, 0xa1, 0x74)
o = msgp.AppendUint8(o, uint8(z.t))
// string "r"
o = append(o, 0xa1, 0x72)
o, err = z.r.MarshalMsg(o)
if err != nil {
return
}
return
}
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
func (z *containerSerz) UnmarshalMsg(bts []byte) (o []byte, err error) {
var field []byte
_ = field
var zbai uint32
zbai, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
return
}
for zbai > 0 {
zbai--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "t":
{
var zcmr uint8
zcmr, bts, err = msgp.ReadUint8Bytes(bts)
z.t = contype(zcmr)
}
if err != nil {
return
}
case "r":
bts, err = z.r.UnmarshalMsg(bts)
if err != nil {
return
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
return
}
}
}
o = bts
return
}
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *containerSerz) Msgsize() (s int) {
s = 1 + 2 + msgp.Uint8Size + 2 + z.r.Msgsize()
return
}
// Deprecated: DecodeMsg implements msgp.Decodable
func (z *contype) DecodeMsg(dc *msgp.Reader) (err error) {
{
var zajw uint8
zajw, err = dc.ReadUint8()
(*z) = contype(zajw)
}
if err != nil {
return
}
return
}
// Deprecated: EncodeMsg implements msgp.Encodable
func (z contype) EncodeMsg(en *msgp.Writer) (err error) {
err = en.WriteUint8(uint8(z))
if err != nil {
return
}
return
}
// Deprecated: MarshalMsg implements msgp.Marshaler
func (z contype) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
o = msgp.AppendUint8(o, uint8(z))
return
}
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
func (z *contype) UnmarshalMsg(bts []byte) (o []byte, err error) {
{
var zwht uint8
zwht, bts, err = msgp.ReadUint8Bytes(bts)
(*z) = contype(zwht)
}
if err != nil {
return
}
o = bts
return
}
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z contype) Msgsize() (s int) {
s = msgp.Uint8Size
return
}
// Deprecated: DecodeMsg implements msgp.Decodable
func (z *roaringArray) DecodeMsg(dc *msgp.Reader) (err error) {
var field []byte
_ = field
var zlqf uint32
zlqf, err = dc.ReadMapHeader()
if err != nil {
return
}
for zlqf > 0 {
zlqf--
field, err = dc.ReadMapKeyPtr()
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "keys":
var zdaf uint32
zdaf, err = dc.ReadArrayHeader()
if err != nil {
return
}
if cap(z.keys) >= int(zdaf) {
z.keys = (z.keys)[:zdaf]
} else {
z.keys = make([]uint16, zdaf)
}
for zhct := range z.keys {
z.keys[zhct], err = dc.ReadUint16()
if err != nil {
return
}
}
case "needCopyOnWrite":
var zpks uint32
zpks, err = dc.ReadArrayHeader()
if err != nil {
return
}
if cap(z.needCopyOnWrite) >= int(zpks) {
z.needCopyOnWrite = (z.needCopyOnWrite)[:zpks]
} else {
z.needCopyOnWrite = make([]bool, zpks)
}
for zcua := range z.needCopyOnWrite {
z.needCopyOnWrite[zcua], err = dc.ReadBool()
if err != nil {
return
}
}
case "copyOnWrite":
z.copyOnWrite, err = dc.ReadBool()
if err != nil {
return
}
case "conserz":
var zjfb uint32
zjfb, err = dc.ReadArrayHeader()
if err != nil {
return
}
if cap(z.conserz) >= int(zjfb) {
z.conserz = (z.conserz)[:zjfb]
} else {
z.conserz = make([]containerSerz, zjfb)
}
for zxhx := range z.conserz {
var zcxo uint32
zcxo, err = dc.ReadMapHeader()
if err != nil {
return
}
for zcxo > 0 {
zcxo--
field, err = dc.ReadMapKeyPtr()
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "t":
{
var zeff uint8
zeff, err = dc.ReadUint8()
z.conserz[zxhx].t = contype(zeff)
}
if err != nil {
return
}
case "r":
err = z.conserz[zxhx].r.DecodeMsg(dc)
if err != nil {
return
}
default:
err = dc.Skip()
if err != nil {
return
}
}
}
}
default:
err = dc.Skip()
if err != nil {
return
}
}
}
return
}
// Deprecated: EncodeMsg implements msgp.Encodable
func (z *roaringArray) EncodeMsg(en *msgp.Writer) (err error) {
// map header, size 4
// write "keys"
err = en.Append(0x84, 0xa4, 0x6b, 0x65, 0x79, 0x73)
if err != nil {
return err
}
err = en.WriteArrayHeader(uint32(len(z.keys)))
if err != nil {
return
}
for zhct := range z.keys {
err = en.WriteUint16(z.keys[zhct])
if err != nil {
return
}
}
// write "needCopyOnWrite"
err = en.Append(0xaf, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
if err != nil {
return err
}
err = en.WriteArrayHeader(uint32(len(z.needCopyOnWrite)))
if err != nil {
return
}
for zcua := range z.needCopyOnWrite {
err = en.WriteBool(z.needCopyOnWrite[zcua])
if err != nil {
return
}
}
// write "copyOnWrite"
err = en.Append(0xab, 0x63, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
if err != nil {
return err
}
err = en.WriteBool(z.copyOnWrite)
if err != nil {
return
}
// write "conserz"
err = en.Append(0xa7, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x7a)
if err != nil {
return err
}
err = en.WriteArrayHeader(uint32(len(z.conserz)))
if err != nil {
return
}
for zxhx := range z.conserz {
// map header, size 2
// write "t"
err = en.Append(0x82, 0xa1, 0x74)
if err != nil {
return err
}
err = en.WriteUint8(uint8(z.conserz[zxhx].t))
if err != nil {
return
}
// write "r"
err = en.Append(0xa1, 0x72)
if err != nil {
return err
}
err = z.conserz[zxhx].r.EncodeMsg(en)
if err != nil {
return
}
}
return
}
// Deprecated: MarshalMsg implements msgp.Marshaler
func (z *roaringArray) MarshalMsg(b []byte) (o []byte, err error) {
o = msgp.Require(b, z.Msgsize())
// map header, size 4
// string "keys"
o = append(o, 0x84, 0xa4, 0x6b, 0x65, 0x79, 0x73)
o = msgp.AppendArrayHeader(o, uint32(len(z.keys)))
for zhct := range z.keys {
o = msgp.AppendUint16(o, z.keys[zhct])
}
// string "needCopyOnWrite"
o = append(o, 0xaf, 0x6e, 0x65, 0x65, 0x64, 0x43, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
o = msgp.AppendArrayHeader(o, uint32(len(z.needCopyOnWrite)))
for zcua := range z.needCopyOnWrite {
o = msgp.AppendBool(o, z.needCopyOnWrite[zcua])
}
// string "copyOnWrite"
o = append(o, 0xab, 0x63, 0x6f, 0x70, 0x79, 0x4f, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65)
o = msgp.AppendBool(o, z.copyOnWrite)
// string "conserz"
o = append(o, 0xa7, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x7a)
o = msgp.AppendArrayHeader(o, uint32(len(z.conserz)))
for zxhx := range z.conserz {
// map header, size 2
// string "t"
o = append(o, 0x82, 0xa1, 0x74)
o = msgp.AppendUint8(o, uint8(z.conserz[zxhx].t))
// string "r"
o = append(o, 0xa1, 0x72)
o, err = z.conserz[zxhx].r.MarshalMsg(o)
if err != nil {
return
}
}
return
}
// Deprecated: UnmarshalMsg implements msgp.Unmarshaler
func (z *roaringArray) UnmarshalMsg(bts []byte) (o []byte, err error) {
var field []byte
_ = field
var zrsw uint32
zrsw, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
return
}
for zrsw > 0 {
zrsw--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "keys":
var zxpk uint32
zxpk, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
return
}
if cap(z.keys) >= int(zxpk) {
z.keys = (z.keys)[:zxpk]
} else {
z.keys = make([]uint16, zxpk)
}
for zhct := range z.keys {
z.keys[zhct], bts, err = msgp.ReadUint16Bytes(bts)
if err != nil {
return
}
}
case "needCopyOnWrite":
var zdnj uint32
zdnj, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
return
}
if cap(z.needCopyOnWrite) >= int(zdnj) {
z.needCopyOnWrite = (z.needCopyOnWrite)[:zdnj]
} else {
z.needCopyOnWrite = make([]bool, zdnj)
}
for zcua := range z.needCopyOnWrite {
z.needCopyOnWrite[zcua], bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
return
}
}
case "copyOnWrite":
z.copyOnWrite, bts, err = msgp.ReadBoolBytes(bts)
if err != nil {
return
}
case "conserz":
var zobc uint32
zobc, bts, err = msgp.ReadArrayHeaderBytes(bts)
if err != nil {
return
}
if cap(z.conserz) >= int(zobc) {
z.conserz = (z.conserz)[:zobc]
} else {
z.conserz = make([]containerSerz, zobc)
}
for zxhx := range z.conserz {
var zsnv uint32
zsnv, bts, err = msgp.ReadMapHeaderBytes(bts)
if err != nil {
return
}
for zsnv > 0 {
zsnv--
field, bts, err = msgp.ReadMapKeyZC(bts)
if err != nil {
return
}
switch msgp.UnsafeString(field) {
case "t":
{
var zkgt uint8
zkgt, bts, err = msgp.ReadUint8Bytes(bts)
z.conserz[zxhx].t = contype(zkgt)
}
if err != nil {
return
}
case "r":
bts, err = z.conserz[zxhx].r.UnmarshalMsg(bts)
if err != nil {
return
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
return
}
}
}
}
default:
bts, err = msgp.Skip(bts)
if err != nil {
return
}
}
}
o = bts
return
}
// Deprecated: Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *roaringArray) Msgsize() (s int) {
s = 1 + 5 + msgp.ArrayHeaderSize + (len(z.keys) * (msgp.Uint16Size)) + 16 + msgp.ArrayHeaderSize + (len(z.needCopyOnWrite) * (msgp.BoolSize)) + 12 + msgp.BoolSize + 8 + msgp.ArrayHeaderSize
for zxhx := range z.conserz {
s += 1 + 2 + msgp.Uint8Size + 2 + z.conserz[zxhx].r.Msgsize()
}
return
}

@ -44,16 +44,11 @@ import (
"unsafe" "unsafe"
) )
//go:generate msgp -unexported
// runContainer16 does run-length encoding of sets of // runContainer16 does run-length encoding of sets of
// uint16 integers. // uint16 integers.
type runContainer16 struct { type runContainer16 struct {
iv []interval16 iv []interval16
card int64 card int64
// avoid allocation during search
myOpts searchOptions `msg:"-"`
} }
// interval16 is the internal to runContainer16 // interval16 is the internal to runContainer16
@ -120,8 +115,6 @@ func (p uint16Slice) Less(i, j int) bool { return p[i] < p[j] }
// Swap swaps elements i and j. // Swap swaps elements i and j.
func (p uint16Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p uint16Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
//msgp:ignore addHelper
// addHelper helps build a runContainer16. // addHelper helps build a runContainer16.
type addHelper16 struct { type addHelper16 struct {
runstart uint16 runstart uint16
@ -617,10 +610,7 @@ func (rc *runContainer16) unionCardinality(b *runContainer16) uint64 {
// indexOfIntervalAtOrAfter is a helper for union. // indexOfIntervalAtOrAfter is a helper for union.
func (rc *runContainer16) indexOfIntervalAtOrAfter(key int64, startIndex int64) int64 { func (rc *runContainer16) indexOfIntervalAtOrAfter(key int64, startIndex int64) int64 {
rc.myOpts.startIndex = startIndex w, already, _ := rc.searchRange(key, startIndex, 0)
rc.myOpts.endxIndex = 0
w, already, _ := rc.search(key, &rc.myOpts)
if already { if already {
return w return w
} }
@ -844,7 +834,7 @@ toploop:
// get returns true iff key is in the container. // get returns true iff key is in the container.
func (rc *runContainer16) contains(key uint16) bool { func (rc *runContainer16) contains(key uint16) bool {
_, in, _ := rc.search(int64(key), nil) _, in, _ := rc.search(int64(key))
return in return in
} }
@ -853,22 +843,7 @@ func (rc *runContainer16) numIntervals() int {
return len(rc.iv) return len(rc.iv)
} }
// searchOptions allows us to accelerate search with // searchRange returns alreadyPresent to indicate if the
// prior knowledge of (mostly lower) bounds. This is used by Union
// and Intersect.
type searchOptions struct {
// start here instead of at 0
startIndex int64
// upper bound instead of len(rc.iv);
// endxIndex == 0 means ignore the bound and use
// endxIndex == n ==len(rc.iv) which is also
// naturally the default for search()
// when opt = nil.
endxIndex int64
}
// search returns alreadyPresent to indicate if the
// key is already in one of our interval16s. // key is already in one of our interval16s.
// //
// If key is alreadyPresent, then whichInterval16 tells // If key is alreadyPresent, then whichInterval16 tells
@ -892,24 +867,16 @@ type searchOptions struct {
// //
// runContainer16.search always returns whichInterval16 < len(rc.iv). // runContainer16.search always returns whichInterval16 < len(rc.iv).
// //
// If not nil, opts can be used to further restrict // The search space is from startIndex to endxIndex. If endxIndex is set to zero, then there
// the search space. // no upper bound.
// //
func (rc *runContainer16) search(key int64, opts *searchOptions) (whichInterval16 int64, alreadyPresent bool, numCompares int) { func (rc *runContainer16) searchRange(key int64, startIndex int64, endxIndex int64) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
n := int64(len(rc.iv)) n := int64(len(rc.iv))
if n == 0 { if n == 0 {
return -1, false, 0 return -1, false, 0
} }
if endxIndex == 0 {
startIndex := int64(0) endxIndex = n
endxIndex := n
if opts != nil {
startIndex = opts.startIndex
// let endxIndex == 0 mean no effect
if opts.endxIndex > 0 {
endxIndex = opts.endxIndex
}
} }
// sort.Search returns the smallest index i // sort.Search returns the smallest index i
@ -979,6 +946,34 @@ func (rc *runContainer16) search(key int64, opts *searchOptions) (whichInterval1
return return
} }
// search returns alreadyPresent to indicate if the
// key is already in one of our interval16s.
//
// If key is alreadyPresent, then whichInterval16 tells
// you where.
//
// If key is not already present, then whichInterval16 is
// set as follows:
//
// a) whichInterval16 == len(rc.iv)-1 if key is beyond our
// last interval16 in rc.iv;
//
// b) whichInterval16 == -1 if key is before our first
// interval16 in rc.iv;
//
// c) whichInterval16 is set to the minimum index of rc.iv
// which comes strictly before the key;
// so rc.iv[whichInterval16].last < key,
// and if whichInterval16+1 exists, then key < rc.iv[whichInterval16+1].start
// (Note that whichInterval16+1 won't exist when
// whichInterval16 is the last interval.)
//
// runContainer16.search always returns whichInterval16 < len(rc.iv).
//
func (rc *runContainer16) search(key int64) (whichInterval16 int64, alreadyPresent bool, numCompares int) {
return rc.searchRange(key, 0, 0)
}
// cardinality returns the count of the integers stored in the // cardinality returns the count of the integers stored in the
// runContainer16. // runContainer16.
func (rc *runContainer16) cardinality() int64 { func (rc *runContainer16) cardinality() int64 {
@ -1072,7 +1067,7 @@ func (rc *runContainer16) Add(k uint16) (wasNew bool) {
k64 := int64(k) k64 := int64(k)
index, present, _ := rc.search(k64, nil) index, present, _ := rc.search(k64)
if present { if present {
return // already there return // already there
} }
@ -1147,8 +1142,6 @@ func (rc *runContainer16) Add(k uint16) (wasNew bool) {
return return
} }
//msgp:ignore runIterator
// runIterator16 advice: you must call hasNext() // runIterator16 advice: you must call hasNext()
// before calling next()/peekNext() to insure there are contents. // before calling next()/peekNext() to insure there are contents.
type runIterator16 struct { type runIterator16 struct {
@ -1207,13 +1200,8 @@ func (ri *runIterator16) advanceIfNeeded(minval uint16) {
return return
} }
opt := &searchOptions{
startIndex: ri.curIndex,
endxIndex: int64(len(ri.rc.iv)),
}
// interval cannot be -1 because of minval > peekNext // interval cannot be -1 because of minval > peekNext
interval, isPresent, _ := ri.rc.search(int64(minval), opt) interval, isPresent, _ := ri.rc.searchRange(int64(minval), ri.curIndex, int64(len(ri.rc.iv)))
// if the minval is present, set the curPosIndex at the right position // if the minval is present, set the curPosIndex at the right position
if isPresent { if isPresent {
@ -1366,7 +1354,7 @@ func (ri *runIterator16) nextMany64(hs uint64, buf []uint64) int {
func (rc *runContainer16) removeKey(key uint16) (wasPresent bool) { func (rc *runContainer16) removeKey(key uint16) (wasPresent bool) {
var index int64 var index int64
index, wasPresent, _ = rc.search(int64(key), nil) index, wasPresent, _ = rc.search(int64(key))
if !wasPresent { if !wasPresent {
return // already removed, nothing to do. return // already removed, nothing to do.
} }
@ -1457,12 +1445,8 @@ func intersectWithLeftover16(astart, alast, bstart, blast int64) (isOverlap, isL
return return
} }
func (rc *runContainer16) findNextIntervalThatIntersectsStartingFrom(startIndex int64, key int64) (index int64, done bool) { func (rc *runContainer16) findNextIntervalThatIntersectsStartingFrom(startIndex int64, key int64) (index int64, done bool) {
w, _, _ := rc.searchRange(key, startIndex, 0)
rc.myOpts.startIndex = startIndex
rc.myOpts.endxIndex = 0
w, _, _ := rc.search(key, &rc.myOpts)
// rc.search always returns w < len(rc.iv) // rc.search always returns w < len(rc.iv)
if w < startIndex { if w < startIndex {
// not found and comes before lower bound startIndex, // not found and comes before lower bound startIndex,
@ -1603,8 +1587,8 @@ func (rc *runContainer16) isubtract(del interval16) {
} }
// INVAR there is some intersection between rc and del // INVAR there is some intersection between rc and del
istart, startAlready, _ := rc.search(int64(del.start), nil) istart, startAlready, _ := rc.search(int64(del.start))
ilast, lastAlready, _ := rc.search(int64(del.last()), nil) ilast, lastAlready, _ := rc.search(int64(del.last()))
rc.card = -1 rc.card = -1
if istart == -1 { if istart == -1 {
if ilast == n-1 && !lastAlready { if ilast == n-1 && !lastAlready {
@ -2356,7 +2340,7 @@ func (rc *runContainer16) getCardinality() int {
func (rc *runContainer16) rank(x uint16) int { func (rc *runContainer16) rank(x uint16) int {
n := int64(len(rc.iv)) n := int64(len(rc.iv))
xx := int64(x) xx := int64(x)
w, already, _ := rc.search(xx, nil) w, already, _ := rc.search(xx)
if w < 0 { if w < 0 {
return 0 return 0
} }

File diff suppressed because it is too large Load Diff

@ -3,8 +3,6 @@ package roaring
import ( import (
"encoding/binary" "encoding/binary"
"io" "io"
"github.com/tinylib/msgp/msgp"
) )
// writeTo for runContainer16 follows this // writeTo for runContainer16 follows this
@ -19,16 +17,3 @@ func (b *runContainer16) writeTo(stream io.Writer) (int, error) {
} }
return stream.Write(buf) return stream.Write(buf)
} }
func (b *runContainer16) writeToMsgpack(stream io.Writer) (int, error) {
bts, err := b.MarshalMsg(nil)
if err != nil {
return 0, err
}
return stream.Write(bts)
}
func (b *runContainer16) readFromMsgpack(stream io.Reader) (int, error) {
err := msgp.Decode(stream, b)
return 0, err
}

@ -177,6 +177,7 @@ func IsPrintableASCII(str string) bool
func IsRFC3339(str string) bool func IsRFC3339(str string) bool
func IsRFC3339WithoutZone(str string) bool func IsRFC3339WithoutZone(str string) bool
func IsRGBcolor(str string) bool func IsRGBcolor(str string) bool
func IsRegex(str string) bool
func IsRequestURI(rawurl string) bool func IsRequestURI(rawurl string) bool
func IsRequestURL(rawurl string) bool func IsRequestURL(rawurl string) bool
func IsRipeMD128(str string) bool func IsRipeMD128(str string) bool
@ -203,6 +204,7 @@ func IsUUID(str string) bool
func IsUUIDv3(str string) bool func IsUUIDv3(str string) bool
func IsUUIDv4(str string) bool func IsUUIDv4(str string) bool
func IsUUIDv5(str string) bool func IsUUIDv5(str string) bool
func IsULID(str string) bool
func IsUnixTime(str string) bool func IsUnixTime(str string) bool
func IsUpperCase(str string) bool func IsUpperCase(str string) bool
func IsVariableWidth(str string) bool func IsVariableWidth(str string) bool
@ -382,6 +384,7 @@ Here is a list of available validators for struct fields (validator - used funct
"rfc3339WithoutZone": IsRFC3339WithoutZone, "rfc3339WithoutZone": IsRFC3339WithoutZone,
"ISO3166Alpha2": IsISO3166Alpha2, "ISO3166Alpha2": IsISO3166Alpha2,
"ISO3166Alpha3": IsISO3166Alpha3, "ISO3166Alpha3": IsISO3166Alpha3,
"ulid": IsULID,
``` ```
Validators with parameters Validators with parameters

@ -42,6 +42,8 @@ const (
SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` SSN string = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$` WinPath string = `^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
UnixPath string = `^(/[^/\x00]*)+/?$` UnixPath string = `^(/[^/\x00]*)+/?$`
WinARPath string = `^(?:(?:[a-zA-Z]:|\\\\[a-z0-9_.$●-]+\\[a-z0-9_.$●-]+)\\|\\?[^\\/:*?"<>|\r\n]+\\?)(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$`
UnixARPath string = `^((\.{0,2}/)?([^/\x00]*))+/?$`
Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$" Semver string = "^v?(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(-(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*)?(\\+[0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)?$"
tagName string = "valid" tagName string = "valid"
hasLowerCase string = ".*[[:lower:]]" hasLowerCase string = ".*[[:lower:]]"
@ -50,6 +52,7 @@ const (
hasWhitespaceOnly string = "^[[:space:]]+$" hasWhitespaceOnly string = "^[[:space:]]+$"
IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$" IMEI string = "^[0-9a-f]{14}$|^\\d{15}$|^\\d{18}$"
IMSI string = "^\\d{14,15}$" IMSI string = "^\\d{14,15}$"
E164 string = `^\+?[1-9]\d{1,14}$`
) )
// Used by IsFilePath func // Used by IsFilePath func
@ -97,6 +100,8 @@ var (
rxSSN = regexp.MustCompile(SSN) rxSSN = regexp.MustCompile(SSN)
rxWinPath = regexp.MustCompile(WinPath) rxWinPath = regexp.MustCompile(WinPath)
rxUnixPath = regexp.MustCompile(UnixPath) rxUnixPath = regexp.MustCompile(UnixPath)
rxARWinPath = regexp.MustCompile(WinARPath)
rxARUnixPath = regexp.MustCompile(UnixARPath)
rxSemver = regexp.MustCompile(Semver) rxSemver = regexp.MustCompile(Semver)
rxHasLowerCase = regexp.MustCompile(hasLowerCase) rxHasLowerCase = regexp.MustCompile(hasLowerCase)
rxHasUpperCase = regexp.MustCompile(hasUpperCase) rxHasUpperCase = regexp.MustCompile(hasUpperCase)
@ -104,4 +109,5 @@ var (
rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly) rxHasWhitespaceOnly = regexp.MustCompile(hasWhitespaceOnly)
rxIMEI = regexp.MustCompile(IMEI) rxIMEI = regexp.MustCompile(IMEI)
rxIMSI = regexp.MustCompile(IMSI) rxIMSI = regexp.MustCompile(IMSI)
rxE164 = regexp.MustCompile(E164)
) )

@ -165,6 +165,7 @@ var TagMap = map[string]Validator{
"ISO3166Alpha3": IsISO3166Alpha3, "ISO3166Alpha3": IsISO3166Alpha3,
"ISO4217": IsISO4217, "ISO4217": IsISO4217,
"IMEI": IsIMEI, "IMEI": IsIMEI,
"ulid": IsULID,
} }
// ISO3166Entry stores country codes // ISO3166Entry stores country codes

@ -361,9 +361,96 @@ func IsUUID(str string) bool {
return rxUUID.MatchString(str) return rxUUID.MatchString(str)
} }
// Byte to index table for O(1) lookups when unmarshaling.
// We use 0xFF as sentinel value for invalid indexes.
var ulidDec = [...]byte{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E,
0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14,
0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}
// EncodedSize is the length of a text encoded ULID.
const ulidEncodedSize = 26
// IsULID checks if the string is a ULID.
//
// Implementation got from:
// https://github.com/oklog/ulid (Apache-2.0 License)
//
func IsULID(str string) bool {
// Check if a base32 encoded ULID is the right length.
if len(str) != ulidEncodedSize {
return false
}
// Check if all the characters in a base32 encoded ULID are part of the
// expected base32 character set.
if ulidDec[str[0]] == 0xFF ||
ulidDec[str[1]] == 0xFF ||
ulidDec[str[2]] == 0xFF ||
ulidDec[str[3]] == 0xFF ||
ulidDec[str[4]] == 0xFF ||
ulidDec[str[5]] == 0xFF ||
ulidDec[str[6]] == 0xFF ||
ulidDec[str[7]] == 0xFF ||
ulidDec[str[8]] == 0xFF ||
ulidDec[str[9]] == 0xFF ||
ulidDec[str[10]] == 0xFF ||
ulidDec[str[11]] == 0xFF ||
ulidDec[str[12]] == 0xFF ||
ulidDec[str[13]] == 0xFF ||
ulidDec[str[14]] == 0xFF ||
ulidDec[str[15]] == 0xFF ||
ulidDec[str[16]] == 0xFF ||
ulidDec[str[17]] == 0xFF ||
ulidDec[str[18]] == 0xFF ||
ulidDec[str[19]] == 0xFF ||
ulidDec[str[20]] == 0xFF ||
ulidDec[str[21]] == 0xFF ||
ulidDec[str[22]] == 0xFF ||
ulidDec[str[23]] == 0xFF ||
ulidDec[str[24]] == 0xFF ||
ulidDec[str[25]] == 0xFF {
return false
}
// Check if the first character in a base32 encoded ULID will overflow. This
// happens because the base32 representation encodes 130 bits, while the
// ULID is only 128 bits.
//
// See https://github.com/oklog/ulid/issues/9 for details.
if str[0] > '7' {
return false
}
return true
}
// IsCreditCard checks if the string is a credit card. // IsCreditCard checks if the string is a credit card.
func IsCreditCard(str string) bool { func IsCreditCard(str string) bool {
sanitized := notNumberRegexp.ReplaceAllString(str, "") sanitized := whiteSpacesAndMinus.ReplaceAllString(str, "")
if !rxCreditCard.MatchString(sanitized) { if !rxCreditCard.MatchString(sanitized) {
return false return false
} }
@ -509,6 +596,27 @@ func IsFilePath(str string) (bool, int) {
return false, Unknown return false, Unknown
} }
//IsWinFilePath checks both relative & absolute paths in Windows
func IsWinFilePath(str string) bool {
if rxARWinPath.MatchString(str) {
//check windows path limit see:
// http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
if len(str[3:]) > 32767 {
return false
}
return true
}
return false
}
//IsUnixFilePath checks both relative & absolute paths in Unix
func IsUnixFilePath(str string) bool {
if rxARUnixPath.MatchString(str) {
return true
}
return false
}
// IsDataURI checks if a string is base64 encoded data URI such as an image // IsDataURI checks if a string is base64 encoded data URI such as an image
func IsDataURI(str string) bool { func IsDataURI(str string) bool {
dataURI := strings.Split(str, ",") dataURI := strings.Split(str, ",")
@ -586,11 +694,13 @@ func IsHash(str string, algorithm string) bool {
len = "40" len = "40"
} else if algo == "tiger192" { } else if algo == "tiger192" {
len = "48" len = "48"
} else if algo == "sha256" { } else if algo == "sha3-224" {
len = "56"
} else if algo == "sha256" || algo == "sha3-256" {
len = "64" len = "64"
} else if algo == "sha384" { } else if algo == "sha384" || algo == "sha3-384" {
len = "96" len = "96"
} else if algo == "sha512" { } else if algo == "sha512" || algo == "sha3-512" {
len = "128" len = "128"
} else { } else {
return false return false
@ -599,6 +709,26 @@ func IsHash(str string, algorithm string) bool {
return Matches(str, "^[a-f0-9]{"+len+"}$") return Matches(str, "^[a-f0-9]{"+len+"}$")
} }
// IsSHA3224 checks is a string is a SHA3-224 hash. Alias for `IsHash(str, "sha3-224")`
func IsSHA3224(str string) bool {
return IsHash(str, "sha3-224")
}
// IsSHA3256 checks is a string is a SHA3-256 hash. Alias for `IsHash(str, "sha3-256")`
func IsSHA3256(str string) bool {
return IsHash(str, "sha3-256")
}
// IsSHA3384 checks is a string is a SHA3-384 hash. Alias for `IsHash(str, "sha3-384")`
func IsSHA3384(str string) bool {
return IsHash(str, "sha3-384")
}
// IsSHA3512 checks is a string is a SHA3-512 hash. Alias for `IsHash(str, "sha3-512")`
func IsSHA3512(str string) bool {
return IsHash(str, "sha3-512")
}
// IsSHA512 checks is a string is a SHA512 hash. Alias for `IsHash(str, "sha512")` // IsSHA512 checks is a string is a SHA512 hash. Alias for `IsHash(str, "sha512")`
func IsSHA512(str string) bool { func IsSHA512(str string) bool {
return IsHash(str, "sha512") return IsHash(str, "sha512")
@ -819,6 +949,14 @@ func IsRsaPublicKey(str string, keylen int) bool {
return bitlen == int(keylen) return bitlen == int(keylen)
} }
// IsRegex checks if a give string is a valid regex with RE2 syntax or not
func IsRegex(str string) bool {
if _, err := regexp.Compile(str); err == nil {
return true
}
return false
}
func toJSONName(tag string) string { func toJSONName(tag string) string {
if tag == "" { if tag == "" {
return "" return ""
@ -1625,3 +1763,7 @@ func (sv stringValues) Len() int { return len(sv) }
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) } func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
func (sv stringValues) get(i int) string { return sv[i].String() } func (sv stringValues) get(i int) string { return sv[i].String() }
func IsE164(str string) bool {
return rxE164.MatchString(str)
}

@ -0,0 +1,3 @@
*.test
*.out
.devcontainer/

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Salvador Cavadini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,52 @@
# garif
A GO package to create and manipulate SARIF logs.
SARIF, from _Static Analysis Results Interchange Format_, is a standard JSON-based format for the output of static analysis tools defined and promoted by [OASIS](https://www.oasis-open.org/).
Current supported version of the standard is [SARIF-v2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html
).
## Usage
The package provides access to every element of the SARIF model, therefore you are free to manipulate it at every detail.
The package also provides constructors functions (`New...`) and decorators methods (`With...`) that simplify the creation of SARIF files for common use cases.
Using these constructors and decorators we can easily create the example SARIF file of the [Microsoft SARIF pages](https://github.com/microsoft/sarif-tutorials/blob/master/docs/1-Introduction.md)
```go
import to `github.com/chavacava/garif`
// ...
rule := garif.NewRule("no-unused-vars").
WithHelpUri("https://eslint.org/docs/rules/no-unused-vars").
WithShortDescription("disallow unused variables").
WithProperties("category", "Variables")
driver := garif.NewDriver("ESLint").
WithInformationUri("https://eslint.org").
WithRules(rule)
run := garif.NewRun(NewTool(driver)).
WithArtifactsURIs("file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js")
run.WithResult(rule.Id, "'x' is assigned a value but never used.", "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js", 1, 5)
logFile := garif.NewLogFile([]*Run{run}, Version210)
logFile.Write(os.Stdout)
```
## Why this package?
This package was initiated during my works on adding to [`revive`](https://github.com/mgechev/revive) a SARIF output formatter.
I've tried to use [go-sarif](https://github.com/owenrumney/go-sarif) by [Owen Rumney](https://github.com/owenrumney) but it is too focused in the use case of the static analyzer [tfsec](https://tfsec.dev) so I've decided to create a package flexible enough to generate SARIF files in broader cases.
## More information about SARIF
For more information about SARIF, you can visit the [Oasis Open](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=sarif) site.
## Contributing
Of course, contributions are welcome!

@ -0,0 +1,338 @@
package garif
// NewAddress creates a valid Address
func NewAddress() *Address {
return &Address{}
}
// NewArtifact creates a valid Artifact
func NewArtifact() *Artifact {
return &Artifact{}
}
// NewArtifactChange creates a valid ArtifactChange
func NewArtifactChange(location *ArtifactLocation, replacements ...*Replacement) *ArtifactChange {
return &ArtifactChange{
ArtifactLocation: location,
Replacements: replacements,
}
}
// NewArtifactContent creates a valid ArtifactContent
func NewArtifactContent() *ArtifactContent {
return &ArtifactContent{}
}
// NewArtifactLocation creates a valid ArtifactLocation
func NewArtifactLocation() *ArtifactLocation {
return &ArtifactLocation{}
}
// NewAttachment creates a valid Attachment
func NewAttachment(location *ArtifactLocation) *Attachment {
return &Attachment{ArtifactLocation: location}
}
// NewCodeFlow creates a valid CodeFlow
func NewCodeFlow(threadFlows ...*ThreadFlow) *CodeFlow {
return &CodeFlow{ThreadFlows: threadFlows}
}
// NewConfigurationOverride creates a valid ConfigurationOverride
func NewConfigurationOverride(configuration *ReportingConfiguration, descriptor *ReportingDescriptorReference) *ConfigurationOverride {
return &ConfigurationOverride{
Configuration: configuration,
Descriptor: descriptor,
}
}
// NewConversion creates a valid Conversion
func NewConversion(tool *Tool) *Conversion {
return &Conversion{Tool: tool}
}
// NewEdge creates a valid Edge
func NewEdge(id, sourceNodeId, targetNodeId string) *Edge {
return &Edge{
Id: id,
SourceNodeId: sourceNodeId,
TargetNodeId: targetNodeId,
}
}
// NewEdgeTraversal creates a valid EdgeTraversal
func NewEdgeTraversal(edgeId string) *EdgeTraversal {
return &EdgeTraversal{
EdgeId: edgeId,
}
}
// NewException creates a valid Exception
func NewException() *Exception {
return &Exception{}
}
// NewExternalProperties creates a valid ExternalProperties
func NewExternalProperties() *ExternalProperties {
return &ExternalProperties{}
}
// NewExternalPropertyFileReference creates a valid ExternalPropertyFileReference
func NewExternalPropertyFileReference() *ExternalPropertyFileReference {
return &ExternalPropertyFileReference{}
}
// NewExternalPropertyFileReferences creates a valid ExternalPropertyFileReferences
func NewExternalPropertyFileReferences() *ExternalPropertyFileReferences {
return &ExternalPropertyFileReferences{}
}
// NewFix creates a valid Fix
func NewFix(artifactChanges ...*ArtifactChange) *Fix {
return &Fix{
ArtifactChanges: artifactChanges,
}
}
// NewGraph creates a valid Graph
func NewGraph() *Graph {
return &Graph{}
}
// NewGraphTraversal creates a valid GraphTraversal
func NewGraphTraversal() *GraphTraversal {
return &GraphTraversal{}
}
// NewInvocation creates a valid Invocation
func NewInvocation(executionSuccessful bool) *Invocation {
return &Invocation{
ExecutionSuccessful: executionSuccessful,
}
}
// NewLocation creates a valid Location
func NewLocation() *Location {
return &Location{}
}
// NewLocationRelationship creates a valid LocationRelationship
func NewLocationRelationship(target int) *LocationRelationship {
return &LocationRelationship{
Target: target,
}
}
type LogFileVersion string
const Version210 LogFileVersion = "2.1.0"
// NewLogFile creates a valid LogFile
func NewLogFile(runs []*Run, version LogFileVersion) *LogFile {
return &LogFile{
Runs: runs,
Version: version,
}
}
// NewLogicalLocation creates a valid LogicalLocation
func NewLogicalLocation() *LogicalLocation {
return &LogicalLocation{}
}
// NewMessage creates a valid Message
func NewMessage() *Message {
return &Message{}
}
// NewMessageFromText creates a valid Message with the given text
func NewMessageFromText(text string) *Message {
return &Message{
Text: text,
}
}
// NewMultiformatMessageString creates a valid MultiformatMessageString
func NewMultiformatMessageString(text string) *MultiformatMessageString {
return &MultiformatMessageString{
Text: text,
}
}
// NewNode creates a valid Node
func NewNode(id string) *Node {
return &Node{
Id: id,
}
}
// NewNotification creates a valid Notification
func NewNotification(message *Message) *Notification {
return &Notification{
Message: message,
}
}
// NewPhysicalLocation creates a valid PhysicalLocation
func NewPhysicalLocation() *PhysicalLocation {
return &PhysicalLocation{}
}
// NewPropertyBag creates a valid PropertyBag
func NewPropertyBag() *PropertyBag {
return &PropertyBag{}
}
// NewRectangle creates a valid Rectangle
func NewRectangle() *Rectangle {
return &Rectangle{}
}
// NewRegion creates a valid Region
func NewRegion() *Region {
return &Region{}
}
// NewReplacement creates a valid Replacement
func NewReplacement(deletedRegion *Region) *Replacement {
return &Replacement{
DeletedRegion: deletedRegion,
}
}
// NewReportingConfiguration creates a valid ReportingConfiguration
func NewReportingConfiguration() *ReportingConfiguration {
return &ReportingConfiguration{}
}
// NewReportingDescriptor creates a valid ReportingDescriptor
func NewReportingDescriptor(id string) *ReportingDescriptor {
return &ReportingDescriptor{
Id: id,
}
}
// NewRule is an alias for NewReportingDescriptor
func NewRule(id string) *ReportingDescriptor {
return NewReportingDescriptor(id)
}
// NewReportingDescriptorReference creates a valid ReportingDescriptorReference
func NewReportingDescriptorReference() *ReportingDescriptorReference {
return &ReportingDescriptorReference{}
}
// NewReportingDescriptorRelationship creates a valid ReportingDescriptorRelationship
func NewReportingDescriptorRelationship(target *ReportingDescriptorReference) *ReportingDescriptorRelationship {
return &ReportingDescriptorRelationship{
Target: target,
}
}
// NewResult creates a valid Result
func NewResult(message *Message) *Result {
return &Result{
Message: message,
}
}
// NewResultProvenance creates a valid ResultProvenance
func NewResultProvenance() *ResultProvenance {
return &ResultProvenance{}
}
// NewRun creates a valid Run
func NewRun(tool *Tool) *Run {
return &Run{
Tool: tool,
}
}
// NewRunAutomationDetails creates a valid RunAutomationDetails
func NewRunAutomationDetails() *RunAutomationDetails {
return &RunAutomationDetails{}
}
// New creates a valid
func NewSpecialLocations() *SpecialLocations {
return &SpecialLocations{}
}
// NewStack creates a valid Stack
func NewStack(frames ...*StackFrame) *Stack {
return &Stack{
Frames: frames,
}
}
// NewStackFrame creates a valid StackFrame
func NewStackFrame() *StackFrame {
return &StackFrame{}
}
// NewSuppression creates a valid Suppression
func NewSuppression(kind string) *Suppression {
return &Suppression{
Kind: kind,
}
}
// NewThreadFlow creates a valid ThreadFlow
func NewThreadFlow(locations []*ThreadFlowLocation) *ThreadFlow {
return &ThreadFlow{
Locations: locations,
}
}
// NewThreadFlowLocation creates a valid ThreadFlowLocation
func NewThreadFlowLocation() *ThreadFlowLocation {
return &ThreadFlowLocation{}
}
// NewTool creates a valid Tool
func NewTool(driver *ToolComponent) *Tool {
return &Tool{
Driver: driver,
}
}
// NewToolComponent creates a valid ToolComponent
func NewToolComponent(name string) *ToolComponent {
return &ToolComponent{
Name: name,
}
}
// NewDriver is an alias for NewToolComponent
func NewDriver(name string) *ToolComponent {
return NewToolComponent(name)
}
// NewToolComponentReference creates a valid ToolComponentReference
func NewToolComponentReference() *ToolComponentReference {
return &ToolComponentReference{}
}
// NewTranslationMetadata creates a valid TranslationMetadata
func NewTranslationMetadata(name string) *TranslationMetadata {
return &TranslationMetadata{
Name: name,
}
}
// NewVersionControlDetails creates a valid VersionControlDetails
func NewVersionControlDetails(repositoryUri string) *VersionControlDetails {
return &VersionControlDetails{
RepositoryUri: repositoryUri,
}
}
// NewWebRequest creates a valid WebRequest
func NewWebRequest() *WebRequest {
return &WebRequest{}
}
// NewWebResponse creates a valid WebResponse
func NewWebResponse() *WebResponse {
return &WebResponse{}
}

@ -0,0 +1,94 @@
package garif
// WithLineColumn sets a physical location with the given line and column
func (l *Location) WithLineColumn(line, column int) *Location {
if l.PhysicalLocation == nil {
l.PhysicalLocation = NewPhysicalLocation()
}
l.PhysicalLocation.Region = NewRegion()
l.PhysicalLocation.Region.StartLine = line
l.PhysicalLocation.Region.StartColumn = column
return l
}
// WithURI sets a physical location with the given URI
func (l *Location) WithURI(uri string) *Location {
if l.PhysicalLocation == nil {
l.PhysicalLocation = NewPhysicalLocation()
}
l.PhysicalLocation.ArtifactLocation = NewArtifactLocation()
l.PhysicalLocation.ArtifactLocation.Uri = uri
return l
}
// WithKeyValue sets (overwrites) the value of the given key
func (b PropertyBag) WithKeyValue(key string, value interface{}) PropertyBag {
b[key] = value
return b
}
// WithHelpUri sets the help URI for this ReportingDescriptor
func (r *ReportingDescriptor) WithHelpUri(uri string) *ReportingDescriptor {
r.HelpUri = uri
return r
}
// WithProperties adds the key & value to the properties of this ReportingDescriptor
func (r *ReportingDescriptor) WithProperties(key string, value interface{}) *ReportingDescriptor {
if r.Properties == nil {
r.Properties = NewPropertyBag()
}
r.Properties.WithKeyValue(key, value)
return r
}
// WithArtifactsURIs adds the given URI as artifacts of this Run
func (r *Run) WithArtifactsURIs(uris ...string) *Run {
if r.Artifacts == nil {
r.Artifacts = []*Artifact{}
}
for _, uri := range uris {
a := NewArtifact()
a.Location = NewArtifactLocation()
a.Location.Uri = uri
r.Artifacts = append(r.Artifacts, a)
}
return r
}
// WithResult adds a result to this Run
func (r *Run) WithResult(ruleId string, message string, uri string, line int, column int) *Run {
if r.Results == nil {
r.Results = []*Result{}
}
msg := NewMessage()
msg.Text = message
result := NewResult(msg)
location := NewLocation().WithURI(uri).WithLineColumn(line, column)
result.Locations = append(result.Locations, location)
result.RuleId = ruleId
r.Results = append(r.Results, result)
return r
}
// WithInformationUri sets the information URI
func (t *ToolComponent) WithInformationUri(uri string) *ToolComponent {
t.InformationUri = uri
return t
}
// WithRules sets (overwrites) the rules
func (t *ToolComponent) WithRules(rules ...*ReportingDescriptor) *ToolComponent {
t.Rules = rules
return t
}

@ -0,0 +1,11 @@
// Package garif defines all the GO structures required to model a SARIF log file.
// These structures were created using the JSON-schema sarif-schema-2.1.0.json of SARIF logfiles
// available at https://github.com/oasis-tcs/sarif-spec/tree/master/Schemata.
//
// The package provides constructors for all structures (see constructors.go) These constructors
// ensure that the returned structure instantiation is valid with respect to the JSON schema and
// should be used in place of plain structure instantiation.
// The root structure is LogFile.
//
// The package provides utility decorators for the most commonly used structures (see decorators.go)
package garif

@ -0,0 +1,5 @@
module github.com/chavacava/garif
go 1.16
require github.com/stretchr/testify v1.7.0

@ -0,0 +1,11 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -0,0 +1,26 @@
package garif
import (
"encoding/json"
"io"
)
// Write writes the JSON
func (l *LogFile) Write(w io.Writer) error {
marshal, err := json.Marshal(l)
if err != nil {
return err
}
_, err = w.Write(marshal)
return err
}
// PrettyWrite writes indented JSON
func (l *LogFile) PrettyWrite(w io.Writer) error {
marshal, err := json.MarshalIndent(l, "", " ")
if err != nil {
return err
}
_, err = w.Write(marshal)
return err
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,8 @@
/.idea
/.connstr
.vscode
.terraform
*.tfstate*
*.log
*.swp
*~

@ -0,0 +1,10 @@
linters:
enable:
# basic go linters
- gofmt
- golint
- govet
# sql related linters
- rowserrcheck
- sqlclosecheck

@ -6,19 +6,8 @@ import (
"context" "context"
"database/sql/driver" "database/sql/driver"
"errors" "errors"
"fmt"
) )
var _ driver.Connector = &accessTokenConnector{}
// accessTokenConnector wraps Connector and injects a
// fresh access token when connecting to the database
type accessTokenConnector struct {
Connector
accessTokenProvider func() (string, error)
}
// NewAccessTokenConnector creates a new connector from a DSN and a token provider. // NewAccessTokenConnector creates a new connector from a DSN and a token provider.
// The token provider func will be called when a new connection is requested and should return a valid access token. // The token provider func will be called when a new connection is requested and should return a valid access token.
// The returned connector may be used with sql.OpenDB. // The returned connector may be used with sql.OpenDB.
@ -32,20 +21,10 @@ func NewAccessTokenConnector(dsn string, tokenProvider func() (string, error)) (
return nil, err return nil, err
} }
c := &accessTokenConnector{ conn.params.fedAuthLibrary = fedAuthLibrarySecurityToken
Connector: *conn, conn.securityTokenProvider = func(ctx context.Context) (string, error) {
accessTokenProvider: tokenProvider, return tokenProvider()
}
return c, nil
}
// Connect returns a new database connection
func (c *accessTokenConnector) Connect(ctx context.Context) (driver.Conn, error) {
var err error
c.Connector.params.fedAuthAccessToken, err = c.accessTokenProvider()
if err != nil {
return nil, fmt.Errorf("mssql: error retrieving access token: %+v", err)
} }
return c.Connector.Connect(ctx) return conn, nil
} }

@ -39,6 +39,9 @@ environment:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
GOVERSION: 115 GOVERSION: 115
SQLINSTANCE: SQL2017 SQLINSTANCE: SQL2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
GOVERSION: 116
SQLINSTANCE: SQL2017
install: install:
- set GOROOT=c:\go%GOVERSION% - set GOROOT=c:\go%GOVERSION%

@ -48,8 +48,8 @@ type tdsBuffer struct {
func newTdsBuffer(bufsize uint16, transport io.ReadWriteCloser) *tdsBuffer { func newTdsBuffer(bufsize uint16, transport io.ReadWriteCloser) *tdsBuffer {
return &tdsBuffer{ return &tdsBuffer{
packetSize: int(bufsize), packetSize: int(bufsize),
wbuf: make([]byte, 1<<16), wbuf: make([]byte, bufsize),
rbuf: make([]byte, 1<<16), rbuf: make([]byte, bufsize),
rpos: 8, rpos: 8,
transport: transport, transport: transport,
} }
@ -137,19 +137,28 @@ func (w *tdsBuffer) FinishPacket() error {
var headerSize = binary.Size(header{}) var headerSize = binary.Size(header{})
func (r *tdsBuffer) readNextPacket() error { func (r *tdsBuffer) readNextPacket() error {
h := header{} buf := r.rbuf[:headerSize]
var err error _, err := io.ReadFull(r.transport, buf)
err = binary.Read(r.transport, binary.BigEndian, &h)
if err != nil { if err != nil {
return err return err
} }
h := header{
PacketType: packetType(buf[0]),
Status: buf[1],
Size: binary.BigEndian.Uint16(buf[2:4]),
Spid: binary.BigEndian.Uint16(buf[4:6]),
PacketNo: buf[6],
Pad: buf[7],
}
if int(h.Size) > r.packetSize { if int(h.Size) > r.packetSize {
return errors.New("Invalid packet size, it is longer than buffer size") return errors.New("invalid packet size, it is longer than buffer size")
} }
if headerSize > int(h.Size) { if headerSize > int(h.Size) {
return errors.New("Invalid packet size, it is shorter than header size") return errors.New("invalid packet size, it is shorter than header size")
} }
_, err = io.ReadFull(r.transport, r.rbuf[headerSize:h.Size]) _, err = io.ReadFull(r.transport, r.rbuf[headerSize:h.Size])
//s := base64.StdEncoding.EncodeToString(r.rbuf[headerSize:h.Size])
//fmt.Print(s)
if err != nil { if err != nil {
return err return err
} }

@ -44,8 +44,9 @@ type BulkOptions struct {
type DataValue interface{} type DataValue interface{}
const ( const (
sqlDateFormat = "2006-01-02" sqlDateFormat = "2006-01-02"
sqlTimeFormat = "2006-01-02 15:04:05.999999999Z07:00" sqlDateTimeFormat = "2006-01-02 15:04:05.999999999Z07:00"
sqlTimeFormat = "15:04:05.9999999"
) )
func (cn *Conn) CreateBulk(table string, columns []string) (_ *Bulk) { func (cn *Conn) CreateBulk(table string, columns []string) (_ *Bulk) {
@ -86,7 +87,7 @@ func (b *Bulk) sendBulkCommand(ctx context.Context) (err error) {
b.bulkColumns = append(b.bulkColumns, *bulkCol) b.bulkColumns = append(b.bulkColumns, *bulkCol)
b.dlogf("Adding column %s %s %#x", colname, bulkCol.ColName, bulkCol.ti.TypeId) b.dlogf("Adding column %s %s %#x", colname, bulkCol.ColName, bulkCol.ti.TypeId)
} else { } else {
return fmt.Errorf("Column %s does not exist in destination table %s", colname, b.tablename) return fmt.Errorf("column %s does not exist in destination table %s", colname, b.tablename)
} }
} }
@ -166,7 +167,7 @@ func (b *Bulk) AddRow(row []interface{}) (err error) {
} }
if len(row) != len(b.bulkColumns) { if len(row) != len(b.bulkColumns) {
return fmt.Errorf("Row does not have the same number of columns than the destination table %d %d", return fmt.Errorf("row does not have the same number of columns than the destination table %d %d",
len(row), len(b.bulkColumns)) len(row), len(b.bulkColumns))
} }
@ -215,7 +216,7 @@ func (b *Bulk) makeRowData(row []interface{}) ([]byte, error) {
} }
func (b *Bulk) Done() (rowcount int64, err error) { func (b *Bulk) Done() (rowcount int64, err error) {
if b.headerSent == false { if !b.headerSent {
//no rows had been sent //no rows had been sent
return 0, nil return 0, nil
} }
@ -233,24 +234,13 @@ func (b *Bulk) Done() (rowcount int64, err error) {
buf.FinishPacket() buf.FinishPacket()
tokchan := make(chan tokenStruct, 5) reader := startReading(b.cn.sess, b.ctx, nil)
go processResponse(b.ctx, b.cn.sess, tokchan, nil) err = reader.iterateResponse()
if err != nil {
var rowCount int64 return 0, b.cn.checkBadConn(err)
for token := range tokchan {
switch token := token.(type) {
case doneStruct:
if token.Status&doneCount != 0 {
rowCount = int64(token.RowCount)
}
if token.isError() {
return 0, token.getError()
}
case error:
return 0, b.cn.checkBadConn(token)
}
} }
return rowCount, nil
return reader.rowCount, nil
} }
func (b *Bulk) createColMetadata() []byte { func (b *Bulk) createColMetadata() []byte {
@ -421,7 +411,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
res.ti.Size = len(res.buffer) res.ti.Size = len(res.buffer)
case string: case string:
var t time.Time var t time.Time
if t, err = time.Parse(sqlTimeFormat, val); err != nil { if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err) return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
} }
res.buffer = encodeDateTime2(t, int(col.ti.Scale)) res.buffer = encodeDateTime2(t, int(col.ti.Scale))
@ -437,7 +427,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
res.ti.Size = len(res.buffer) res.ti.Size = len(res.buffer)
case string: case string:
var t time.Time var t time.Time
if t, err = time.Parse(sqlTimeFormat, val); err != nil { if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err) return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
} }
res.buffer = encodeDateTimeOffset(t, int(col.ti.Scale)) res.buffer = encodeDateTimeOffset(t, int(col.ti.Scale))
@ -468,7 +458,7 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
case time.Time: case time.Time:
t = val t = val
case string: case string:
if t, err = time.Parse(sqlTimeFormat, val); err != nil { if t, err = time.Parse(sqlDateTimeFormat, val); err != nil {
return res, fmt.Errorf("bulk: unable to convert string to date: %v", err) return res, fmt.Errorf("bulk: unable to convert string to date: %v", err)
} }
default: default:
@ -485,7 +475,22 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error)
} else { } else {
err = fmt.Errorf("mssql: invalid size of column %d", col.ti.Size) err = fmt.Errorf("mssql: invalid size of column %d", col.ti.Size)
} }
case typeTimeN:
var t time.Time
switch val := val.(type) {
case time.Time:
res.buffer = encodeTime(val.Hour(), val.Minute(), val.Second(), val.Nanosecond(), int(col.ti.Scale))
res.ti.Size = len(res.buffer)
case string:
if t, err = time.Parse(sqlTimeFormat, val); err != nil {
return res, fmt.Errorf("bulk: unable to convert string to time: %v", err)
}
res.buffer = encodeTime(t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), int(col.ti.Scale))
res.ti.Size = len(res.buffer)
default:
err = fmt.Errorf("mssql: invalid type for time column: %T %s", val, val)
return
}
// case typeMoney, typeMoney4, typeMoneyN: // case typeMoney, typeMoney4, typeMoneyN:
case typeDecimal, typeDecimalN, typeNumeric, typeNumericN: case typeDecimal, typeDecimalN, typeNumeric, typeNumericN:
prec := col.ti.Prec prec := col.ti.Prec

@ -37,11 +37,17 @@ type connectParams struct {
failOverPartner string failOverPartner string
failOverPort uint64 failOverPort uint64
packetSize uint16 packetSize uint16
fedAuthAccessToken string fedAuthLibrary int
fedAuthADALWorkflow byte
} }
// default packet size for TDS buffer
const defaultPacketSize = 4096
func parseConnectParams(dsn string) (connectParams, error) { func parseConnectParams(dsn string) (connectParams, error) {
var p connectParams p := connectParams{
fedAuthLibrary: fedAuthLibraryReserved,
}
var params map[string]string var params map[string]string
if strings.HasPrefix(dsn, "odbc:") { if strings.HasPrefix(dsn, "odbc:") {
@ -65,7 +71,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
var err error var err error
p.logFlags, err = strconv.ParseUint(strlog, 10, 64) p.logFlags, err = strconv.ParseUint(strlog, 10, 64)
if err != nil { if err != nil {
return p, fmt.Errorf("Invalid log parameter '%s': %s", strlog, err.Error()) return p, fmt.Errorf("invalid log parameter '%s': %s", strlog, err.Error())
} }
} }
server := params["server"] server := params["server"]
@ -87,20 +93,19 @@ func parseConnectParams(dsn string) (connectParams, error) {
var err error var err error
p.port, err = strconv.ParseUint(strport, 10, 16) p.port, err = strconv.ParseUint(strport, 10, 16)
if err != nil { if err != nil {
f := "Invalid tcp port '%v': %v" f := "invalid tcp port '%v': %v"
return p, fmt.Errorf(f, strport, err.Error()) return p, fmt.Errorf(f, strport, err.Error())
} }
} }
// https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-network-packet-size-server-configuration-option // https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-network-packet-size-server-configuration-option
// Default packet size remains at 4096 bytes p.packetSize = defaultPacketSize
p.packetSize = 4096
strpsize, ok := params["packet size"] strpsize, ok := params["packet size"]
if ok { if ok {
var err error var err error
psize, err := strconv.ParseUint(strpsize, 0, 16) psize, err := strconv.ParseUint(strpsize, 0, 16)
if err != nil { if err != nil {
f := "Invalid packet size '%v': %v" f := "invalid packet size '%v': %v"
return p, fmt.Errorf(f, strpsize, err.Error()) return p, fmt.Errorf(f, strpsize, err.Error())
} }
@ -123,7 +128,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
if strconntimeout, ok := params["connection timeout"]; ok { if strconntimeout, ok := params["connection timeout"]; ok {
timeout, err := strconv.ParseUint(strconntimeout, 10, 64) timeout, err := strconv.ParseUint(strconntimeout, 10, 64)
if err != nil { if err != nil {
f := "Invalid connection timeout '%v': %v" f := "invalid connection timeout '%v': %v"
return p, fmt.Errorf(f, strconntimeout, err.Error()) return p, fmt.Errorf(f, strconntimeout, err.Error())
} }
p.conn_timeout = time.Duration(timeout) * time.Second p.conn_timeout = time.Duration(timeout) * time.Second
@ -132,7 +137,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
if strdialtimeout, ok := params["dial timeout"]; ok { if strdialtimeout, ok := params["dial timeout"]; ok {
timeout, err := strconv.ParseUint(strdialtimeout, 10, 64) timeout, err := strconv.ParseUint(strdialtimeout, 10, 64)
if err != nil { if err != nil {
f := "Invalid dial timeout '%v': %v" f := "invalid dial timeout '%v': %v"
return p, fmt.Errorf(f, strdialtimeout, err.Error()) return p, fmt.Errorf(f, strdialtimeout, err.Error())
} }
p.dial_timeout = time.Duration(timeout) * time.Second p.dial_timeout = time.Duration(timeout) * time.Second
@ -144,7 +149,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
if keepAlive, ok := params["keepalive"]; ok { if keepAlive, ok := params["keepalive"]; ok {
timeout, err := strconv.ParseUint(keepAlive, 10, 64) timeout, err := strconv.ParseUint(keepAlive, 10, 64)
if err != nil { if err != nil {
f := "Invalid keepAlive value '%s': %s" f := "invalid keepAlive value '%s': %s"
return p, fmt.Errorf(f, keepAlive, err.Error()) return p, fmt.Errorf(f, keepAlive, err.Error())
} }
p.keepAlive = time.Duration(timeout) * time.Second p.keepAlive = time.Duration(timeout) * time.Second
@ -157,7 +162,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
var err error var err error
p.encrypt, err = strconv.ParseBool(encrypt) p.encrypt, err = strconv.ParseBool(encrypt)
if err != nil { if err != nil {
f := "Invalid encrypt '%s': %s" f := "invalid encrypt '%s': %s"
return p, fmt.Errorf(f, encrypt, err.Error()) return p, fmt.Errorf(f, encrypt, err.Error())
} }
} }
@ -169,7 +174,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
var err error var err error
p.trustServerCertificate, err = strconv.ParseBool(trust) p.trustServerCertificate, err = strconv.ParseBool(trust)
if err != nil { if err != nil {
f := "Invalid trust server certificate '%s': %s" f := "invalid trust server certificate '%s': %s"
return p, fmt.Errorf(f, trust, err.Error()) return p, fmt.Errorf(f, trust, err.Error())
} }
} }
@ -209,7 +214,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
if ok { if ok {
if appintent == "ReadOnly" { if appintent == "ReadOnly" {
if p.database == "" { if p.database == "" {
return p, fmt.Errorf("Database must be specified when ApplicationIntent is ReadOnly") return p, fmt.Errorf("database must be specified when ApplicationIntent is ReadOnly")
} }
p.typeFlags |= fReadOnlyIntent p.typeFlags |= fReadOnlyIntent
} }
@ -225,7 +230,7 @@ func parseConnectParams(dsn string) (connectParams, error) {
var err error var err error
p.failOverPort, err = strconv.ParseUint(failOverPort, 0, 16) p.failOverPort, err = strconv.ParseUint(failOverPort, 0, 16)
if err != nil { if err != nil {
f := "Invalid tcp port '%v': %v" f := "invalid tcp port '%v': %v"
return p, fmt.Errorf(f, failOverPort, err.Error()) return p, fmt.Errorf(f, failOverPort, err.Error())
} }
} }
@ -233,6 +238,30 @@ func parseConnectParams(dsn string) (connectParams, error) {
return p, nil return p, nil
} }
// convert connectionParams to url style connection string
// used mostly for testing
func (p connectParams) toUrl() *url.URL {
q := url.Values{}
if p.database != "" {
q.Add("database", p.database)
}
if p.logFlags != 0 {
q.Add("log", strconv.FormatUint(p.logFlags, 10))
}
res := url.URL{
Scheme: "sqlserver",
Host: p.host,
User: url.UserPassword(p.user, p.password),
}
if p.instance != "" {
res.Path = p.instance
}
if len(q) > 0 {
res.RawQuery = q.Encode()
}
return &res
}
func splitConnectionString(dsn string) (res map[string]string) { func splitConnectionString(dsn string) (res map[string]string) {
res = map[string]string{} res = map[string]string{}
parts := strings.Split(dsn, ";") parts := strings.Split(dsn, ";")
@ -340,7 +369,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
case parserStateBeforeKey: case parserStateBeforeKey:
switch { switch {
case c == '=': case c == '=':
return res, fmt.Errorf("Unexpected character = at index %d. Expected start of key or semi-colon or whitespace.", i) return res, fmt.Errorf("unexpected character = at index %d. Expected start of key or semi-colon or whitespace", i)
case !unicode.IsSpace(c) && c != ';': case !unicode.IsSpace(c) && c != ';':
state = parserStateKey state = parserStateKey
key += string(c) key += string(c)
@ -419,7 +448,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
case unicode.IsSpace(c): case unicode.IsSpace(c):
// Ignore whitespace // Ignore whitespace
default: default:
return res, fmt.Errorf("Unexpected character %c at index %d. Expected semi-colon or whitespace.", c, i) return res, fmt.Errorf("unexpected character %c at index %d. Expected semi-colon or whitespace", c, i)
} }
case parserStateEndValue: case parserStateEndValue:
@ -429,7 +458,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
case unicode.IsSpace(c): case unicode.IsSpace(c):
// Ignore whitespace // Ignore whitespace
default: default:
return res, fmt.Errorf("Unexpected character %c at index %d. Expected semi-colon or whitespace.", c, i) return res, fmt.Errorf("unexpected character %c at index %d. Expected semi-colon or whitespace", c, i)
} }
} }
} }
@ -444,7 +473,7 @@ func splitConnectionStringOdbc(dsn string) (map[string]string, error) {
case parserStateBareValue: case parserStateBareValue:
res[key] = strings.TrimRightFunc(value, unicode.IsSpace) res[key] = strings.TrimRightFunc(value, unicode.IsSpace)
case parserStateBracedValue: case parserStateBracedValue:
return res, fmt.Errorf("Unexpected end of braced value at index %d.", len(dsn)) return res, fmt.Errorf("unexpected end of braced value at index %d", len(dsn))
case parserStateBracedValueClosingBrace: // End of braced value case parserStateBracedValueClosingBrace: // End of braced value
res[key] = value res[key] = value
case parserStateEndValue: // Okay case parserStateEndValue: // Okay

@ -0,0 +1,82 @@
package mssql
import (
"context"
"errors"
)
// Federated authentication library affects the login data structure and message sequence.
const (
// fedAuthLibraryLiveIDCompactToken specifies the Microsoft Live ID Compact Token authentication scheme
fedAuthLibraryLiveIDCompactToken = 0x00
// fedAuthLibrarySecurityToken specifies a token-based authentication where the token is available
// without additional information provided during the login sequence.
fedAuthLibrarySecurityToken = 0x01
// fedAuthLibraryADAL specifies a token-based authentication where a token is obtained during the
// login sequence using the server SPN and STS URL provided by the server during login.
fedAuthLibraryADAL = 0x02
// fedAuthLibraryReserved is used to indicate that no federated authentication scheme applies.
fedAuthLibraryReserved = 0x7F
)
// Federated authentication ADAL workflow affects the mechanism used to authenticate.
const (
// fedAuthADALWorkflowPassword uses a username/password to obtain a token from Active Directory
fedAuthADALWorkflowPassword = 0x01
// fedAuthADALWorkflowPassword uses the Windows identity to obtain a token from Active Directory
fedAuthADALWorkflowIntegrated = 0x02
// fedAuthADALWorkflowMSI uses the managed identity service to obtain a token
fedAuthADALWorkflowMSI = 0x03
)
// newSecurityTokenConnector creates a new connector from a DSN and a token provider.
// When invoked, token provider implementations should contact the security token
// service specified and obtain the appropriate token, or return an error
// to indicate why a token is not available.
// The returned connector may be used with sql.OpenDB.
func newSecurityTokenConnector(dsn string, tokenProvider func(ctx context.Context) (string, error)) (*Connector, error) {
if tokenProvider == nil {
return nil, errors.New("mssql: tokenProvider cannot be nil")
}
conn, err := NewConnector(dsn)
if err != nil {
return nil, err
}
conn.params.fedAuthLibrary = fedAuthLibrarySecurityToken
conn.securityTokenProvider = tokenProvider
return conn, nil
}
// newADALTokenConnector creates a new connector from a DSN and a Active Directory token provider.
// Token provider implementations are called during federated
// authentication login sequences where the server provides a service
// principal name and security token service endpoint that should be used
// to obtain the token. Implementations should contact the security token
// service specified and obtain the appropriate token, or return an error
// to indicate why a token is not available.
//
// The returned connector may be used with sql.OpenDB.
func newActiveDirectoryTokenConnector(dsn string, adalWorkflow byte, tokenProvider func(ctx context.Context, serverSPN, stsURL string) (string, error)) (*Connector, error) {
if tokenProvider == nil {
return nil, errors.New("mssql: tokenProvider cannot be nil")
}
conn, err := NewConnector(dsn)
if err != nil {
return nil, err
}
conn.params.fedAuthLibrary = fedAuthLibraryADAL
conn.params.fedAuthADALWorkflow = adalWorkflow
conn.adalTokenProvider = tokenProvider
return conn, nil
}

@ -58,6 +58,7 @@ func (d *Driver) OpenConnector(dsn string) (*Connector, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Connector{ return &Connector{
params: params, params: params,
driver: d, driver: d,
@ -100,6 +101,12 @@ type Connector struct {
params connectParams params connectParams
driver *Driver driver *Driver
// callback that can provide a security token during login
securityTokenProvider func(ctx context.Context) (string, error)
// callback that can provide a security token during ADAL login
adalTokenProvider func(ctx context.Context, serverSPN, stsURL string) (string, error)
// SessionInitSQL is executed after marking a given session to be reset. // SessionInitSQL is executed after marking a given session to be reset.
// When not present, the next query will still reset the session to the // When not present, the next query will still reset the session to the
// database defaults. // database defaults.
@ -148,15 +155,7 @@ type Conn struct {
processQueryText bool processQueryText bool
connectionGood bool connectionGood bool
outs map[string]interface{} outs map[string]interface{}
returnStatus *ReturnStatus
}
func (c *Conn) setReturnStatus(s ReturnStatus) {
if c.returnStatus == nil {
return
}
*c.returnStatus = s
} }
func (c *Conn) checkBadConn(err error) error { func (c *Conn) checkBadConn(err error) error {
@ -201,20 +200,15 @@ func (c *Conn) clearOuts() {
} }
func (c *Conn) simpleProcessResp(ctx context.Context) error { func (c *Conn) simpleProcessResp(ctx context.Context) error {
tokchan := make(chan tokenStruct, 5) reader := startReading(c.sess, ctx, c.outs)
go processResponse(ctx, c.sess, tokchan, c.outs)
c.clearOuts() c.clearOuts()
for tok := range tokchan {
switch token := tok.(type) { var resultError error
case doneStruct: err := reader.iterateResponse()
if token.isError() { if err != nil {
return c.checkBadConn(token.getError()) return c.checkBadConn(err)
}
case error:
return c.checkBadConn(token)
}
} }
return nil return resultError
} }
func (c *Conn) Commit() error { func (c *Conn) Commit() error {
@ -239,7 +233,7 @@ func (c *Conn) sendCommitRequest() error {
c.sess.log.Printf("Failed to send CommitXact with %v", err) c.sess.log.Printf("Failed to send CommitXact with %v", err)
} }
c.connectionGood = false c.connectionGood = false
return fmt.Errorf("Faild to send CommitXact: %v", err) return fmt.Errorf("faild to send CommitXact: %v", err)
} }
return nil return nil
} }
@ -266,7 +260,7 @@ func (c *Conn) sendRollbackRequest() error {
c.sess.log.Printf("Failed to send RollbackXact with %v", err) c.sess.log.Printf("Failed to send RollbackXact with %v", err)
} }
c.connectionGood = false c.connectionGood = false
return fmt.Errorf("Failed to send RollbackXact: %v", err) return fmt.Errorf("failed to send RollbackXact: %v", err)
} }
return nil return nil
} }
@ -303,7 +297,7 @@ func (c *Conn) sendBeginRequest(ctx context.Context, tdsIsolation isoLevel) erro
c.sess.log.Printf("Failed to send BeginXact with %v", err) c.sess.log.Printf("Failed to send BeginXact with %v", err)
} }
c.connectionGood = false c.connectionGood = false
return fmt.Errorf("Failed to send BeginXact: %v", err) return fmt.Errorf("failed to send BeginXact: %v", err)
} }
return nil return nil
} }
@ -478,7 +472,7 @@ func (s *Stmt) sendQuery(args []namedValue) (err error) {
conn.sess.log.Printf("Failed to send Rpc with %v", err) conn.sess.log.Printf("Failed to send Rpc with %v", err)
} }
conn.connectionGood = false conn.connectionGood = false
return fmt.Errorf("Failed to send RPC: %v", err) return fmt.Errorf("failed to send RPC: %v", err)
} }
} }
return return
@ -595,38 +589,46 @@ func (s *Stmt) queryContext(ctx context.Context, args []namedValue) (rows driver
} }
func (s *Stmt) processQueryResponse(ctx context.Context) (res driver.Rows, err error) { func (s *Stmt) processQueryResponse(ctx context.Context) (res driver.Rows, err error) {
tokchan := make(chan tokenStruct, 5)
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
go processResponse(ctx, s.c.sess, tokchan, s.c.outs) reader := startReading(s.c.sess, ctx, s.c.outs)
s.c.clearOuts() s.c.clearOuts()
// process metadata // process metadata
var cols []columnStruct var cols []columnStruct
loop: loop:
for tok := range tokchan { for {
switch token := tok.(type) { tok, err := reader.nextToken()
// By ignoring DONE token we effectively if err == nil {
// skip empty result-sets. if tok == nil {
// This improves results in queries like that: break
// set nocount on; select 1 } else {
// see TestIgnoreEmptyResults test switch token := tok.(type) {
//case doneStruct: // By ignoring DONE token we effectively
//break loop // skip empty result-sets.
case []columnStruct: // This improves results in queries like that:
cols = token // set nocount on; select 1
break loop // see TestIgnoreEmptyResults test
case doneStruct: //case doneStruct:
if token.isError() { //break loop
cancel() case []columnStruct:
return nil, s.c.checkBadConn(token.getError()) cols = token
break loop
case doneStruct:
if token.isError() {
// need to cleanup cancellable context
cancel()
return nil, s.c.checkBadConn(token.getError())
}
case ReturnStatus:
s.c.sess.setReturnStatus(token)
}
} }
case ReturnStatus: } else {
s.c.setReturnStatus(token) // need to cleanup cancellable context
case error:
cancel() cancel()
return nil, s.c.checkBadConn(token) return nil, s.c.checkBadConn(err)
} }
} }
res = &Rows{stmt: s, tokchan: tokchan, cols: cols, cancel: cancel} res = &Rows{stmt: s, reader: reader, cols: cols, cancel: cancel}
return return
} }
@ -648,48 +650,46 @@ func (s *Stmt) exec(ctx context.Context, args []namedValue) (res driver.Result,
} }
func (s *Stmt) processExec(ctx context.Context) (res driver.Result, err error) { func (s *Stmt) processExec(ctx context.Context) (res driver.Result, err error) {
tokchan := make(chan tokenStruct, 5) reader := startReading(s.c.sess, ctx, s.c.outs)
go processResponse(ctx, s.c.sess, tokchan, s.c.outs)
s.c.clearOuts() s.c.clearOuts()
var rowCount int64 err = reader.iterateResponse()
for token := range tokchan { if err != nil {
switch token := token.(type) { return nil, s.c.checkBadConn(err)
case doneInProcStruct:
if token.Status&doneCount != 0 {
rowCount += int64(token.RowCount)
}
case doneStruct:
if token.Status&doneCount != 0 {
rowCount += int64(token.RowCount)
}
if token.isError() {
return nil, token.getError()
}
case ReturnStatus:
s.c.setReturnStatus(token)
case error:
return nil, token
}
} }
return &Result{s.c, rowCount}, nil return &Result{s.c, reader.rowCount}, nil
} }
type Rows struct { type Rows struct {
stmt *Stmt stmt *Stmt
cols []columnStruct cols []columnStruct
tokchan chan tokenStruct reader *tokenProcessor
nextCols []columnStruct nextCols []columnStruct
cancel func() cancel func()
} }
func (rc *Rows) Close() error { func (rc *Rows) Close() error {
// need to add a test which returns lots of rows
// and check closing after reading only few rows
rc.cancel() rc.cancel()
for _ = range rc.tokchan {
for {
tok, err := rc.reader.nextToken()
if err == nil {
if tok == nil {
return nil
} else {
// continue consuming tokens
continue
}
} else {
if err == rc.reader.ctx.Err() {
return nil
} else {
return err
}
}
} }
rc.tokchan = nil
return nil
} }
func (rc *Rows) Columns() (res []string) { func (rc *Rows) Columns() (res []string) {
@ -707,27 +707,34 @@ func (rc *Rows) Next(dest []driver.Value) error {
if rc.nextCols != nil { if rc.nextCols != nil {
return io.EOF return io.EOF
} }
for tok := range rc.tokchan { for {
switch tokdata := tok.(type) { tok, err := rc.reader.nextToken()
case []columnStruct: if err == nil {
rc.nextCols = tokdata if tok == nil {
return io.EOF return io.EOF
case []interface{}: } else {
for i := range dest { switch tokdata := tok.(type) {
dest[i] = tokdata[i] case []columnStruct:
} rc.nextCols = tokdata
return nil return io.EOF
case doneStruct: case []interface{}:
if tokdata.isError() { for i := range dest {
return rc.stmt.c.checkBadConn(tokdata.getError()) dest[i] = tokdata[i]
}
return nil
case doneStruct:
if tokdata.isError() {
return rc.stmt.c.checkBadConn(tokdata.getError())
}
case ReturnStatus:
rc.stmt.c.sess.setReturnStatus(tokdata)
}
} }
case ReturnStatus:
rc.stmt.c.setReturnStatus(tokdata) } else {
case error: return rc.stmt.c.checkBadConn(err)
return rc.stmt.c.checkBadConn(tokdata)
} }
} }
return io.EOF
} }
func (rc *Rows) HasNextResultSet() bool { func (rc *Rows) HasNextResultSet() bool {
@ -895,35 +902,41 @@ func (c *Conn) Ping(ctx context.Context) error {
var _ driver.ConnBeginTx = &Conn{} var _ driver.ConnBeginTx = &Conn{}
// BeginTx satisfies ConnBeginTx. func convertIsolationLevel(level sql.IsolationLevel) (isoLevel, error) {
func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { switch level {
if !c.connectionGood {
return nil, driver.ErrBadConn
}
if opts.ReadOnly {
return nil, errors.New("Read-only transactions are not supported")
}
var tdsIsolation isoLevel
switch sql.IsolationLevel(opts.Isolation) {
case sql.LevelDefault: case sql.LevelDefault:
tdsIsolation = isolationUseCurrent return isolationUseCurrent, nil
case sql.LevelReadUncommitted: case sql.LevelReadUncommitted:
tdsIsolation = isolationReadUncommited return isolationReadUncommited, nil
case sql.LevelReadCommitted: case sql.LevelReadCommitted:
tdsIsolation = isolationReadCommited return isolationReadCommited, nil
case sql.LevelWriteCommitted: case sql.LevelWriteCommitted:
return nil, errors.New("LevelWriteCommitted isolation level is not supported") return isolationUseCurrent, errors.New("LevelWriteCommitted isolation level is not supported")
case sql.LevelRepeatableRead: case sql.LevelRepeatableRead:
tdsIsolation = isolationRepeatableRead return isolationRepeatableRead, nil
case sql.LevelSnapshot: case sql.LevelSnapshot:
tdsIsolation = isolationSnapshot return isolationSnapshot, nil
case sql.LevelSerializable: case sql.LevelSerializable:
tdsIsolation = isolationSerializable return isolationSerializable, nil
case sql.LevelLinearizable: case sql.LevelLinearizable:
return nil, errors.New("LevelLinearizable isolation level is not supported") return isolationUseCurrent, errors.New("LevelLinearizable isolation level is not supported")
default: default:
return nil, errors.New("Isolation level is not supported or unknown") return isolationUseCurrent, errors.New("isolation level is not supported or unknown")
}
}
// BeginTx satisfies ConnBeginTx.
func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
if !c.connectionGood {
return nil, driver.ErrBadConn
}
if opts.ReadOnly {
return nil, errors.New("read-only transactions are not supported")
}
tdsIsolation, err := convertIsolationLevel(sql.IsolationLevel(opts.Isolation))
if err != nil {
return nil, err
} }
return c.begin(ctx, tdsIsolation) return c.begin(ctx, tdsIsolation)
} }

@ -48,5 +48,5 @@ func (c *Connector) Driver() driver.Driver {
} }
func (r *Result) LastInsertId() (int64, error) { func (r *Result) LastInsertId() (int64, error) {
return -1, errors.New("LastInsertId is not supported. Please use the OUTPUT clause or add `select ID = convert(bigint, SCOPE_IDENTITY())` to the end of your query.") return -1, errors.New("LastInsertId is not supported. Please use the OUTPUT clause or add `select ID = convert(bigint, SCOPE_IDENTITY())` to the end of your query")
} }

@ -110,7 +110,7 @@ func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error {
return nil return nil
case *ReturnStatus: case *ReturnStatus:
*v = 0 // By default the return value should be zero. *v = 0 // By default the return value should be zero.
c.returnStatus = v c.sess.returnStatus = v
return driver.ErrRemoveArgument return driver.ErrRemoveArgument
case TVP: case TVP:
return nil return nil

@ -7,8 +7,8 @@ import (
) )
type timeoutConn struct { type timeoutConn struct {
c net.Conn c net.Conn
timeout time.Duration timeout time.Duration
} }
func newTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn { func newTimeoutConn(conn net.Conn, timeout time.Duration) *timeoutConn {
@ -51,21 +51,21 @@ func (c timeoutConn) RemoteAddr() net.Addr {
} }
func (c timeoutConn) SetDeadline(t time.Time) error { func (c timeoutConn) SetDeadline(t time.Time) error {
panic("Not implemented") return c.c.SetDeadline(t)
} }
func (c timeoutConn) SetReadDeadline(t time.Time) error { func (c timeoutConn) SetReadDeadline(t time.Time) error {
panic("Not implemented") return c.c.SetReadDeadline(t)
} }
func (c timeoutConn) SetWriteDeadline(t time.Time) error { func (c timeoutConn) SetWriteDeadline(t time.Time) error {
panic("Not implemented") return c.c.SetWriteDeadline(t)
} }
// this connection is used during TLS Handshake // this connection is used during TLS Handshake
// TDS protocol requires TLS handshake messages to be sent inside TDS packets // TDS protocol requires TLS handshake messages to be sent inside TDS packets
type tlsHandshakeConn struct { type tlsHandshakeConn struct {
buf *tdsBuffer buf *tdsBuffer
packetPending bool packetPending bool
continueRead bool continueRead bool
} }
@ -75,7 +75,7 @@ func (c *tlsHandshakeConn) Read(b []byte) (n int, err error) {
c.packetPending = false c.packetPending = false
err = c.buf.FinishPacket() err = c.buf.FinishPacket()
if err != nil { if err != nil {
err = fmt.Errorf("Cannot send handshake packet: %s", err.Error()) err = fmt.Errorf("cannot send handshake packet: %s", err.Error())
return return
} }
c.continueRead = false c.continueRead = false
@ -84,7 +84,7 @@ func (c *tlsHandshakeConn) Read(b []byte) (n int, err error) {
var packet packetType var packet packetType
packet, err = c.buf.BeginRead() packet, err = c.buf.BeginRead()
if err != nil { if err != nil {
err = fmt.Errorf("Cannot read handshake packet: %s", err.Error()) err = fmt.Errorf("cannot read handshake packet: %s", err.Error())
return return
} }
if packet != packPrelogin { if packet != packPrelogin {
@ -105,27 +105,27 @@ func (c *tlsHandshakeConn) Write(b []byte) (n int, err error) {
} }
func (c *tlsHandshakeConn) Close() error { func (c *tlsHandshakeConn) Close() error {
panic("Not implemented") return c.buf.transport.Close()
} }
func (c *tlsHandshakeConn) LocalAddr() net.Addr { func (c *tlsHandshakeConn) LocalAddr() net.Addr {
panic("Not implemented") return nil
} }
func (c *tlsHandshakeConn) RemoteAddr() net.Addr { func (c *tlsHandshakeConn) RemoteAddr() net.Addr {
panic("Not implemented") return nil
} }
func (c *tlsHandshakeConn) SetDeadline(t time.Time) error { func (c *tlsHandshakeConn) SetDeadline(_ time.Time) error {
panic("Not implemented") return nil
} }
func (c *tlsHandshakeConn) SetReadDeadline(t time.Time) error { func (c *tlsHandshakeConn) SetReadDeadline(_ time.Time) error {
panic("Not implemented") return nil
} }
func (c *tlsHandshakeConn) SetWriteDeadline(t time.Time) error { func (c *tlsHandshakeConn) SetWriteDeadline(_ time.Time) error {
panic("Not implemented") return nil
} }
// this connection just delegates all methods to it's wrapped connection // this connection just delegates all methods to it's wrapped connection
@ -148,21 +148,21 @@ func (c passthroughConn) Close() error {
} }
func (c passthroughConn) LocalAddr() net.Addr { func (c passthroughConn) LocalAddr() net.Addr {
panic("Not implemented") return c.c.LocalAddr()
} }
func (c passthroughConn) RemoteAddr() net.Addr { func (c passthroughConn) RemoteAddr() net.Addr {
panic("Not implemented") return c.c.RemoteAddr()
} }
func (c passthroughConn) SetDeadline(t time.Time) error { func (c passthroughConn) SetDeadline(t time.Time) error {
panic("Not implemented") return c.c.SetDeadline(t)
} }
func (c passthroughConn) SetReadDeadline(t time.Time) error { func (c passthroughConn) SetReadDeadline(t time.Time) error {
panic("Not implemented") return c.c.SetReadDeadline(t)
} }
func (c passthroughConn) SetWriteDeadline(t time.Time) error { func (c passthroughConn) SetWriteDeadline(t time.Time) error {
panic("Not implemented") return c.c.SetWriteDeadline(t)
} }

@ -14,6 +14,7 @@ import (
"time" "time"
"unicode/utf16" "unicode/utf16"
//lint:ignore SA1019 MD4 is used by legacy NTLM
"golang.org/x/crypto/md4" "golang.org/x/crypto/md4"
) )
@ -126,18 +127,6 @@ func createDesKey(bytes, material []byte) {
material[7] = (byte)(bytes[6] << 1) material[7] = (byte)(bytes[6] << 1)
} }
func oddParity(bytes []byte) {
for i := 0; i < len(bytes); i++ {
b := bytes[i]
needsParity := (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1)) & 0x01) == 0
if needsParity {
bytes[i] = bytes[i] | byte(0x01)
} else {
bytes[i] = bytes[i] & byte(0xfe)
}
}
}
func encryptDes(key []byte, cleartext []byte, ciphertext []byte) { func encryptDes(key []byte, cleartext []byte, ciphertext []byte) {
var desKey [8]byte var desKey [8]byte
createDesKey(key, desKey[:]) createDesKey(key, desKey[:])

@ -22,12 +22,6 @@ type param struct {
buffer []byte buffer []byte
} }
const (
fWithRecomp = 1
fNoMetaData = 2
fReuseMetaData = 4
)
var ( var (
sp_Cursor = procId{1, ""} sp_Cursor = procId{1, ""}
sp_CursorOpen = procId{2, ""} sp_CursorOpen = procId{2, ""}

@ -82,19 +82,20 @@ const (
// https://msdn.microsoft.com/en-us/library/dd304214.aspx // https://msdn.microsoft.com/en-us/library/dd304214.aspx
const ( const (
packSQLBatch packetType = 1 packSQLBatch packetType = 1
packRPCRequest = 3 packRPCRequest packetType = 3
packReply = 4 packReply packetType = 4
// 2.2.1.7 Attention: https://msdn.microsoft.com/en-us/library/dd341449.aspx // 2.2.1.7 Attention: https://msdn.microsoft.com/en-us/library/dd341449.aspx
// 4.19.2 Out-of-Band Attention Signal: https://msdn.microsoft.com/en-us/library/dd305167.aspx // 4.19.2 Out-of-Band Attention Signal: https://msdn.microsoft.com/en-us/library/dd305167.aspx
packAttention = 6 packAttention packetType = 6
packBulkLoadBCP = 7 packBulkLoadBCP packetType = 7
packTransMgrReq = 14 packFedAuthToken packetType = 8
packNormal = 15 packTransMgrReq packetType = 14
packLogin7 = 16 packNormal packetType = 15
packSSPIMessage = 17 packLogin7 packetType = 16
packPrelogin = 18 packSSPIMessage packetType = 17
packPrelogin packetType = 18
) )
// prelogin fields // prelogin fields
@ -118,6 +119,17 @@ const (
encryptReq = 3 // Encryption is required. encryptReq = 3 // Encryption is required.
) )
const (
featExtSESSIONRECOVERY byte = 0x01
featExtFEDAUTH byte = 0x02
featExtCOLUMNENCRYPTION byte = 0x04
featExtGLOBALTRANSACTIONS byte = 0x05
featExtAZURESQLSUPPORT byte = 0x08
featExtDATACLASSIFICATION byte = 0x09
featExtUTF8SUPPORT byte = 0x0A
featExtTERMINATOR byte = 0xFF
)
type tdsSession struct { type tdsSession struct {
buf *tdsBuffer buf *tdsBuffer
loginAck loginAckStruct loginAck loginAckStruct
@ -129,6 +141,7 @@ type tdsSession struct {
log optionalLogger log optionalLogger
routedServer string routedServer string
routedPort uint16 routedPort uint16
returnStatus *ReturnStatus
} }
const ( const (
@ -155,13 +168,13 @@ func (p keySlice) Less(i, j int) bool { return p[i] < p[j] }
func (p keySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p keySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// http://msdn.microsoft.com/en-us/library/dd357559.aspx // http://msdn.microsoft.com/en-us/library/dd357559.aspx
func writePrelogin(w *tdsBuffer, fields map[uint8][]byte) error { func writePrelogin(packetType packetType, w *tdsBuffer, fields map[uint8][]byte) error {
var err error var err error
w.BeginPacket(packPrelogin, false) w.BeginPacket(packetType, false)
offset := uint16(5*len(fields) + 1) offset := uint16(5*len(fields) + 1)
keys := make(keySlice, 0, len(fields)) keys := make(keySlice, 0, len(fields))
for k, _ := range fields { for k := range fields {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Sort(keys) sort.Sort(keys)
@ -210,12 +223,15 @@ func readPrelogin(r *tdsBuffer) (map[uint8][]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if packet_type != 4 { if packet_type != packReply {
return nil, errors.New("Invalid respones, expected packet type 4, PRELOGIN RESPONSE") return nil, errors.New("invalid respones, expected packet type 4, PRELOGIN RESPONSE")
}
if len(struct_buf) == 0 {
return nil, errors.New("invalid empty PRELOGIN response, it must contain at least one byte")
} }
offset := 0 offset := 0
results := map[uint8][]byte{} results := map[uint8][]byte{}
for true { for {
rec_type := struct_buf[offset] rec_type := struct_buf[offset]
if rec_type == preloginTERMINATOR { if rec_type == preloginTERMINATOR {
break break
@ -240,6 +256,16 @@ const (
fIntSecurity = 0x80 fIntSecurity = 0x80
) )
// OptionFlags3
// http://msdn.microsoft.com/en-us/library/dd304019.aspx
const (
fChangePassword = 1
fSendYukonBinaryXML = 2
fUserInstance = 4
fUnknownCollationHandling = 8
fExtension = 0x10
)
// TypeFlags // TypeFlags
const ( const (
// 4 bits for fSQLType // 4 bits for fSQLType
@ -247,12 +273,6 @@ const (
fReadOnlyIntent = 32 fReadOnlyIntent = 32
) )
// OptionFlags3
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/773a62b6-ee89-4c02-9e5e-344882630aac
const (
fExtension = 0x10
)
type login struct { type login struct {
TDSVersion uint32 TDSVersion uint32
PacketSize uint32 PacketSize uint32
@ -295,7 +315,7 @@ func (e *featureExts) Add(f featureExt) error {
} }
id := f.featureID() id := f.featureID()
if _, exists := e.features[id]; exists { if _, exists := e.features[id]; exists {
f := "Login error: Feature with ID '%v' is already present in FeatureExt block." f := "login error: Feature with ID '%v' is already present in FeatureExt block"
return fmt.Errorf(f, id) return fmt.Errorf(f, id)
} }
if e.features == nil { if e.features == nil {
@ -326,37 +346,63 @@ func (e featureExts) toBytes() []byte {
return d return d
} }
type featureExtFedAuthSTS struct { // featureExtFedAuth tracks federated authentication state before and during login
FedAuthEcho bool type featureExtFedAuth struct {
// FedAuthLibrary is populated by the federated authentication provider.
FedAuthLibrary int
// ADALWorkflow is populated by the federated authentication provider.
ADALWorkflow byte
// FedAuthEcho is populated from the prelogin response
FedAuthEcho bool
// FedAuthToken is populated during login with the value from the provider.
FedAuthToken string FedAuthToken string
Nonce []byte
// Nonce is populated during login with the value from the provider.
Nonce []byte
// Signature is populated during login with the value from the server.
Signature []byte
} }
func (e *featureExtFedAuthSTS) featureID() byte { func (e *featureExtFedAuth) featureID() byte {
return 0x02 return featExtFEDAUTH
} }
func (e *featureExtFedAuthSTS) toBytes() []byte { func (e *featureExtFedAuth) toBytes() []byte {
if e == nil { if e == nil {
return nil return nil
} }
options := byte(0x01) << 1 // 0x01 => STS bFedAuthLibrary 7BIT options := byte(e.FedAuthLibrary) << 1
if e.FedAuthEcho { if e.FedAuthEcho {
options |= 1 // fFedAuthEcho options |= 1 // fFedAuthEcho
} }
d := make([]byte, 5) // Feature extension format depends on the federated auth library.
d[0] = options // Options are described at
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/773a62b6-ee89-4c02-9e5e-344882630aac
var d []byte
switch e.FedAuthLibrary {
case fedAuthLibrarySecurityToken:
d = make([]byte, 5)
d[0] = options
// looks like string in // looks like string in
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/f88b63bb-b479-49e1-a87b-deda521da508 // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/f88b63bb-b479-49e1-a87b-deda521da508
tokenBytes := str2ucs2(e.FedAuthToken) tokenBytes := str2ucs2(e.FedAuthToken)
binary.LittleEndian.PutUint32(d[1:], uint32(len(tokenBytes))) // Should be a signed int32, but since the length is relatively small, this should work binary.LittleEndian.PutUint32(d[1:], uint32(len(tokenBytes))) // Should be a signed int32, but since the length is relatively small, this should work
d = append(d, tokenBytes...) d = append(d, tokenBytes...)
if len(e.Nonce) == 32 { if len(e.Nonce) == 32 {
d = append(d, e.Nonce...) d = append(d, e.Nonce...)
}
case fedAuthLibraryADAL:
d = []byte{options, e.ADALWorkflow}
} }
return d return d
@ -418,7 +464,7 @@ func str2ucs2(s string) []byte {
func ucs22str(s []byte) (string, error) { func ucs22str(s []byte) (string, error) {
if len(s)%2 != 0 { if len(s)%2 != 0 {
return "", fmt.Errorf("Illegal UCS2 string length: %d", len(s)) return "", fmt.Errorf("illegal UCS2 string length: %d", len(s))
} }
buf := make([]uint16, len(s)/2) buf := make([]uint16, len(s)/2)
for i := 0; i < len(s); i += 2 { for i := 0; i < len(s); i += 2 {
@ -436,7 +482,7 @@ func manglePassword(password string) []byte {
} }
// http://msdn.microsoft.com/en-us/library/dd304019.aspx // http://msdn.microsoft.com/en-us/library/dd304019.aspx
func sendLogin(w *tdsBuffer, login login) error { func sendLogin(w *tdsBuffer, login *login) error {
w.BeginPacket(packLogin7, false) w.BeginPacket(packLogin7, false)
hostname := str2ucs2(login.HostName) hostname := str2ucs2(login.HostName)
username := str2ucs2(login.UserName) username := str2ucs2(login.UserName)
@ -572,6 +618,36 @@ func sendLogin(w *tdsBuffer, login login) error {
return w.FinishPacket() return w.FinishPacket()
} }
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/827d9632-2957-4d54-b9ea-384530ae79d0
func sendFedAuthInfo(w *tdsBuffer, fedAuth *featureExtFedAuth) (err error) {
fedauthtoken := str2ucs2(fedAuth.FedAuthToken)
tokenlen := len(fedauthtoken)
datalen := 4 + tokenlen + len(fedAuth.Nonce)
w.BeginPacket(packFedAuthToken, false)
err = binary.Write(w, binary.LittleEndian, uint32(datalen))
if err != nil {
return
}
err = binary.Write(w, binary.LittleEndian, uint32(tokenlen))
if err != nil {
return
}
_, err = w.Write(fedauthtoken)
if err != nil {
return
}
_, err = w.Write(fedAuth.Nonce)
if err != nil {
return
}
return w.FinishPacket()
}
func readUcs2(r io.Reader, numchars int) (res string, err error) { func readUcs2(r io.Reader, numchars int) (res string, err error) {
buf := make([]byte, numchars*2) buf := make([]byte, numchars*2)
_, err = io.ReadFull(r, buf) _, err = io.ReadFull(r, buf)
@ -770,12 +846,13 @@ type auth interface {
// use the first one that allows a connection. // use the first one that allows a connection.
func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn net.Conn, err error) { func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn net.Conn, err error) {
var ips []net.IP var ips []net.IP
ips, err = net.LookupIP(p.host) ip := net.ParseIP(p.host)
if err != nil { if ip == nil {
ip := net.ParseIP(p.host) ips, err = net.LookupIP(p.host)
if ip == nil { if err != nil {
return nil, err return
} }
} else {
ips = []net.IP{ip} ips = []net.IP{ip}
} }
if len(ips) == 1 { if len(ips) == 1 {
@ -802,7 +879,7 @@ func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn ne
} }
// Wait for either the *first* successful connection, or all the errors // Wait for either the *first* successful connection, or all the errors
wait_loop: wait_loop:
for i, _ := range ips { for i := range ips {
select { select {
case conn = <-connChan: case conn = <-connChan:
// Got a connection to use, close any others // Got a connection to use, close any others
@ -824,12 +901,123 @@ func dialConnection(ctx context.Context, c *Connector, p connectParams) (conn ne
} }
// Can't do the usual err != nil check, as it is possible to have gotten an error before a successful connection // Can't do the usual err != nil check, as it is possible to have gotten an error before a successful connection
if conn == nil { if conn == nil {
f := "Unable to open tcp connection with host '%v:%v': %v" f := "unable to open tcp connection with host '%v:%v': %v"
return nil, fmt.Errorf(f, p.host, resolveServerPort(p.port), err.Error()) return nil, fmt.Errorf(f, p.host, resolveServerPort(p.port), err.Error())
} }
return conn, err return conn, err
} }
func preparePreloginFields(p connectParams, fe *featureExtFedAuth) map[uint8][]byte {
instance_buf := []byte(p.instance)
instance_buf = append(instance_buf, 0) // zero terminate instance name
var encrypt byte
if p.disableEncryption {
encrypt = encryptNotSup
} else if p.encrypt {
encrypt = encryptOn
} else {
encrypt = encryptOff
}
fields := map[uint8][]byte{
preloginVERSION: {0, 0, 0, 0, 0, 0},
preloginENCRYPTION: {encrypt},
preloginINSTOPT: instance_buf,
preloginTHREADID: {0, 0, 0, 0},
preloginMARS: {0}, // MARS disabled
}
if fe.FedAuthLibrary != fedAuthLibraryReserved {
fields[preloginFEDAUTHREQUIRED] = []byte{1}
}
return fields
}
func interpretPreloginResponse(p connectParams, fe *featureExtFedAuth, fields map[uint8][]byte) (encrypt byte, err error) {
// If the server returns the preloginFEDAUTHREQUIRED field, then federated authentication
// is supported. The actual value may be 0 or 1, where 0 means either SSPI or federated
// authentication is allowed, while 1 means only federated authentication is allowed.
if fedAuthSupport, ok := fields[preloginFEDAUTHREQUIRED]; ok {
if len(fedAuthSupport) != 1 {
return 0, fmt.Errorf("Federated authentication flag length should be 1: is %d", len(fedAuthSupport))
}
// We need to be able to echo the value back to the server
fe.FedAuthEcho = fedAuthSupport[0] != 0
} else if fe.FedAuthLibrary != fedAuthLibraryReserved {
return 0, fmt.Errorf("Federated authentication is not supported by the server")
}
encryptBytes, ok := fields[preloginENCRYPTION]
if !ok {
return 0, fmt.Errorf("encrypt negotiation failed")
}
encrypt = encryptBytes[0]
if p.encrypt && (encrypt == encryptNotSup || encrypt == encryptOff) {
return 0, fmt.Errorf("server does not support encryption")
}
return
}
func prepareLogin(ctx context.Context, c *Connector, p connectParams, log optionalLogger, auth auth, fe *featureExtFedAuth, packetSize uint32) (l *login, err error) {
l = &login{
TDSVersion: verTDS74,
PacketSize: packetSize,
Database: p.database,
OptionFlags2: fODBC, // to get unlimited TEXTSIZE
HostName: p.workstation,
ServerName: p.host,
AppName: p.appname,
TypeFlags: p.typeFlags,
}
switch {
case fe.FedAuthLibrary == fedAuthLibrarySecurityToken:
if p.logFlags&logDebug != 0 {
log.Println("Starting federated authentication using security token")
}
fe.FedAuthToken, err = c.securityTokenProvider(ctx)
if err != nil {
if p.logFlags&logDebug != 0 {
log.Printf("Failed to retrieve service principal token for federated authentication security token library: %v", err)
}
return nil, err
}
l.FeatureExt.Add(fe)
case fe.FedAuthLibrary == fedAuthLibraryADAL:
if p.logFlags&logDebug != 0 {
log.Println("Starting federated authentication using ADAL")
}
l.FeatureExt.Add(fe)
case auth != nil:
if p.logFlags&logDebug != 0 {
log.Println("Starting SSPI login")
}
l.SSPI, err = auth.InitialBytes()
if err != nil {
return nil, err
}
l.OptionFlags2 |= fIntSecurity
return l, nil
default:
// Default to SQL server authentication with user and password
l.UserName = p.user
l.Password = p.password
}
return l, nil
}
func connect(ctx context.Context, c *Connector, log optionalLogger, p connectParams) (res *tdsSession, err error) { func connect(ctx context.Context, c *Connector, log optionalLogger, p connectParams) (res *tdsSession, err error) {
dialCtx := ctx dialCtx := ctx
if p.dial_timeout > 0 { if p.dial_timeout > 0 {
@ -842,24 +1030,24 @@ func connect(ctx context.Context, c *Connector, log optionalLogger, p connectPar
// both instance name and port specified // both instance name and port specified
// when port is specified instance name is not used // when port is specified instance name is not used
// you should not provide instance name when you provide port // you should not provide instance name when you provide port
log.Println("WARN: You specified both instance name and port in the connection string, port will be used and instance name will be ignored"); log.Println("WARN: You specified both instance name and port in the connection string, port will be used and instance name will be ignored")
} }
if p.instance != "" && p.port == 0 { if p.instance != "" && p.port == 0 {
p.instance = strings.ToUpper(p.instance) p.instance = strings.ToUpper(p.instance)
d := c.getDialer(&p) d := c.getDialer(&p)
instances, err := getInstances(dialCtx, d, p.host) instances, err := getInstances(dialCtx, d, p.host)
if err != nil { if err != nil {
f := "Unable to get instances from Sql Server Browser on host %v: %v" f := "unable to get instances from Sql Server Browser on host %v: %v"
return nil, fmt.Errorf(f, p.host, err.Error()) return nil, fmt.Errorf(f, p.host, err.Error())
} }
strport, ok := instances[p.instance]["tcp"] strport, ok := instances[p.instance]["tcp"]
if !ok { if !ok {
f := "No instance matching '%v' returned from host '%v'" f := "no instance matching '%v' returned from host '%v'"
return nil, fmt.Errorf(f, p.instance, p.host) return nil, fmt.Errorf(f, p.instance, p.host)
} }
port, err := strconv.ParseUint(strport, 0, 16) port, err := strconv.ParseUint(strport, 0, 16)
if err != nil { if err != nil {
f := "Invalid tcp port returned from Sql Server Browser '%v': %v" f := "invalid tcp port returned from Sql Server Browser '%v': %v"
return nil, fmt.Errorf(f, strport, err.Error()) return nil, fmt.Errorf(f, strport, err.Error())
} }
p.port = port p.port = port
@ -880,25 +1068,14 @@ initiate_connection:
logFlags: p.logFlags, logFlags: p.logFlags,
} }
instance_buf := []byte(p.instance) fedAuth := &featureExtFedAuth{
instance_buf = append(instance_buf, 0) // zero terminate instance name FedAuthLibrary: p.fedAuthLibrary,
var encrypt byte ADALWorkflow: p.fedAuthADALWorkflow,
if p.disableEncryption {
encrypt = encryptNotSup
} else if p.encrypt {
encrypt = encryptOn
} else {
encrypt = encryptOff
}
fields := map[uint8][]byte{
preloginVERSION: {0, 0, 0, 0, 0, 0},
preloginENCRYPTION: {encrypt},
preloginINSTOPT: instance_buf,
preloginTHREADID: {0, 0, 0, 0},
preloginMARS: {0}, // MARS disabled
} }
err = writePrelogin(outbuf, fields) fields := preparePreloginFields(p, fedAuth)
err = writePrelogin(packPrelogin, outbuf, fields)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -908,13 +1085,9 @@ initiate_connection:
return nil, err return nil, err
} }
encryptBytes, ok := fields[preloginENCRYPTION] encrypt, err := interpretPreloginResponse(p, fedAuth, fields)
if !ok { if err != nil {
return nil, fmt.Errorf("Encrypt negotiation failed") return nil, err
}
encrypt = encryptBytes[0]
if p.encrypt && (encrypt == encryptNotSup || encrypt == encryptOff) {
return nil, fmt.Errorf("Server does not support encryption")
} }
if encrypt != encryptNotSup { if encrypt != encryptNotSup {
@ -922,7 +1095,7 @@ initiate_connection:
if p.certificate != "" { if p.certificate != "" {
pem, err := ioutil.ReadFile(p.certificate) pem, err := ioutil.ReadFile(p.certificate)
if err != nil { if err != nil {
return nil, fmt.Errorf("Cannot read certificate %q: %v", p.certificate, err) return nil, fmt.Errorf("cannot read certificate %q: %v", p.certificate, err)
} }
certs := x509.NewCertPool() certs := x509.NewCertPool()
certs.AppendCertsFromPEM(pem) certs.AppendCertsFromPEM(pem)
@ -954,54 +1127,46 @@ initiate_connection:
} }
} }
login := login{
TDSVersion: verTDS74,
PacketSize: uint32(outbuf.PackageSize()),
Database: p.database,
OptionFlags2: fODBC, // to get unlimited TEXTSIZE
HostName: p.workstation,
ServerName: p.host,
AppName: p.appname,
TypeFlags: p.typeFlags,
}
auth, authOk := getAuth(p.user, p.password, p.serverSPN, p.workstation) auth, authOk := getAuth(p.user, p.password, p.serverSPN, p.workstation)
switch { if authOk {
case p.fedAuthAccessToken != "": // accesstoken ignores user/password
featurext := &featureExtFedAuthSTS{
FedAuthEcho: len(fields[preloginFEDAUTHREQUIRED]) > 0 && fields[preloginFEDAUTHREQUIRED][0] == 1,
FedAuthToken: p.fedAuthAccessToken,
Nonce: fields[preloginNONCEOPT],
}
login.FeatureExt.Add(featurext)
case authOk:
login.SSPI, err = auth.InitialBytes()
if err != nil {
return nil, err
}
login.OptionFlags2 |= fIntSecurity
defer auth.Free() defer auth.Free()
default: } else {
login.UserName = p.user auth = nil
login.Password = p.password
} }
login, err := prepareLogin(ctx, c, p, log, auth, fedAuth, uint32(outbuf.PackageSize()))
if err != nil {
return nil, err
}
err = sendLogin(outbuf, login) err = sendLogin(outbuf, login)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// processing login response // Loop until a packet containing a login acknowledgement is received.
success := false // SSPI and federated authentication scenarios may require multiple
for { // packet exchanges to complete the login sequence.
tokchan := make(chan tokenStruct, 5) for loginAck := false; !loginAck; {
go processResponse(context.Background(), &sess, tokchan, nil) reader := startReading(&sess, ctx, nil)
for tok := range tokchan {
for {
tok, err := reader.nextToken()
if err != nil {
return nil, err
}
if tok == nil {
break
}
switch token := tok.(type) { switch token := tok.(type) {
case sspiMsg: case sspiMsg:
sspi_msg, err := auth.NextBytes(token) sspi_msg, err := auth.NextBytes(token)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if sspi_msg != nil && len(sspi_msg) > 0 { if len(sspi_msg) > 0 {
outbuf.BeginPacket(packSSPIMessage, false) outbuf.BeginPacket(packSSPIMessage, false)
_, err = outbuf.Write(sspi_msg) _, err = outbuf.Write(sspi_msg)
if err != nil { if err != nil {
@ -1013,23 +1178,41 @@ initiate_connection:
} }
sspi_msg = nil sspi_msg = nil
} }
// TODO: for Live ID authentication it may be necessary to
// compare fedAuth.Nonce == token.Nonce and keep track of signature
//case fedAuthAckStruct:
//fedAuth.Signature = token.Signature
case fedAuthInfoStruct:
// For ADAL workflows this contains the STS URL and server SPN.
// If received outside of an ADAL workflow, ignore.
if c == nil || c.adalTokenProvider == nil {
continue
}
// Request the AD token given the server SPN and STS URL
fedAuth.FedAuthToken, err = c.adalTokenProvider(ctx, token.ServerSPN, token.STSURL)
if err != nil {
return nil, err
}
// Now need to send the token as a FEDINFO packet
err = sendFedAuthInfo(outbuf, fedAuth)
if err != nil {
return nil, err
}
case loginAckStruct: case loginAckStruct:
success = true
sess.loginAck = token sess.loginAck = token
case error: loginAck = true
return nil, fmt.Errorf("Login error: %s", token.Error())
case doneStruct: case doneStruct:
if token.isError() { if token.isError() {
return nil, fmt.Errorf("Login error: %s", token.getError()) return nil, fmt.Errorf("login error: %s", token.getError())
} }
goto loginEnd case error:
return nil, fmt.Errorf("login error: %s", token.Error())
} }
} }
} }
loginEnd:
if !success {
return nil, fmt.Errorf("Login failed")
}
if sess.routedServer != "" { if sess.routedServer != "" {
toconn.Close() toconn.Close()
p.host = sess.routedServer p.host = sess.routedServer
@ -1041,3 +1224,9 @@ loginEnd:
} }
return &sess, nil return &sess, nil
} }
func (sess *tdsSession) setReturnStatus(status ReturnStatus) {
if sess.returnStatus != nil {
*sess.returnStatus = status
}
}

@ -6,12 +6,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"net" "io/ioutil"
"strconv" "strconv"
"strings"
) )
//go:generate stringer -type token //go:generate go run golang.org/x/tools/cmd/stringer -type token
type token byte type token byte
@ -29,6 +28,7 @@ const (
tokenNbcRow token = 210 // 0xd2 tokenNbcRow token = 210 // 0xd2
tokenEnvChange token = 227 // 0xE3 tokenEnvChange token = 227 // 0xE3
tokenSSPI token = 237 // 0xED tokenSSPI token = 237 // 0xED
tokenFedAuthInfo token = 238 // 0xEE
tokenDone token = 253 // 0xFD tokenDone token = 253 // 0xFD
tokenDoneProc token = 254 tokenDoneProc token = 254
tokenDoneInProc token = 255 tokenDoneInProc token = 255
@ -70,6 +70,11 @@ const (
envRouting = 20 envRouting = 20
) )
const (
fedAuthInfoSTSURL = 0x01
fedAuthInfoSPN = 0x02
)
// COLMETADATA flags // COLMETADATA flags
// https://msdn.microsoft.com/en-us/library/dd357363.aspx // https://msdn.microsoft.com/en-us/library/dd357363.aspx
const ( const (
@ -105,26 +110,6 @@ func (d doneStruct) getError() Error {
type doneInProcStruct doneStruct type doneInProcStruct doneStruct
var doneFlags2str = map[uint16]string{
doneFinal: "final",
doneMore: "more",
doneError: "error",
doneInxact: "inxact",
doneCount: "count",
doneAttn: "attn",
doneSrvError: "srverror",
}
func doneFlags2Str(flags uint16) string {
strs := make([]string, 0, len(doneFlags2str))
for flag, tag := range doneFlags2str {
if flags&flag != 0 {
strs = append(strs, tag)
}
}
return strings.Join(strs, "|")
}
// ENVCHANGE stream // ENVCHANGE stream
// http://msdn.microsoft.com/en-us/library/dd303449.aspx // http://msdn.microsoft.com/en-us/library/dd303449.aspx
func processEnvChg(sess *tdsSession) { func processEnvChg(sess *tdsSession) {
@ -380,9 +365,8 @@ func processEnvChg(sess *tdsSession) {
default: default:
// ignore rest of records because we don't know how to skip those // ignore rest of records because we don't know how to skip those
sess.log.Printf("WARN: Unknown ENVCHANGE record detected with type id = %d\n", envtype) sess.log.Printf("WARN: Unknown ENVCHANGE record detected with type id = %d\n", envtype)
break return
} }
} }
} }
@ -425,6 +409,78 @@ func parseSSPIMsg(r *tdsBuffer) sspiMsg {
return sspiMsg(buf) return sspiMsg(buf)
} }
type fedAuthInfoStruct struct {
STSURL string
ServerSPN string
}
type fedAuthInfoOpt struct {
fedAuthInfoID byte
dataLength, dataOffset uint32
}
func parseFedAuthInfo(r *tdsBuffer) fedAuthInfoStruct {
size := r.uint32()
var STSURL, SPN string
var err error
// Each fedAuthInfoOpt is one byte to indicate the info ID,
// then a four byte offset and a four byte length.
count := r.uint32()
offset := uint32(4)
opts := make([]fedAuthInfoOpt, count)
for i := uint32(0); i < count; i++ {
fedAuthInfoID := r.byte()
dataLength := r.uint32()
dataOffset := r.uint32()
offset += 1 + 4 + 4
opts[i] = fedAuthInfoOpt{
fedAuthInfoID: fedAuthInfoID,
dataLength: dataLength,
dataOffset: dataOffset,
}
}
data := make([]byte, size-offset)
r.ReadFull(data)
for i := uint32(0); i < count; i++ {
if opts[i].dataOffset < offset {
badStreamPanicf("Fed auth info opt stated data offset %d is before data begins in packet at %d",
opts[i].dataOffset, offset)
// returns via panic
}
if opts[i].dataOffset+opts[i].dataLength > size {
badStreamPanicf("Fed auth info opt stated data length %d added to stated offset exceeds size of packet %d",
opts[i].dataOffset+opts[i].dataLength, size)
// returns via panic
}
optData := data[opts[i].dataOffset-offset : opts[i].dataOffset-offset+opts[i].dataLength]
switch opts[i].fedAuthInfoID {
case fedAuthInfoSTSURL:
STSURL, err = ucs22str(optData)
case fedAuthInfoSPN:
SPN, err = ucs22str(optData)
default:
err = fmt.Errorf("Unexpected fed auth info opt ID %d", int(opts[i].fedAuthInfoID))
}
if err != nil {
badStreamPanic(err)
}
}
return fedAuthInfoStruct{
STSURL: STSURL,
ServerSPN: SPN,
}
}
type loginAckStruct struct { type loginAckStruct struct {
Interface uint8 Interface uint8
TDSVersion uint32 TDSVersion uint32
@ -449,19 +505,43 @@ func parseLoginAck(r *tdsBuffer) loginAckStruct {
} }
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/2eb82f8e-11f0-46dc-b42d-27302fa4701a // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/2eb82f8e-11f0-46dc-b42d-27302fa4701a
func parseFeatureExtAck(r *tdsBuffer) { type fedAuthAckStruct struct {
// at most 1 featureAck per feature in featureExt Nonce []byte
// go-mssqldb will add at most 1 feature, the spec defines 7 different features Signature []byte
for i := 0; i < 8; i++ { }
featureID := r.byte() // FeatureID
if featureID == 0xff { func parseFeatureExtAck(r *tdsBuffer) map[byte]interface{} {
return ack := map[byte]interface{}{}
for feature := r.byte(); feature != featExtTERMINATOR; feature = r.byte() {
length := r.uint32()
switch feature {
case featExtFEDAUTH:
// In theory we need to know the federated authentication library to
// know how to parse, but the alternatives provide compatible structures.
fedAuthAck := fedAuthAckStruct{}
if length >= 32 {
fedAuthAck.Nonce = make([]byte, 32)
r.ReadFull(fedAuthAck.Nonce)
length -= 32
}
if length >= 32 {
fedAuthAck.Signature = make([]byte, 32)
r.ReadFull(fedAuthAck.Signature)
length -= 32
}
ack[feature] = fedAuthAck
}
// Skip unprocessed bytes
if length > 0 {
io.CopyN(ioutil.Discard, r, int64(length))
} }
size := r.uint32() // FeatureAckDataLen
d := make([]byte, size)
r.ReadFull(d)
} }
panic("parsed more than 7 featureAck's, protocol implementation error?")
return ack
} }
// http://msdn.microsoft.com/en-us/library/dd357363.aspx // http://msdn.microsoft.com/en-us/library/dd357363.aspx
@ -579,7 +659,7 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
} }
var columns []columnStruct var columns []columnStruct
errs := make([]Error, 0, 5) errs := make([]Error, 0, 5)
for { for tokens := 0; ; tokens += 1 {
token := token(sess.buf.byte()) token := token(sess.buf.byte())
if sess.logFlags&logDebug != 0 { if sess.logFlags&logDebug != 0 {
sess.log.Printf("got token %v", token) sess.log.Printf("got token %v", token)
@ -588,6 +668,9 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
case tokenSSPI: case tokenSSPI:
ch <- parseSSPIMsg(sess.buf) ch <- parseSSPIMsg(sess.buf)
return return
case tokenFedAuthInfo:
ch <- parseFedAuthInfo(sess.buf)
return
case tokenReturnStatus: case tokenReturnStatus:
returnStatus := parseReturnStatus(sess.buf) returnStatus := parseReturnStatus(sess.buf)
ch <- returnStatus ch <- returnStatus
@ -595,7 +678,8 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
loginAck := parseLoginAck(sess.buf) loginAck := parseLoginAck(sess.buf)
ch <- loginAck ch <- loginAck
case tokenFeatureExtAck: case tokenFeatureExtAck:
parseFeatureExtAck(sess.buf) featureExtAck := parseFeatureExtAck(sess.buf)
ch <- featureExtAck
case tokenOrder: case tokenOrder:
order := parseOrder(sess.buf) order := parseOrder(sess.buf)
ch <- order ch <- order
@ -670,158 +754,137 @@ func processSingleResponse(sess *tdsSession, ch chan tokenStruct, outs map[strin
} }
} }
type parseRespIter byte type tokenProcessor struct {
tokChan chan tokenStruct
const ( ctx context.Context
parseRespIterContinue parseRespIter = iota // Continue parsing current token. sess *tdsSession
parseRespIterNext // Fetch the next token. outs map[string]interface{}
parseRespIterDone // Done with parsing the response. lastRow []interface{}
) rowCount int64
firstError error
type parseRespState byte
const (
parseRespStateNormal parseRespState = iota // Normal response state.
parseRespStateCancel // Query is canceled, wait for server to confirm.
parseRespStateClosing // Waiting for tokens to come through.
)
type parseResp struct {
sess *tdsSession
ctxDone <-chan struct{}
state parseRespState
cancelError error
} }
func (ts *parseResp) sendAttention(ch chan tokenStruct) parseRespIter { func startReading(sess *tdsSession, ctx context.Context, outs map[string]interface{}) *tokenProcessor {
if err := sendAttention(ts.sess.buf); err != nil { tokChan := make(chan tokenStruct, 5)
ts.dlogf("failed to send attention signal %v", err) go processSingleResponse(sess, tokChan, outs)
ch <- err return &tokenProcessor{
return parseRespIterDone tokChan: tokChan,
ctx: ctx,
sess: sess,
outs: outs,
} }
ts.state = parseRespStateCancel
return parseRespIterContinue
} }
func (ts *parseResp) dlog(msg string) { func (t *tokenProcessor) iterateResponse() error {
// logging from goroutine is disabled to prevent for {
// data race detection from firing tok, err := t.nextToken()
// The race is probably happening when if err == nil {
// test logger changes between tests. if tok == nil {
/*if ts.sess.logFlags&logDebug != 0 { return t.firstError
ts.sess.log.Println(msg) } else {
}*/ switch token := tok.(type) {
} case []columnStruct:
func (ts *parseResp) dlogf(f string, v ...interface{}) { t.sess.columns = token
/*if ts.sess.logFlags&logDebug != 0 { case []interface{}:
ts.sess.log.Printf(f, v...) t.lastRow = token
}*/ case doneInProcStruct:
if token.Status&doneCount != 0 {
t.rowCount += int64(token.RowCount)
}
case doneStruct:
if token.Status&doneCount != 0 {
t.rowCount += int64(token.RowCount)
}
if token.isError() && t.firstError == nil {
t.firstError = token.getError()
}
case ReturnStatus:
t.sess.setReturnStatus(token)
/*case error:
if resultError == nil {
resultError = token
}*/
}
}
} else {
return err
}
}
} }
func (ts *parseResp) iter(ctx context.Context, ch chan tokenStruct, tokChan chan tokenStruct) parseRespIter { func (t tokenProcessor) nextToken() (tokenStruct, error) {
switch ts.state { // we do this separate non-blocking check on token channel to
// prioritize it over cancellation channel
select {
case tok, more := <-t.tokChan:
err, more := tok.(error)
if more {
// this is an error and not a token
return nil, err
} else {
return tok, nil
}
default: default:
panic("unknown state") // there are no tokens on the channel, will need to wait
case parseRespStateNormal: }
select {
case tok, ok := <-tokChan: select {
if !ok { case tok, more := <-t.tokChan:
ts.dlog("response finished") if more {
return parseRespIterDone err, ok := tok.(error)
} if ok {
if err, ok := tok.(net.Error); ok && err.Timeout() { // this is an error and not a token
ts.cancelError = err return nil, err
ts.dlog("got timeout error, sending attention signal to server") } else {
return ts.sendAttention(ch) return tok, nil
} }
// Pass the token along. } else {
ch <- tok // completed reading response
return parseRespIterContinue return nil, nil
}
case <-ts.ctxDone: case <-t.ctx.Done():
ts.ctxDone = nil if err := sendAttention(t.sess.buf); err != nil {
ts.dlog("got cancel message, sending attention signal to server") // unable to send attention, current connection is bad
return ts.sendAttention(ch) // notify caller and close channel
return nil, err
} }
case parseRespStateCancel: // Read all responses until a DONE or error is received.Auth
select {
case tok, ok := <-tokChan:
if !ok {
ts.dlog("response finished but waiting for attention ack")
return parseRespIterNext
}
switch tok := tok.(type) {
default:
// Ignore all other tokens while waiting.
// The TDS spec says other tokens may arrive after an attention
// signal is sent. Ignore these tokens and continue looking for
// a DONE with attention confirm mark.
case doneStruct:
if tok.Status&doneAttn != 0 {
ts.dlog("got cancellation confirmation from server")
if ts.cancelError != nil {
ch <- ts.cancelError
ts.cancelError = nil
} else {
ch <- ctx.Err()
}
return parseRespIterDone
}
// If an error happens during cancel, pass it along and just stop. // now the server should send cancellation confirmation
// We are uncertain to receive more tokens. // it is possible that we already received full response
case error: // just before we sent cancellation request
ch <- tok // in this case current response would not contain confirmation
ts.state = parseRespStateClosing // and we would need to read one more response
}
return parseRespIterContinue // first lets finish reading current response and look
case <-ts.ctxDone: // for confirmation in it
ts.ctxDone = nil if readCancelConfirmation(t.tokChan) {
ts.state = parseRespStateClosing // we got confirmation in current response
return parseRespIterContinue return nil, t.ctx.Err()
} }
case parseRespStateClosing: // Wait for current token chan to close. // we did not get cancellation confirmation in the current response
if _, ok := <-tokChan; !ok { // read one more response, it must be there
ts.dlog("response finished") t.tokChan = make(chan tokenStruct, 5)
return parseRespIterDone go processSingleResponse(t.sess, t.tokChan, t.outs)
if readCancelConfirmation(t.tokChan) {
return nil, t.ctx.Err()
} }
return parseRespIterContinue // we did not get cancellation confirmation, something is not
// right, this connection is not usable anymore
return nil, errors.New("did not get cancellation confirmation from the server")
} }
} }
func processResponse(ctx context.Context, sess *tdsSession, ch chan tokenStruct, outs map[string]interface{}) { func readCancelConfirmation(tokChan chan tokenStruct) bool {
ts := &parseResp{ for tok := range tokChan {
sess: sess, switch tok := tok.(type) {
ctxDone: ctx.Done(), default:
} // just skip token
defer func() { case doneStruct:
// Ensure any remaining error is piped through if tok.Status&doneAttn != 0 {
// or the query may look like it executed when it actually failed. // got cancellation confirmation, exit
if ts.cancelError != nil { return true
ch <- ts.cancelError
ts.cancelError = nil
}
close(ch)
}()
// Loop over multiple responses.
for {
ts.dlog("initiating response reading")
tokChan := make(chan tokenStruct)
go processSingleResponse(sess, tokChan, outs)
// Loop over multiple tokens in response.
tokensLoop:
for {
switch ts.iter(ctx, ch, tokChan) {
case parseRespIterContinue:
// Nothing, continue to next token.
case parseRespIterNext:
break tokensLoop
case parseRespIterDone:
return
} }
} }
} }
return false
} }

@ -1,29 +1,24 @@
// Code generated by "stringer -type token"; DO NOT EDIT // Code generated by "stringer -type token"; DO NOT EDIT.
package mssql package mssql
import "fmt" import "strconv"
const ( const (
_token_name_0 = "tokenReturnStatus" _token_name_0 = "tokenReturnStatus"
_token_name_1 = "tokenColMetadata" _token_name_1 = "tokenColMetadata"
_token_name_2 = "tokenOrdertokenErrortokenInfo" _token_name_2 = "tokenOrdertokenErrortokenInfotokenReturnValuetokenLoginAcktokenFeatureExtAck"
_token_name_3 = "tokenLoginAck" _token_name_3 = "tokenRowtokenNbcRow"
_token_name_4 = "tokenRowtokenNbcRow" _token_name_4 = "tokenEnvChange"
_token_name_5 = "tokenEnvChange" _token_name_5 = "tokenSSPItokenFedAuthInfo"
_token_name_6 = "tokenSSPI" _token_name_6 = "tokenDonetokenDoneProctokenDoneInProc"
_token_name_7 = "tokenDonetokenDoneProctokenDoneInProc"
) )
var ( var (
_token_index_0 = [...]uint8{0, 17} _token_index_2 = [...]uint8{0, 10, 20, 29, 45, 58, 76}
_token_index_1 = [...]uint8{0, 16} _token_index_3 = [...]uint8{0, 8, 19}
_token_index_2 = [...]uint8{0, 10, 20, 29} _token_index_5 = [...]uint8{0, 9, 25}
_token_index_3 = [...]uint8{0, 13} _token_index_6 = [...]uint8{0, 9, 22, 37}
_token_index_4 = [...]uint8{0, 8, 19}
_token_index_5 = [...]uint8{0, 14}
_token_index_6 = [...]uint8{0, 9}
_token_index_7 = [...]uint8{0, 9, 22, 37}
) )
func (i token) String() string { func (i token) String() string {
@ -32,22 +27,21 @@ func (i token) String() string {
return _token_name_0 return _token_name_0
case i == 129: case i == 129:
return _token_name_1 return _token_name_1
case 169 <= i && i <= 171: case 169 <= i && i <= 174:
i -= 169 i -= 169
return _token_name_2[_token_index_2[i]:_token_index_2[i+1]] return _token_name_2[_token_index_2[i]:_token_index_2[i+1]]
case i == 173:
return _token_name_3
case 209 <= i && i <= 210: case 209 <= i && i <= 210:
i -= 209 i -= 209
return _token_name_4[_token_index_4[i]:_token_index_4[i+1]] return _token_name_3[_token_index_3[i]:_token_index_3[i+1]]
case i == 227: case i == 227:
return _token_name_5 return _token_name_4
case i == 237: case 237 <= i && i <= 238:
return _token_name_6 i -= 237
return _token_name_5[_token_index_5[i]:_token_index_5[i+1]]
case 253 <= i && i <= 255: case 253 <= i && i <= 255:
i -= 253 i -= 253
return _token_name_7[_token_index_7[i]:_token_index_7[i+1]] return _token_name_6[_token_index_6[i]:_token_index_6[i+1]]
default: default:
return fmt.Sprintf("token(%d)", i) return "token(" + strconv.FormatInt(int64(i), 10) + ")"
} }
} }

@ -21,11 +21,11 @@ type isoLevel uint8
const ( const (
isolationUseCurrent isoLevel = 0 isolationUseCurrent isoLevel = 0
isolationReadUncommited = 1 isolationReadUncommited isoLevel = 1
isolationReadCommited = 2 isolationReadCommited isoLevel = 2
isolationRepeatableRead = 3 isolationRepeatableRead isoLevel = 3
isolationSerializable = 4 isolationSerializable isoLevel = 4
isolationSnapshot = 5 isolationSnapshot isoLevel = 5
) )
func sendBeginXact(buf *tdsBuffer, headers []headerStruct, isolation isoLevel, name string, resetSession bool) (err error) { func sendBeginXact(buf *tdsBuffer, headers []headerStruct, isolation isoLevel, name string, resetSession bool) (err error) {

@ -4,6 +4,7 @@ package mssql
import ( import (
"bytes" "bytes"
"database/sql"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
@ -97,6 +98,9 @@ func (tvp TVP) encode(schema, name string, columnStr []columnStruct, tvpFieldInd
for columnStrIdx, fieldIdx := range tvpFieldIndexes { for columnStrIdx, fieldIdx := range tvpFieldIndexes {
field := refStr.Field(fieldIdx) field := refStr.Field(fieldIdx)
tvpVal := field.Interface() tvpVal := field.Interface()
if tvp.verifyStandardTypeOnNull(buf, tvpVal) {
continue
}
valOf := reflect.ValueOf(tvpVal) valOf := reflect.ValueOf(tvpVal)
elemKind := field.Kind() elemKind := field.Kind()
if elemKind == reflect.Ptr && valOf.IsNil() { if elemKind == reflect.Ptr && valOf.IsNil() {
@ -155,7 +159,7 @@ func (tvp TVP) columnTypes() ([]columnStruct, []int, error) {
defaultValues = append(defaultValues, v.Interface()) defaultValues = append(defaultValues, v.Interface())
continue continue
} }
defaultValues = append(defaultValues, reflect.Zero(field.Type).Interface()) defaultValues = append(defaultValues, tvp.createZeroType(reflect.Zero(field.Type).Interface()))
} }
if columnCount-len(tvpFieldIndexes) == columnCount { if columnCount-len(tvpFieldIndexes) == columnCount {
@ -209,19 +213,23 @@ func getSchemeAndName(tvpName string) (string, string, error) {
} }
splitVal := strings.Split(tvpName, ".") splitVal := strings.Split(tvpName, ".")
if len(splitVal) > 2 { if len(splitVal) > 2 {
return "", "", errors.New("wrong tvp name") return "", "", ErrorObjectName
} }
const (
openSquareBrackets = "["
closeSquareBrackets = "]"
)
if len(splitVal) == 2 { if len(splitVal) == 2 {
res := make([]string, 2) res := make([]string, 2)
for key, value := range splitVal { for key, value := range splitVal {
tmp := strings.Replace(value, "[", "", -1) tmp := strings.Replace(value, openSquareBrackets, "", -1)
tmp = strings.Replace(tmp, "]", "", -1) tmp = strings.Replace(tmp, closeSquareBrackets, "", -1)
res[key] = tmp res[key] = tmp
} }
return res[0], res[1], nil return res[0], res[1], nil
} }
tmp := strings.Replace(splitVal[0], "[", "", -1) tmp := strings.Replace(splitVal[0], openSquareBrackets, "", -1)
tmp = strings.Replace(tmp, "]", "", -1) tmp = strings.Replace(tmp, closeSquareBrackets, "", -1)
return "", tmp, nil return "", tmp, nil
} }
@ -229,3 +237,56 @@ func getSchemeAndName(tvpName string) (string, string, error) {
func getCountSQLSeparators(str string) int { func getCountSQLSeparators(str string) int {
return strings.Count(str, sqlSeparator) return strings.Count(str, sqlSeparator)
} }
// verify types https://golang.org/pkg/database/sql/
func (tvp TVP) createZeroType(fieldVal interface{}) interface{} {
const (
defaultBool = false
defaultFloat64 = float64(0)
defaultInt64 = int64(0)
defaultString = ""
)
switch fieldVal.(type) {
case sql.NullBool:
return defaultBool
case sql.NullFloat64:
return defaultFloat64
case sql.NullInt64:
return defaultInt64
case sql.NullString:
return defaultString
}
return fieldVal
}
// verify types https://golang.org/pkg/database/sql/
func (tvp TVP) verifyStandardTypeOnNull(buf *bytes.Buffer, tvpVal interface{}) bool {
const (
defaultNull = uint8(0)
)
switch val := tvpVal.(type) {
case sql.NullBool:
if !val.Valid {
binary.Write(buf, binary.LittleEndian, defaultNull)
return true
}
case sql.NullFloat64:
if !val.Valid {
binary.Write(buf, binary.LittleEndian, defaultNull)
return true
}
case sql.NullInt64:
if !val.Valid {
binary.Write(buf, binary.LittleEndian, defaultNull)
return true
}
case sql.NullString:
if !val.Valid {
binary.Write(buf, binary.LittleEndian, uint64(_PLP_NULL))
return true
}
}
return false
}

@ -665,7 +665,7 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
default: default:
buf = bytes.NewBuffer(make([]byte, 0, size)) buf = bytes.NewBuffer(make([]byte, 0, size))
} }
for true { for {
chunksize := r.uint32() chunksize := r.uint32()
if chunksize == 0 { if chunksize == 0 {
break break
@ -690,6 +690,10 @@ func readPLPType(ti *typeInfo, r *tdsBuffer) interface{} {
} }
func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) { func writePLPType(w io.Writer, ti typeInfo, buf []byte) (err error) {
if buf == nil {
err = binary.Write(w, binary.LittleEndian, uint64(_PLP_NULL))
return
}
if err = binary.Write(w, binary.LittleEndian, uint64(_UNKNOWN_PLP_LEN)); err != nil { if err = binary.Write(w, binary.LittleEndian, uint64(_UNKNOWN_PLP_LEN)); err != nil {
return return
} }
@ -807,7 +811,6 @@ func readVarLen(ti *typeInfo, r *tdsBuffer) {
default: default:
badStreamPanicf("Invalid type %d", ti.TypeId) badStreamPanicf("Invalid type %d", ti.TypeId)
} }
return
} }
func decodeMoney(buf []byte) []byte { func decodeMoney(buf []byte) []byte {
@ -834,8 +837,7 @@ func decodeGuid(buf []byte) []byte {
} }
func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte { func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte {
var sign uint8 sign := buf[0]
sign = buf[0]
var dec decimal.Decimal var dec decimal.Decimal
dec.SetPositive(sign != 0) dec.SetPositive(sign != 0)
dec.SetPrec(prec) dec.SetPrec(prec)
@ -1187,7 +1189,7 @@ func makeDecl(ti typeInfo) string {
return fmt.Sprintf("char(%d)", ti.Size) return fmt.Sprintf("char(%d)", ti.Size)
case typeBigVarChar, typeVarChar: case typeBigVarChar, typeVarChar:
if ti.Size > 8000 || ti.Size == 0 { if ti.Size > 8000 || ti.Size == 0 {
return fmt.Sprintf("varchar(max)") return "varchar(max)"
} else { } else {
return fmt.Sprintf("varchar(%d)", ti.Size) return fmt.Sprintf("varchar(%d)", ti.Size)
} }

@ -1,11 +1,16 @@
linters-settings: linters-settings:
golint: golint:
min-confidence: 0.3 min-confidence: 0.3
cyclop:
max-complexity: 15
package-average: 10
linters: linters:
disable: disable:
- exhaustivestruct - exhaustivestruct
- gomnd - gomnd
- interfacer
- maligned
presets: presets:
- bugs - bugs
- complexity - complexity

@ -1,5 +1,12 @@
# Change log # Change log
## v2.4.2 - 2021-03-21
- Upgrade google/go-cmp v0.5.5
([#105](https://github.com/editorconfig/editorconfig-core-go/pull/105));
- Upgrade x/mod v0.4.2
([#106](https://github.com/editorconfig/editorconfig-core-go/pull/106)).
## v2.4.1 - 2021-02-25 ## v2.4.1 - 2021-02-25
- Fix for Go 1.16 os.IsNotExist wrapping - Fix for Go 1.16 os.IsNotExist wrapping

@ -121,7 +121,7 @@ func (d *Definition) merge(md *Definition) {
} }
// InsertToIniFile writes the definition into a ini file. // InsertToIniFile writes the definition into a ini file.
func (d *Definition) InsertToIniFile(iniFile *ini.File) { // nolint: funlen,gocognit func (d *Definition) InsertToIniFile(iniFile *ini.File) { // nolint: funlen,gocognit,cyclop
iniSec := iniFile.Section(d.Selector) iniSec := iniFile.Section(d.Selector)
for k, v := range d.Raw { for k, v := range d.Raw {

@ -33,7 +33,7 @@ func FnmatchCase(pattern, name string) (bool, error) {
return r.MatchString(name), nil return r.MatchString(name), nil
} }
func translate(pattern string) string { // nolint: funlen,gocognit,gocyclo func translate(pattern string) string { // nolint: funlen,gocognit,gocyclo,cyclop
index := 0 index := 0
pat := []rune(pattern) pat := []rune(pattern)
length := len(pat) length := len(pat)

@ -3,8 +3,8 @@ module github.com/editorconfig/editorconfig-core-go/v2
go 1.13 go 1.13
require ( require (
github.com/google/go-cmp v0.5.4 github.com/google/go-cmp v0.5.5
github.com/smartystreets/goconvey v1.6.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
golang.org/x/mod v0.4.1 golang.org/x/mod v0.4.2
gopkg.in/ini.v1 v1.62.0 gopkg.in/ini.v1 v1.62.0
) )

@ -1,5 +1,5 @@
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@ -10,8 +10,8 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
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/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=

@ -1,21 +0,0 @@
The MIT license.
Copyright (c) 2014 the go-unsnap-stream authors.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,22 +0,0 @@
go-unsnap-stream
================
This is a small golang library for decoding and encoding the snappy *streaming* format, specified here: https://github.com/google/snappy/blob/master/framing_format.txt
Note that the *streaming or framing format* for snappy is different from snappy itself. Think of it as a train of boxcars: the streaming format breaks your data in chunks, applies snappy to each chunk alone, then puts a thin wrapper around the chunk, and sends it along in turn. You can begin decoding before receiving everything. And memory requirements for decoding are sane.
Strangely, though the streaming format was first proposed in Go[1][2], it was never upated, and I could not locate any other library for Go that would handle the streaming/framed snappy format. Hence this implementation of the spec. There is a command line tool[3] that has a C implementation, but this is the only Go implementation that I am aware of. The reference for the framing/streaming spec seems to be the python implementation[4].
Update to the previous paragraph: Horray! Good news: Thanks to @nigeltao, we have since learned that the [github.com/golang/snappy](https://github.com/golang/snappy) package now provides the snappy streaming format too. Even though the type level descriptions are a little misleading because they don't mention that they are for the stream format, the [snappy package header documentation](https://godoc.org/github.com/golang/snappy) points out that the [snappy.Reader](https://godoc.org/github.com/golang/snappy#Reader) and [snappy.Writer](https://godoc.org/github.com/golang/snappy#Writer) types do indeed provide stream (vs block) handling. Although I have not benchmarked, you should probably prefer that package as it will likely be maintained more than I have time to devote, and also perhaps better integrated with the underlying snappy as they share the same repo.
For binary compatibility with the [python implementation](https://pypi.python.org/pypi/python-snappy) in [4], one could use the C-snappy compressor/decompressor code directly; using github.com/dgryski/go-csnappy. In fact we did this for a while to verify byte-for-byte compatiblity, as the native Go implementation produces slightly different binary compression (still conformant with the standard of course), which made test-diffs harder, and some have complained about it being slower than the C.
However, while the c-snappy was useful for checking compatibility, it introduced dependencies on external C libraries (both the c-snappy library and the C standard library). Our go binary executable that used the go-unsnap-stream library was no longer standalone, and deployment was painful if not impossible if the target had a different C standard library. So we've gone back to using the snappy-go implementation (entirely in Go) for ease of deployment. See the comments at the top of unsnap.go if you wish to use c-snappy instead.
[1] https://groups.google.com/forum/#!msg/snappy-compression/qvLNe2cSH9s/R19oBC-p7g4J
[2] https://codereview.appspot.com/5167058
[3] https://github.com/kubo/snzip
[4] https://pypi.python.org/pypi/python-snappy

Binary file not shown.

Binary file not shown.

@ -1,375 +0,0 @@
package unsnap
// copyright (c) 2014, Jason E. Aten
// license: MIT
// Some text from the Golang standard library doc is adapted and
// reproduced in fragments below to document the expected behaviors
// of the interface functions Read()/Write()/ReadFrom()/WriteTo() that
// are implemented here. Those descriptions (see
// http://golang.org/pkg/io/#Reader for example) are
// copyright 2010 The Go Authors.
import "io"
// FixedSizeRingBuf:
//
// a fixed-size circular ring buffer. Yes, just what is says.
//
// We keep a pair of ping/pong buffers so that we can linearize
// the circular buffer into a contiguous slice if need be.
//
// For efficiency, a FixedSizeRingBuf may be vastly preferred to
// a bytes.Buffer. The ReadWithoutAdvance(), Advance(), and Adopt()
// methods are all non-standard methods written for speed.
//
// For an I/O heavy application, I have replaced bytes.Buffer with
// FixedSizeRingBuf and seen memory consumption go from 8GB to 25MB.
// Yes, that is a 300x reduction in memory footprint. Everything ran
// faster too.
//
// Note that Bytes(), while inescapable at times, is expensive: avoid
// it if possible. Instead it is better to use the FixedSizeRingBuf.Readable
// member to get the number of bytes available. Bytes() is expensive because
// it may copy the back and then the front of a wrapped buffer A[Use]
// into A[1-Use] in order to get a contiguous slice. If possible use ContigLen()
// first to get the size that can be read without copying, Read() that
// amount, and then Read() a second time -- to avoid the copy.
type FixedSizeRingBuf struct {
A [2][]byte // a pair of ping/pong buffers. Only one is active.
Use int // which A buffer is in active use, 0 or 1
N int // MaxViewInBytes, the size of A[0] and A[1] in bytes.
Beg int // start of data in A[Use]
Readable int // number of bytes available to read in A[Use]
OneMade bool // lazily instantiate the [1] buffer. If we never call Bytes(),
// we may never need it. If OneMade is false, the Use must be = 0.
}
func (b *FixedSizeRingBuf) Make2ndBuffer() {
if b.OneMade {
return
}
b.A[1] = make([]byte, b.N, b.N)
b.OneMade = true
}
// get the length of the largest read that we can provide to a contiguous slice
// without an extra linearizing copy of all bytes internally.
func (b *FixedSizeRingBuf) ContigLen() int {
extent := b.Beg + b.Readable
firstContigLen := intMin(extent, b.N) - b.Beg
return firstContigLen
}
func NewFixedSizeRingBuf(maxViewInBytes int) *FixedSizeRingBuf {
n := maxViewInBytes
r := &FixedSizeRingBuf{
Use: 0, // 0 or 1, whichever is actually in use at the moment.
// If we are asked for Bytes() and we wrap, linearize into the other.
N: n,
Beg: 0,
Readable: 0,
OneMade: false,
}
r.A[0] = make([]byte, n, n)
// r.A[1] initialized lazily now.
return r
}
// from the standard library description of Bytes():
// Bytes() returns a slice of the contents of the unread portion of the buffer.
// If the caller changes the contents of the
// returned slice, the contents of the buffer will change provided there
// are no intervening method calls on the Buffer.
//
func (b *FixedSizeRingBuf) Bytes() []byte {
extent := b.Beg + b.Readable
if extent <= b.N {
// we fit contiguously in this buffer without wrapping to the other
return b.A[b.Use][b.Beg:(b.Beg + b.Readable)]
}
// wrap into the other buffer
b.Make2ndBuffer()
src := b.Use
dest := 1 - b.Use
n := copy(b.A[dest], b.A[src][b.Beg:])
n += copy(b.A[dest][n:], b.A[src][0:(extent%b.N)])
b.Use = dest
b.Beg = 0
return b.A[b.Use][:n]
}
// Read():
//
// from bytes.Buffer.Read(): Read reads the next len(p) bytes
// from the buffer or until the buffer is drained. The return
// value n is the number of bytes read. If the buffer has no data
// to return, err is io.EOF (unless len(p) is zero); otherwise it is nil.
//
// from the description of the Reader interface,
// http://golang.org/pkg/io/#Reader
//
/*
Reader is the interface that wraps the basic Read method.
Read reads up to len(p) bytes into p. It returns the number
of bytes read (0 <= n <= len(p)) and any error encountered.
Even if Read returns n < len(p), it may use all of p as scratch
space during the call. If some data is available but not
len(p) bytes, Read conventionally returns what is available
instead of waiting for more.
When Read encounters an error or end-of-file condition after
successfully reading n > 0 bytes, it returns the number of bytes
read. It may return the (non-nil) error from the same call or
return the error (and n == 0) from a subsequent call. An instance
of this general case is that a Reader returning a non-zero number
of bytes at the end of the input stream may return
either err == EOF or err == nil. The next Read should
return 0, EOF regardless.
Callers should always process the n > 0 bytes returned before
considering the error err. Doing so correctly handles I/O errors
that happen after reading some bytes and also both of the
allowed EOF behaviors.
Implementations of Read are discouraged from returning a zero
byte count with a nil error, and callers should treat that
situation as a no-op.
*/
//
func (b *FixedSizeRingBuf) Read(p []byte) (n int, err error) {
return b.ReadAndMaybeAdvance(p, true)
}
// if you want to Read the data and leave it in the buffer, so as
// to peek ahead for example.
func (b *FixedSizeRingBuf) ReadWithoutAdvance(p []byte) (n int, err error) {
return b.ReadAndMaybeAdvance(p, false)
}
func (b *FixedSizeRingBuf) ReadAndMaybeAdvance(p []byte, doAdvance bool) (n int, err error) {
if len(p) == 0 {
return 0, nil
}
if b.Readable == 0 {
return 0, io.EOF
}
extent := b.Beg + b.Readable
if extent <= b.N {
n += copy(p, b.A[b.Use][b.Beg:extent])
} else {
n += copy(p, b.A[b.Use][b.Beg:b.N])
if n < len(p) {
n += copy(p[n:], b.A[b.Use][0:(extent%b.N)])
}
}
if doAdvance {
b.Advance(n)
}
return
}
//
// Write writes len(p) bytes from p to the underlying data stream.
// It returns the number of bytes written from p (0 <= n <= len(p))
// and any error encountered that caused the write to stop early.
// Write must return a non-nil error if it returns n < len(p).
//
func (b *FixedSizeRingBuf) Write(p []byte) (n int, err error) {
for {
if len(p) == 0 {
// nothing (left) to copy in; notice we shorten our
// local copy p (below) as we read from it.
return
}
writeCapacity := b.N - b.Readable
if writeCapacity <= 0 {
// we are all full up already.
return n, io.ErrShortWrite
}
if len(p) > writeCapacity {
err = io.ErrShortWrite
// leave err set and
// keep going, write what we can.
}
writeStart := (b.Beg + b.Readable) % b.N
upperLim := intMin(writeStart+writeCapacity, b.N)
k := copy(b.A[b.Use][writeStart:upperLim], p)
n += k
b.Readable += k
p = p[k:]
// we can fill from b.A[b.Use][0:something] from
// p's remainder, so loop
}
}
// WriteTo and ReadFrom avoid intermediate allocation and copies.
// WriteTo writes data to w until there's no more data to write
// or when an error occurs. The return value n is the number of
// bytes written. Any error encountered during the write is also returned.
func (b *FixedSizeRingBuf) WriteTo(w io.Writer) (n int64, err error) {
if b.Readable == 0 {
return 0, io.EOF
}
extent := b.Beg + b.Readable
firstWriteLen := intMin(extent, b.N) - b.Beg
secondWriteLen := b.Readable - firstWriteLen
if firstWriteLen > 0 {
m, e := w.Write(b.A[b.Use][b.Beg:(b.Beg + firstWriteLen)])
n += int64(m)
b.Advance(m)
if e != nil {
return n, e
}
// all bytes should have been written, by definition of
// Write method in io.Writer
if m != firstWriteLen {
return n, io.ErrShortWrite
}
}
if secondWriteLen > 0 {
m, e := w.Write(b.A[b.Use][0:secondWriteLen])
n += int64(m)
b.Advance(m)
if e != nil {
return n, e
}
// all bytes should have been written, by definition of
// Write method in io.Writer
if m != secondWriteLen {
return n, io.ErrShortWrite
}
}
return n, nil
}
// ReadFrom() reads data from r until EOF or error. The return value n
// is the number of bytes read. Any error except io.EOF encountered
// during the read is also returned.
func (b *FixedSizeRingBuf) ReadFrom(r io.Reader) (n int64, err error) {
for {
writeCapacity := b.N - b.Readable
if writeCapacity <= 0 {
// we are all full
return n, nil
}
writeStart := (b.Beg + b.Readable) % b.N
upperLim := intMin(writeStart+writeCapacity, b.N)
m, e := r.Read(b.A[b.Use][writeStart:upperLim])
n += int64(m)
b.Readable += m
if e == io.EOF {
return n, nil
}
if e != nil {
return n, e
}
}
}
func (b *FixedSizeRingBuf) Reset() {
b.Beg = 0
b.Readable = 0
b.Use = 0
}
// Advance(): non-standard, but better than Next(),
// because we don't have to unwrap our buffer and pay the cpu time
// for the copy that unwrapping may need.
// Useful in conjuction/after ReadWithoutAdvance() above.
func (b *FixedSizeRingBuf) Advance(n int) {
if n <= 0 {
return
}
if n > b.Readable {
n = b.Readable
}
b.Readable -= n
b.Beg = (b.Beg + n) % b.N
}
// Adopt(): non-standard.
//
// For efficiency's sake, (possibly) take ownership of
// already allocated slice offered in me.
//
// If me is large we will adopt it, and we will potentially then
// write to the me buffer.
// If we already have a bigger buffer, copy me into the existing
// buffer instead.
func (b *FixedSizeRingBuf) Adopt(me []byte) {
n := len(me)
if n > b.N {
b.A[0] = me
b.OneMade = false
b.N = n
b.Use = 0
b.Beg = 0
b.Readable = n
} else {
// we already have a larger buffer, reuse it.
copy(b.A[0], me)
b.Use = 0
b.Beg = 0
b.Readable = n
}
}
func intMax(a, b int) int {
if a > b {
return a
} else {
return b
}
}
func intMin(a, b int) int {
if a < b {
return a
} else {
return b
}
}
// Get the (beg, end] indices of the tailing empty buffer of bytes slice that from that is free for writing.
// Note: not guaranteed to be zeroed. At all.
func (b *FixedSizeRingBuf) GetEndmostWritable() (beg int, end int) {
extent := b.Beg + b.Readable
if extent < b.N {
return extent, b.N
}
return extent % b.N, b.Beg
}
// Note: not guaranteed to be zeroed.
func (b *FixedSizeRingBuf) GetEndmostWritableSlice() []byte {
beg, e := b.GetEndmostWritable()
return b.A[b.Use][beg:e]
}

@ -1,100 +0,0 @@
package unsnap
import (
"encoding/binary"
// no c lib dependency
snappy "github.com/golang/snappy"
// or, use the C wrapper for speed
//snappy "github.com/dgryski/go-csnappy"
)
// add Write() method for SnappyFile (see unsnap.go)
// reference for snappy framing/streaming format:
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
// ?spec=svn68&r=71
//
// Write writes len(p) bytes from p to the underlying data stream.
// It returns the number of bytes written from p (0 <= n <= len(p)) and
// any error encountered that caused the write to stop early. Write
// must return a non-nil error if it returns n < len(p).
//
func (sf *SnappyFile) Write(p []byte) (n int, err error) {
if sf.SnappyEncodeDecodeOff {
return sf.Writer.Write(p)
}
if !sf.Writing {
panic("Writing on a read-only SnappyFile")
}
// encoding in snappy can apparently go beyond the original size, beware.
// so our buffers must be sized 2*max snappy chunk => 2 * CHUNK_MAX(65536)
sf.DecBuf.Reset()
sf.EncBuf.Reset()
if !sf.HeaderChunkWritten {
sf.HeaderChunkWritten = true
_, err = sf.Writer.Write(SnappyStreamHeaderMagic)
if err != nil {
return
}
}
var chunk []byte
var chunk_type byte
var crc uint32
for len(p) > 0 {
// chunk points to input p by default, unencoded input.
chunk = p[:IntMin(len(p), CHUNK_MAX)]
crc = masked_crc32c(chunk)
writeme := chunk[:]
// first write to EncBuf, as a temp, in case we want
// to discard and send uncompressed instead.
compressed_chunk := snappy.Encode(sf.EncBuf.GetEndmostWritableSlice(), chunk)
if len(compressed_chunk) <= int((1-_COMPRESSION_THRESHOLD)*float64(len(chunk))) {
writeme = compressed_chunk
chunk_type = _COMPRESSED_CHUNK
} else {
// keep writeme pointing at original chunk (uncompressed)
chunk_type = _UNCOMPRESSED_CHUNK
}
const crc32Sz = 4
var tag32 uint32 = uint32(chunk_type) + (uint32(len(writeme)+crc32Sz) << 8)
err = binary.Write(sf.Writer, binary.LittleEndian, tag32)
if err != nil {
return
}
err = binary.Write(sf.Writer, binary.LittleEndian, crc)
if err != nil {
return
}
_, err = sf.Writer.Write(writeme)
if err != nil {
return
}
n += len(chunk)
p = p[len(chunk):]
}
return n, nil
}
func IntMin(a int, b int) int {
if a < b {
return a
}
return b
}

Binary file not shown.

@ -1,520 +0,0 @@
package unsnap
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
"hash/crc32"
snappy "github.com/golang/snappy"
// The C library can be used, but this makes the binary dependent
// lots of extraneous c-libraries; it is no longer stand-alone. Yuck.
//
// Therefore we comment out the "dgryski/go-csnappy" path and use the
// "github.com/golang/snappy/snappy" above instead. If you are
// performance limited and can deal with distributing more libraries,
// then this is easy to swap.
//
// If you swap, note that some of the tests won't pass
// because snappy-go produces slightly different (but still
// conformant) encodings on some data. Here are bindings
// to the C-snappy:
// snappy "github.com/dgryski/go-csnappy"
)
// SnappyFile: create a drop-in-replacement/wrapper for an *os.File that handles doing the unsnappification online as more is read from it
type SnappyFile struct {
Fname string
Reader io.Reader
Writer io.Writer
// allow clients to substitute us for an os.File and just switch
// off compression if they don't want it.
SnappyEncodeDecodeOff bool // if true, we bypass straight to Filep
EncBuf FixedSizeRingBuf // holds any extra that isn't yet returned, encoded
DecBuf FixedSizeRingBuf // holds any extra that isn't yet returned, decoded
// for writing to stream-framed snappy
HeaderChunkWritten bool
// Sanity check: we can only read, or only write, to one SnappyFile.
// EncBuf and DecBuf are used differently in each mode. Verify
// that we are consistent with this flag.
Writing bool
}
var total int
// for debugging, show state of buffers
func (f *SnappyFile) Dump() {
fmt.Printf("EncBuf has length %d and contents:\n%s\n", len(f.EncBuf.Bytes()), string(f.EncBuf.Bytes()))
fmt.Printf("DecBuf has length %d and contents:\n%s\n", len(f.DecBuf.Bytes()), string(f.DecBuf.Bytes()))
}
func (f *SnappyFile) Read(p []byte) (n int, err error) {
if f.SnappyEncodeDecodeOff {
return f.Reader.Read(p)
}
if f.Writing {
panic("Reading on a write-only SnappyFile")
}
// before we unencrypt more, try to drain the DecBuf first
n, _ = f.DecBuf.Read(p)
if n > 0 {
total += n
return n, nil
}
//nEncRead, nDecAdded, err := UnsnapOneFrame(f.Filep, &f.EncBuf, &f.DecBuf, f.Fname)
_, _, err = UnsnapOneFrame(f.Reader, &f.EncBuf, &f.DecBuf, f.Fname)
if err != nil && err != io.EOF {
return
}
n, _ = f.DecBuf.Read(p)
if n > 0 {
total += n
return n, nil
}
if f.DecBuf.Readable == 0 {
if f.DecBuf.Readable == 0 && f.EncBuf.Readable == 0 {
// only now (when EncBuf is empty) can we give io.EOF.
// Any earlier, and we leave stuff un-decoded!
return 0, io.EOF
}
}
return 0, nil
}
func Open(name string) (file *SnappyFile, err error) {
fp, err := os.Open(name)
if err != nil {
return nil, err
}
// encoding in snappy can apparently go beyond the original size, so
// we make our buffers big enough, 2*max snappy chunk => 2 * CHUNK_MAX(65536)
snap := NewReader(fp)
snap.Fname = name
return snap, nil
}
func NewReader(r io.Reader) *SnappyFile {
return &SnappyFile{
Reader: r,
EncBuf: *NewFixedSizeRingBuf(CHUNK_MAX * 2), // buffer of snappy encoded bytes
DecBuf: *NewFixedSizeRingBuf(CHUNK_MAX * 2), // buffer of snapppy decoded bytes
Writing: false,
}
}
func NewWriter(w io.Writer) *SnappyFile {
return &SnappyFile{
Writer: w,
EncBuf: *NewFixedSizeRingBuf(65536), // on writing: temp for testing compression
DecBuf: *NewFixedSizeRingBuf(65536 * 2), // on writing: final buffer of snappy framed and encoded bytes
Writing: true,
}
}
func Create(name string) (file *SnappyFile, err error) {
fp, err := os.Create(name)
if err != nil {
return nil, err
}
snap := NewWriter(fp)
snap.Fname = name
return snap, nil
}
func (f *SnappyFile) Close() error {
if f.Writing {
wc, ok := f.Writer.(io.WriteCloser)
if ok {
return wc.Close()
}
return nil
}
rc, ok := f.Reader.(io.ReadCloser)
if ok {
return rc.Close()
}
return nil
}
func (f *SnappyFile) Sync() error {
file, ok := f.Writer.(*os.File)
if ok {
return file.Sync()
}
return nil
}
// for an increment of a frame at a time:
// read from r into encBuf (encBuf is still encoded, thus the name), and write unsnappified frames into outDecodedBuf
// the returned n: number of bytes read from the encrypted encBuf
func UnsnapOneFrame(r io.Reader, encBuf *FixedSizeRingBuf, outDecodedBuf *FixedSizeRingBuf, fname string) (nEnc int64, nDec int64, err error) {
// b, err := ioutil.ReadAll(r)
// if err != nil {
// panic(err)
// }
nEnc = 0
nDec = 0
// read up to 65536 bytes from r into encBuf, at least a snappy frame
nread, err := io.CopyN(encBuf, r, 65536) // returns nwrotebytes, err
nEnc += nread
if err != nil {
if err == io.EOF {
if nread == 0 {
if encBuf.Readable == 0 {
return nEnc, nDec, io.EOF
}
// else we have bytes in encBuf, so decode them!
err = nil
} else {
// continue below, processing the nread bytes
err = nil
}
} else {
// may be an odd already closed... don't panic on that
if strings.Contains(err.Error(), "file already closed") {
err = nil
} else {
panic(err)
}
}
}
// flag for printing chunk size alignment messages
verbose := false
const snappyStreamHeaderSz = 10
const headerSz = 4
const crc32Sz = 4
// the magic 18 bytes accounts for the snappy streaming header and the first chunks size and checksum
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
chunk := (*encBuf).Bytes()
// however we exit, advance as
// defer func() { (*encBuf).Next(N) }()
// 65536 is the max size of a snappy framed chunk. See
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt:91
// buf := make([]byte, 65536)
// fmt.Printf("read from file, b is len:%d with value: %#v\n", len(b), b)
// fmt.Printf("read from file, bcut is len:%d with value: %#v\n", len(bcut), bcut)
//fmt.Printf("raw bytes of chunksz are: %v\n", b[11:14])
fourbytes := make([]byte, 4)
chunkCount := 0
for nDec < 65536 {
if len(chunk) == 0 {
break
}
chunkCount++
fourbytes[3] = 0
copy(fourbytes, chunk[1:4])
chunksz := binary.LittleEndian.Uint32(fourbytes)
chunk_type := chunk[0]
switch true {
case chunk_type == 0xff:
{ // stream identifier
streamHeader := chunk[:snappyStreamHeaderSz]
if 0 != bytes.Compare(streamHeader, []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}) {
panic("file had chunk starting with 0xff but then no magic snappy streaming protocol bytes, aborting.")
} else {
//fmt.Printf("got streaming snappy magic header just fine.\n")
}
chunk = chunk[snappyStreamHeaderSz:]
(*encBuf).Advance(snappyStreamHeaderSz)
nEnc += snappyStreamHeaderSz
continue
}
case chunk_type == 0x00:
{ // compressed data
if verbose {
fmt.Fprintf(os.Stderr, "chunksz is %d while total bytes avail are: %d\n", int(chunksz), len(chunk)-4)
}
crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
dec, ok := snappy.Decode(nil, section)
if ok != nil {
// we've probably truncated a snappy frame at this point
// ok=snappy: corrupt input
// len(dec) == 0
//
err = fmt.Errorf("could not decode snappy stream: '%s' and len dec=%d and error='%v'\n", fname, len(dec), ok)
// get back to caller with what we've got so far
return nEnc, nDec, err
}
// fmt.Printf("ok, b is %#v , %#v\n", ok, dec)
// spit out decoded text
// n, err := w.Write(dec)
//fmt.Printf("len(dec) = %d, outDecodedBuf.Readable=%d\n", len(dec), outDecodedBuf.Readable)
bnb := bytes.NewBuffer(dec)
n, err := io.Copy(outDecodedBuf, bnb)
if err != nil {
//fmt.Printf("got n=%d, err= %s ; when trying to io.Copy(outDecodedBuf: N=%d, Readable=%d)\n", n, err, outDecodedBuf.N, outDecodedBuf.Readable)
panic(err)
}
if n != int64(len(dec)) {
panic("could not write all bytes to outDecodedBuf")
}
nDec += n
// verify the crc32 rotated checksum
m32 := masked_crc32c(dec)
if m32 != crc {
panic(fmt.Sprintf("crc32 masked failiure. expected: %v but got: %v", crc, m32))
} else {
//fmt.Printf("\nchecksums match: %v == %v\n", crc, m32)
}
// move to next header
inc := (headerSz + int(chunksz))
chunk = chunk[inc:]
(*encBuf).Advance(inc)
nEnc += int64(inc)
continue
}
case chunk_type == 0x01:
{ // uncompressed data
//n, err := w.Write(chunk[(headerSz+crc32Sz):(headerSz + int(chunksz))])
n, err := io.Copy(outDecodedBuf, bytes.NewBuffer(chunk[(headerSz+crc32Sz):(headerSz+int(chunksz))]))
if verbose {
//fmt.Printf("debug: n=%d err=%v chunksz=%d outDecodedBuf='%v'\n", n, err, chunksz, outDecodedBuf)
}
if err != nil {
panic(err)
}
if n != int64(chunksz-crc32Sz) {
panic("could not write all bytes to stdout")
}
nDec += n
inc := (headerSz + int(chunksz))
chunk = chunk[inc:]
(*encBuf).Advance(inc)
nEnc += int64(inc)
continue
}
case chunk_type == 0xfe:
fallthrough // padding, just skip it
case chunk_type >= 0x80 && chunk_type <= 0xfd:
{ // Reserved skippable chunks
//fmt.Printf("\nin reserved skippable chunks, at nEnc=%v\n", nEnc)
inc := (headerSz + int(chunksz))
chunk = chunk[inc:]
nEnc += int64(inc)
(*encBuf).Advance(inc)
continue
}
default:
err = fmt.Errorf("unrecognized/unsupported chunk type %#v; on fname='%v'", chunk_type, fname)
return nEnc, nDec, err
}
} // end for{}
return nEnc, nDec, err
//return int64(N), nil
}
// for whole file at once:
//
// receive on stdin a stream of bytes in the snappy-streaming framed
// format, defined here: http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
// Grab each frame, run it through the snappy decoder, and spit out
// each frame all joined back-to-back on stdout.
//
func Unsnappy(r io.Reader, w io.Writer) (err error) {
b, err := ioutil.ReadAll(r)
if err != nil {
panic(err)
}
// flag for printing chunk size alignment messages
verbose := false
const snappyStreamHeaderSz = 10
const headerSz = 4
const crc32Sz = 4
// the magic 18 bytes accounts for the snappy streaming header and the first chunks size and checksum
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
chunk := b[:]
// 65536 is the max size of a snappy framed chunk. See
// http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt:91
//buf := make([]byte, 65536)
// fmt.Printf("read from file, b is len:%d with value: %#v\n", len(b), b)
// fmt.Printf("read from file, bcut is len:%d with value: %#v\n", len(bcut), bcut)
//fmt.Printf("raw bytes of chunksz are: %v\n", b[11:14])
fourbytes := make([]byte, 4)
chunkCount := 0
for {
if len(chunk) == 0 {
break
}
chunkCount++
fourbytes[3] = 0
copy(fourbytes, chunk[1:4])
chunksz := binary.LittleEndian.Uint32(fourbytes)
chunk_type := chunk[0]
switch true {
case chunk_type == 0xff:
{ // stream identifier
streamHeader := chunk[:snappyStreamHeaderSz]
if 0 != bytes.Compare(streamHeader, []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}) {
panic("file had chunk starting with 0xff but then no magic snappy streaming protocol bytes, aborting.")
} else {
//fmt.Printf("got streaming snappy magic header just fine.\n")
}
chunk = chunk[snappyStreamHeaderSz:]
continue
}
case chunk_type == 0x00:
{ // compressed data
if verbose {
fmt.Fprintf(os.Stderr, "chunksz is %d while total bytes avail are: %d\n", int(chunksz), len(chunk)-4)
}
//crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
dec, ok := snappy.Decode(nil, section)
if ok != nil {
panic("could not decode snappy stream")
}
// fmt.Printf("ok, b is %#v , %#v\n", ok, dec)
// spit out decoded text
n, err := w.Write(dec)
if err != nil {
panic(err)
}
if n != len(dec) {
panic("could not write all bytes to stdout")
}
// TODO: verify the crc32 rotated checksum?
// move to next header
chunk = chunk[(headerSz + int(chunksz)):]
continue
}
case chunk_type == 0x01:
{ // uncompressed data
//crc := binary.LittleEndian.Uint32(chunk[headerSz:(headerSz + crc32Sz)])
section := chunk[(headerSz + crc32Sz):(headerSz + chunksz)]
n, err := w.Write(section)
if err != nil {
panic(err)
}
if n != int(chunksz-crc32Sz) {
panic("could not write all bytes to stdout")
}
chunk = chunk[(headerSz + int(chunksz)):]
continue
}
case chunk_type == 0xfe:
fallthrough // padding, just skip it
case chunk_type >= 0x80 && chunk_type <= 0xfd:
{ // Reserved skippable chunks
chunk = chunk[(headerSz + int(chunksz)):]
continue
}
default:
panic(fmt.Sprintf("unrecognized/unsupported chunk type %#v", chunk_type))
}
} // end for{}
return nil
}
// 0xff 0x06 0x00 0x00 sNaPpY
var SnappyStreamHeaderMagic = []byte{0xff, 0x06, 0x00, 0x00, 0x73, 0x4e, 0x61, 0x50, 0x70, 0x59}
const CHUNK_MAX = 65536
const _STREAM_TO_STREAM_BLOCK_SIZE = CHUNK_MAX
const _STREAM_IDENTIFIER = `sNaPpY`
const _COMPRESSED_CHUNK = 0x00
const _UNCOMPRESSED_CHUNK = 0x01
const _IDENTIFIER_CHUNK = 0xff
const _RESERVED_UNSKIPPABLE0 = 0x02 // chunk ranges are [inclusive, exclusive)
const _RESERVED_UNSKIPPABLE1 = 0x80
const _RESERVED_SKIPPABLE0 = 0x80
const _RESERVED_SKIPPABLE1 = 0xff
// the minimum percent of bytes compression must save to be enabled in automatic
// mode
const _COMPRESSION_THRESHOLD = .125
var crctab *crc32.Table
func init() {
crctab = crc32.MakeTable(crc32.Castagnoli) // this is correct table, matches the crc32c.c code used by python
}
func masked_crc32c(data []byte) uint32 {
// see the framing format specification, http://code.google.com/p/snappy/source/browse/trunk/framing_format.txt
var crc uint32 = crc32.Checksum(data, crctab)
return (uint32((crc>>15)|(crc<<17)) + 0xa282ead8)
}
func ReadSnappyStreamCompressedFile(filename string) ([]byte, error) {
snappyFile, err := Open(filename)
if err != nil {
return []byte{}, err
}
var bb bytes.Buffer
_, err = bb.ReadFrom(snappyFile)
if err == io.EOF {
err = nil
}
if err != nil {
panic(err)
}
return bb.Bytes(), err
}

@ -16,8 +16,8 @@ func main() {
// Basic CORS // Basic CORS
// for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing // for more ideas, see: https://developer.github.com/v3/#cross-origin-resource-sharing
r.Use(cors.Handler(cors.Options{ r.Use(cors.Handler(cors.Options{
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts // AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
AllowedOrigins: []string{"*"}, AllowedOrigins: []string{"https://*", "http://*"},
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true }, // AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"}, AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},

@ -0,0 +1,3 @@
module github.com/go-chi/cors
go 1.14

@ -1,4 +1,4 @@
# go-billy [![GoDoc](https://godoc.org/gopkg.in/go-git/go-billy.v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-billy) [![Test](https://github.com/go-git/go-billy/workflows/Test/badge.svg)](https://github.com/go-git/go-billy/actions?query=workflow%3ATest) # go-billy [![GoDoc](https://godoc.org/gopkg.in/go-git/go-billy.v5?status.svg)](https://pkg.go.dev/github.com/go-git/go-billy/v5) [![Test](https://github.com/go-git/go-billy/workflows/Test/badge.svg)](https://github.com/go-git/go-billy/actions?query=workflow%3ATest)
The missing interface filesystem abstraction for Go. The missing interface filesystem abstraction for Go.
Billy implements an interface based on the `os` standard library, allowing to develop applications without dependency on the underlying storage. Makes it virtually free to implement mocks and testing over filesystem operations. Billy implements an interface based on the `os` standard library, allowing to develop applications without dependency on the underlying storage. Makes it virtually free to implement mocks and testing over filesystem operations.

@ -89,6 +89,13 @@ type Config struct {
Window uint Window uint
} }
Init struct {
// DefaultBranch Allows overriding the default branch name
// e.g. when initializing a new repository or when cloning
// an empty repository.
DefaultBranch string
}
// Remotes list of repository remotes, the key of the map is the name // Remotes list of repository remotes, the key of the map is the name
// of the remote, should equal to RemoteConfig.Name. // of the remote, should equal to RemoteConfig.Name.
Remotes map[string]*RemoteConfig Remotes map[string]*RemoteConfig
@ -98,6 +105,9 @@ type Config struct {
// Branches list of branches, the key is the branch name and should // Branches list of branches, the key is the branch name and should
// equal Branch.Name // equal Branch.Name
Branches map[string]*Branch Branches map[string]*Branch
// URLs list of url rewrite rules, if repo url starts with URL.InsteadOf value, it will be replaced with the
// key instead.
URLs map[string]*URL
// Raw contains the raw information of a config file. The main goal is // Raw contains the raw information of a config file. The main goal is
// preserve the parsed information from the original format, to avoid // preserve the parsed information from the original format, to avoid
// dropping unsupported fields. // dropping unsupported fields.
@ -110,6 +120,7 @@ func NewConfig() *Config {
Remotes: make(map[string]*RemoteConfig), Remotes: make(map[string]*RemoteConfig),
Submodules: make(map[string]*Submodule), Submodules: make(map[string]*Submodule),
Branches: make(map[string]*Branch), Branches: make(map[string]*Branch),
URLs: make(map[string]*URL),
Raw: format.New(), Raw: format.New(),
} }
@ -223,6 +234,8 @@ const (
userSection = "user" userSection = "user"
authorSection = "author" authorSection = "author"
committerSection = "committer" committerSection = "committer"
initSection = "init"
urlSection = "url"
fetchKey = "fetch" fetchKey = "fetch"
urlKey = "url" urlKey = "url"
bareKey = "bare" bareKey = "bare"
@ -233,6 +246,7 @@ const (
rebaseKey = "rebase" rebaseKey = "rebase"
nameKey = "name" nameKey = "name"
emailKey = "email" emailKey = "email"
defaultBranchKey = "defaultBranch"
// DefaultPackWindow holds the number of previous objects used to // DefaultPackWindow holds the number of previous objects used to
// generate deltas. The value 10 is the same used by git command. // generate deltas. The value 10 is the same used by git command.
@ -251,6 +265,7 @@ func (c *Config) Unmarshal(b []byte) error {
c.unmarshalCore() c.unmarshalCore()
c.unmarshalUser() c.unmarshalUser()
c.unmarshalInit()
if err := c.unmarshalPack(); err != nil { if err := c.unmarshalPack(); err != nil {
return err return err
} }
@ -260,6 +275,10 @@ func (c *Config) Unmarshal(b []byte) error {
return err return err
} }
if err := c.unmarshalURLs(); err != nil {
return err
}
return c.unmarshalRemotes() return c.unmarshalRemotes()
} }
@ -313,6 +332,25 @@ func (c *Config) unmarshalRemotes() error {
c.Remotes[r.Name] = r c.Remotes[r.Name] = r
} }
// Apply insteadOf url rules
for _, r := range c.Remotes {
r.applyURLRules(c.URLs)
}
return nil
}
func (c *Config) unmarshalURLs() error {
s := c.Raw.Section(urlSection)
for _, sub := range s.Subsections {
r := &URL{}
if err := r.unmarshal(sub); err != nil {
return err
}
c.URLs[r.Name] = r
}
return nil return nil
} }
@ -344,6 +382,11 @@ func (c *Config) unmarshalBranches() error {
return nil return nil
} }
func (c *Config) unmarshalInit() {
s := c.Raw.Section(initSection)
c.Init.DefaultBranch = s.Options.Get(defaultBranchKey)
}
// Marshal returns Config encoded as a git-config file. // Marshal returns Config encoded as a git-config file.
func (c *Config) Marshal() ([]byte, error) { func (c *Config) Marshal() ([]byte, error) {
c.marshalCore() c.marshalCore()
@ -352,6 +395,8 @@ func (c *Config) Marshal() ([]byte, error) {
c.marshalRemotes() c.marshalRemotes()
c.marshalSubmodules() c.marshalSubmodules()
c.marshalBranches() c.marshalBranches()
c.marshalURLs()
c.marshalInit()
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
if err := format.NewEncoder(buf).Encode(c.Raw); err != nil { if err := format.NewEncoder(buf).Encode(c.Raw); err != nil {
@ -475,6 +520,27 @@ func (c *Config) marshalBranches() {
s.Subsections = newSubsections s.Subsections = newSubsections
} }
func (c *Config) marshalURLs() {
s := c.Raw.Section(urlSection)
s.Subsections = make(format.Subsections, len(c.URLs))
var i int
for _, r := range c.URLs {
section := r.marshal()
// the submodule section at config is a subset of the .gitmodule file
// we should remove the non-valid options for the config file.
s.Subsections[i] = section
i++
}
}
func (c *Config) marshalInit() {
s := c.Raw.Section(initSection)
if c.Init.DefaultBranch != "" {
s.SetOption(defaultBranchKey, c.Init.DefaultBranch)
}
}
// RemoteConfig contains the configuration for a given remote repository. // RemoteConfig contains the configuration for a given remote repository.
type RemoteConfig struct { type RemoteConfig struct {
// Name of the remote // Name of the remote
@ -482,6 +548,12 @@ type RemoteConfig struct {
// URLs the URLs of a remote repository. It must be non-empty. Fetch will // URLs the URLs of a remote repository. It must be non-empty. Fetch will
// always use the first URL, while push will use all of them. // always use the first URL, while push will use all of them.
URLs []string URLs []string
// insteadOfRulesApplied have urls been modified
insteadOfRulesApplied bool
// originalURLs are the urls before applying insteadOf rules
originalURLs []string
// Fetch the default set of "refspec" for fetch operation // Fetch the default set of "refspec" for fetch operation
Fetch []RefSpec Fetch []RefSpec
@ -542,7 +614,12 @@ func (c *RemoteConfig) marshal() *format.Subsection {
if len(c.URLs) == 0 { if len(c.URLs) == 0 {
c.raw.RemoveOption(urlKey) c.raw.RemoveOption(urlKey)
} else { } else {
c.raw.SetOption(urlKey, c.URLs...) urls := c.URLs
if c.insteadOfRulesApplied {
urls = c.originalURLs
}
c.raw.SetOption(urlKey, urls...)
} }
if len(c.Fetch) == 0 { if len(c.Fetch) == 0 {
@ -562,3 +639,20 @@ func (c *RemoteConfig) marshal() *format.Subsection {
func (c *RemoteConfig) IsFirstURLLocal() bool { func (c *RemoteConfig) IsFirstURLLocal() bool {
return url.IsLocalEndpoint(c.URLs[0]) return url.IsLocalEndpoint(c.URLs[0])
} }
func (c *RemoteConfig) applyURLRules(urlRules map[string]*URL) {
// save original urls
originalURLs := make([]string, len(c.URLs))
copy(originalURLs, c.URLs)
for i, url := range c.URLs {
if matchingURLRule := findLongestInsteadOfMatch(url, urlRules); matchingURLRule != nil {
c.URLs[i] = matchingURLRule.ApplyInsteadOf(c.URLs[i])
c.insteadOfRulesApplied = true
}
}
if c.insteadOfRulesApplied {
c.originalURLs = originalURLs
}
}

@ -0,0 +1,81 @@
package config
import (
"errors"
"strings"
format "github.com/go-git/go-git/v5/plumbing/format/config"
)
var (
errURLEmptyInsteadOf = errors.New("url config: empty insteadOf")
)
// Url defines Url rewrite rules
type URL struct {
// Name new base url
Name string
// Any URL that starts with this value will be rewritten to start, instead, with <base>.
// When more than one insteadOf strings match a given URL, the longest match is used.
InsteadOf string
// raw representation of the subsection, filled by marshal or unmarshal are
// called.
raw *format.Subsection
}
// Validate validates fields of branch
func (b *URL) Validate() error {
if b.InsteadOf == "" {
return errURLEmptyInsteadOf
}
return nil
}
const (
insteadOfKey = "insteadOf"
)
func (u *URL) unmarshal(s *format.Subsection) error {
u.raw = s
u.Name = s.Name
u.InsteadOf = u.raw.Option(insteadOfKey)
return nil
}
func (u *URL) marshal() *format.Subsection {
if u.raw == nil {
u.raw = &format.Subsection{}
}
u.raw.Name = u.Name
u.raw.SetOption(insteadOfKey, u.InsteadOf)
return u.raw
}
func findLongestInsteadOfMatch(remoteURL string, urls map[string]*URL) *URL {
var longestMatch *URL
for _, u := range urls {
if !strings.HasPrefix(remoteURL, u.InsteadOf) {
continue
}
// according to spec if there is more than one match, take the logest
if longestMatch == nil || len(longestMatch.InsteadOf) < len(u.InsteadOf) {
longestMatch = u
}
}
return longestMatch
}
func (u *URL) ApplyInsteadOf(url string) string {
if !strings.HasPrefix(url, u.InsteadOf) {
return url
}
return u.Name + url[len(u.InsteadOf):]
}

@ -1,27 +1,27 @@
module github.com/go-git/go-git/v5 module github.com/go-git/go-git/v5
require ( require (
github.com/Microsoft/go-winio v0.4.16 // indirect
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 // indirect
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
github.com/emirpasic/gods v1.12.0 github.com/emirpasic/gods v1.12.0
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/gliderlabs/ssh v0.2.2 github.com/gliderlabs/ssh v0.2.2
github.com/go-git/gcfg v1.5.0 github.com/go-git/gcfg v1.5.0
github.com/go-git/go-billy/v5 v5.0.0 github.com/go-git/go-billy/v5 v5.1.0
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12
github.com/google/go-cmp v0.3.0 github.com/google/go-cmp v0.3.0
github.com/imdario/mergo v0.3.9 github.com/imdario/mergo v0.3.12
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
github.com/jessevdk/go-flags v1.4.0 github.com/jessevdk/go-flags v1.5.0
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/pkg/errors v0.8.1 // indirect
github.com/sergi/go-diff v1.1.0 github.com/sergi/go-diff v1.1.0
github.com/xanzy/ssh-agent v0.2.1 github.com/xanzy/ssh-agent v0.3.0
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/net v0.0.0-20200301022130-244492dfa37a golang.org/x/net v0.0.0-20210326060303-6b1517762897
golang.org/x/text v0.3.2 golang.org/x/text v0.3.3
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
) )

@ -1,3 +1,6 @@
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
@ -18,6 +21,8 @@ github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTYahk=
github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc= github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
@ -26,14 +31,23 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@ -45,38 +59,62 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

@ -60,6 +60,10 @@ type CloneOptions struct {
// Tags describe how the tags will be fetched from the remote repository, // Tags describe how the tags will be fetched from the remote repository,
// by default is AllTags. // by default is AllTags.
Tags TagMode Tags TagMode
// InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
// CABundle specify additional ca bundle with system cert pool
CABundle []byte
} }
// Validate validates the fields and sets the default values. // Validate validates the fields and sets the default values.
@ -105,6 +109,10 @@ type PullOptions struct {
// Force allows the pull to update a local branch even when the remote // Force allows the pull to update a local branch even when the remote
// branch does not descend from it. // branch does not descend from it.
Force bool Force bool
// InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
// CABundle specify additional ca bundle with system cert pool
CABundle []byte
} }
// Validate validates the fields and sets the default values. // Validate validates the fields and sets the default values.
@ -155,6 +163,10 @@ type FetchOptions struct {
// Force allows the fetch to update a local branch even when the remote // Force allows the fetch to update a local branch even when the remote
// branch does not descend from it. // branch does not descend from it.
Force bool Force bool
// InsecureSkipTLS skips ssl verify if protocol is https
InsecureSkipTLS bool
// CABundle specify additional ca bundle with system cert pool
CABundle []byte
} }
// Validate validates the fields and sets the default values. // Validate validates the fields and sets the default values.
@ -194,6 +206,13 @@ type PushOptions struct {
// Force allows the push to update a remote branch even when the local // Force allows the push to update a remote branch even when the local
// branch does not descend from it. // branch does not descend from it.
Force bool Force bool
// InsecureSkipTLS skips ssl verify if protocal is https
InsecureSkipTLS bool
// CABundle specify additional ca bundle with system cert pool
CABundle []byte
// RequireRemoteRefs only allows a remote ref to be updated if its current
// value is the one specified here.
RequireRemoteRefs []config.RefSpec
} }
// Validate validates the fields and sets the default values. // Validate validates the fields and sets the default values.
@ -552,6 +571,10 @@ func (o *CreateTagOptions) loadConfigTagger(r *Repository) error {
type ListOptions struct { type ListOptions struct {
// Auth credentials, if required, to use with the remote repository. // Auth credentials, if required, to use with the remote repository.
Auth transport.AuthMethod Auth transport.AuthMethod
// InsecureSkipTLS skips ssl verify if protocal is https
InsecureSkipTLS bool
// CABundle specify additional ca bundle with system cert pool
CABundle []byte
} }
// CleanOptions describes how a clean should be performed. // CleanOptions describes how a clean should be performed.

@ -38,6 +38,10 @@ type UnifiedEncoder struct {
// a change. // a change.
contextLines int contextLines int
// srcPrefix and dstPrefix are prepended to file paths when encoding a diff.
srcPrefix string
dstPrefix string
// colorConfig is the color configuration. The default is no color. // colorConfig is the color configuration. The default is no color.
color ColorConfig color ColorConfig
} }
@ -46,6 +50,8 @@ type UnifiedEncoder struct {
func NewUnifiedEncoder(w io.Writer, contextLines int) *UnifiedEncoder { func NewUnifiedEncoder(w io.Writer, contextLines int) *UnifiedEncoder {
return &UnifiedEncoder{ return &UnifiedEncoder{
Writer: w, Writer: w,
srcPrefix: "a/",
dstPrefix: "b/",
contextLines: contextLines, contextLines: contextLines,
} }
} }
@ -56,6 +62,18 @@ func (e *UnifiedEncoder) SetColor(colorConfig ColorConfig) *UnifiedEncoder {
return e return e
} }
// SetSrcPrefix sets e's srcPrefix and returns e.
func (e *UnifiedEncoder) SetSrcPrefix(prefix string) *UnifiedEncoder {
e.srcPrefix = prefix
return e
}
// SetDstPrefix sets e's dstPrefix and returns e.
func (e *UnifiedEncoder) SetDstPrefix(prefix string) *UnifiedEncoder {
e.dstPrefix = prefix
return e
}
// Encode encodes patch. // Encode encodes patch.
func (e *UnifiedEncoder) Encode(patch Patch) error { func (e *UnifiedEncoder) Encode(patch Patch) error {
sb := &strings.Builder{} sb := &strings.Builder{}
@ -91,7 +109,8 @@ func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch Fil
case from != nil && to != nil: case from != nil && to != nil:
hashEquals := from.Hash() == to.Hash() hashEquals := from.Hash() == to.Hash()
lines = append(lines, lines = append(lines,
fmt.Sprintf("diff --git a/%s b/%s", from.Path(), to.Path()), fmt.Sprintf("diff --git %s%s %s%s",
e.srcPrefix, from.Path(), e.dstPrefix, to.Path()),
) )
if from.Mode() != to.Mode() { if from.Mode() != to.Mode() {
lines = append(lines, lines = append(lines,
@ -115,22 +134,22 @@ func (e *UnifiedEncoder) writeFilePatchHeader(sb *strings.Builder, filePatch Fil
) )
} }
if !hashEquals { if !hashEquals {
lines = e.appendPathLines(lines, "a/"+from.Path(), "b/"+to.Path(), isBinary) lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), e.dstPrefix+to.Path(), isBinary)
} }
case from == nil: case from == nil:
lines = append(lines, lines = append(lines,
fmt.Sprintf("diff --git a/%s b/%s", to.Path(), to.Path()), fmt.Sprintf("diff --git %s %s", e.srcPrefix+to.Path(), e.dstPrefix+to.Path()),
fmt.Sprintf("new file mode %o", to.Mode()), fmt.Sprintf("new file mode %o", to.Mode()),
fmt.Sprintf("index %s..%s", plumbing.ZeroHash, to.Hash()), fmt.Sprintf("index %s..%s", plumbing.ZeroHash, to.Hash()),
) )
lines = e.appendPathLines(lines, "/dev/null", "b/"+to.Path(), isBinary) lines = e.appendPathLines(lines, "/dev/null", e.dstPrefix+to.Path(), isBinary)
case to == nil: case to == nil:
lines = append(lines, lines = append(lines,
fmt.Sprintf("diff --git a/%s b/%s", from.Path(), from.Path()), fmt.Sprintf("diff --git %s %s", e.srcPrefix+from.Path(), e.dstPrefix+from.Path()),
fmt.Sprintf("deleted file mode %o", from.Mode()), fmt.Sprintf("deleted file mode %o", from.Mode()),
fmt.Sprintf("index %s..%s", from.Hash(), plumbing.ZeroHash), fmt.Sprintf("index %s..%s", from.Hash(), plumbing.ZeroHash),
) )
lines = e.appendPathLines(lines, "a/"+from.Path(), "/dev/null", isBinary) lines = e.appendPathLines(lines, e.srcPrefix+from.Path(), "/dev/null", isBinary)
} }
sb.WriteString(e.color[Meta]) sb.WriteString(e.color[Meta])

@ -125,7 +125,7 @@ func LoadGlobalPatterns(fs billy.Filesystem) (ps []Pattern, err error) {
} }
// LoadSystemPatterns loads gitignore patterns from from the gitignore file // LoadSystemPatterns loads gitignore patterns from from the gitignore file
// declared in a system's /etc/gitconfig file. If the ~/.gitconfig file does // declared in a system's /etc/gitconfig file. If the /etc/gitconfig file does
// not exist the function will return nil. If the core.excludesfile property // not exist the function will return nil. If the core.excludesfile property
// is not declared, the function will return nil. If the file pointed to by // is not declared, the function will return nil. If the file pointed to by
// the core.excludesfile property does not exist, the function will return nil. // the core.excludesfile property does not exist, the function will return nil.

@ -230,6 +230,12 @@ const (
PushCert Capability = "push-cert" PushCert Capability = "push-cert"
// SymRef symbolic reference support for better negotiation. // SymRef symbolic reference support for better negotiation.
SymRef Capability = "symref" SymRef Capability = "symref"
// ObjectFormat takes a hash algorithm as an argument, indicates that the
// server supports the given hash algorithms.
ObjectFormat Capability = "object-format"
// Filter if present, fetch-pack may send "filter" commands to request a
// partial clone or partial fetch and request that the server omit various objects from the packfile
Filter Capability = "filter"
) )
const DefaultAgent = "go-git/4.x" const DefaultAgent = "go-git/4.x"
@ -241,10 +247,11 @@ var known = map[Capability]bool{
NoProgress: true, IncludeTag: true, ReportStatus: true, DeleteRefs: true, NoProgress: true, IncludeTag: true, ReportStatus: true, DeleteRefs: true,
Quiet: true, Atomic: true, PushOptions: true, AllowTipSHA1InWant: true, Quiet: true, Atomic: true, PushOptions: true, AllowTipSHA1InWant: true,
AllowReachableSHA1InWant: true, PushCert: true, SymRef: true, AllowReachableSHA1InWant: true, PushCert: true, SymRef: true,
ObjectFormat: true, Filter: true,
} }
var requiresArgument = map[Capability]bool{ var requiresArgument = map[Capability]bool{
Agent: true, PushCert: true, SymRef: true, Agent: true, PushCert: true, SymRef: true, ObjectFormat: true,
} }
var multipleArgument = map[Capability]bool{ var multipleArgument = map[Capability]bool{

@ -3,7 +3,10 @@
package client package client
import ( import (
"crypto/tls"
"crypto/x509"
"fmt" "fmt"
gohttp "net/http"
"github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/file" "github.com/go-git/go-git/v5/plumbing/transport/file"
@ -21,6 +24,14 @@ var Protocols = map[string]transport.Transport{
"file": file.DefaultClient, "file": file.DefaultClient,
} }
var insecureClient = http.NewClient(&gohttp.Client{
Transport: &gohttp.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
})
// InstallProtocol adds or modifies an existing protocol. // InstallProtocol adds or modifies an existing protocol.
func InstallProtocol(scheme string, c transport.Transport) { func InstallProtocol(scheme string, c transport.Transport) {
if c == nil { if c == nil {
@ -35,6 +46,31 @@ func InstallProtocol(scheme string, c transport.Transport) {
// http://, https://, ssh:// and file://. // http://, https://, ssh:// and file://.
// See `InstallProtocol` to add or modify protocols. // See `InstallProtocol` to add or modify protocols.
func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) { func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
return getTransport(endpoint)
}
func getTransport(endpoint *transport.Endpoint) (transport.Transport, error) {
if endpoint.Protocol == "https" {
if endpoint.InsecureSkipTLS {
return insecureClient, nil
}
if len(endpoint.CaBundle) != 0 {
rootCAs, _ := x509.SystemCertPool()
if rootCAs == nil {
rootCAs = x509.NewCertPool()
}
rootCAs.AppendCertsFromPEM(endpoint.CaBundle)
return http.NewClient(&gohttp.Client{
Transport: &gohttp.Transport{
TLSClientConfig: &tls.Config{
RootCAs: rootCAs,
},
},
}), nil
}
}
f, ok := Protocols[endpoint.Protocol] f, ok := Protocols[endpoint.Protocol]
if !ok { if !ok {
return nil, fmt.Errorf("unsupported scheme %q", endpoint.Protocol) return nil, fmt.Errorf("unsupported scheme %q", endpoint.Protocol)
@ -43,6 +79,5 @@ func NewClient(endpoint *transport.Endpoint) (transport.Transport, error) {
if f == nil { if f == nil {
return nil, fmt.Errorf("malformed client for scheme %q, client is defined as nil", endpoint.Protocol) return nil, fmt.Errorf("malformed client for scheme %q, client is defined as nil", endpoint.Protocol)
} }
return f, nil return f, nil
} }

@ -58,6 +58,11 @@ type Session interface {
// If the repository does not exist, returns ErrRepositoryNotFound. // If the repository does not exist, returns ErrRepositoryNotFound.
// If the repository exists, but is empty, returns ErrEmptyRemoteRepository. // If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
AdvertisedReferences() (*packp.AdvRefs, error) AdvertisedReferences() (*packp.AdvRefs, error)
// AdvertisedReferencesContext retrieves the advertised references for a
// repository.
// If the repository does not exist, returns ErrRepositoryNotFound.
// If the repository exists, but is empty, returns ErrEmptyRemoteRepository.
AdvertisedReferencesContext(context.Context) (*packp.AdvRefs, error)
io.Closer io.Closer
} }
@ -107,6 +112,10 @@ type Endpoint struct {
Port int Port int
// Path is the repository path. // Path is the repository path.
Path string Path string
// InsecureSkipTLS skips ssl verify if protocal is https
InsecureSkipTLS bool
// CaBundle specify additional ca bundle with system cert pool
CaBundle []byte
} }
var defaultPorts = map[string]int{ var defaultPorts = map[string]int{

@ -3,6 +3,7 @@ package http
import ( import (
"bytes" "bytes"
"context"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@ -32,7 +33,7 @@ func applyHeadersToRequest(req *http.Request, content *bytes.Buffer, host string
const infoRefsPath = "/info/refs" const infoRefsPath = "/info/refs"
func advertisedReferences(s *session, serviceName string) (ref *packp.AdvRefs, err error) { func advertisedReferences(ctx context.Context, s *session, serviceName string) (ref *packp.AdvRefs, err error) {
url := fmt.Sprintf( url := fmt.Sprintf(
"%s%s?service=%s", "%s%s?service=%s",
s.endpoint.String(), infoRefsPath, serviceName, s.endpoint.String(), infoRefsPath, serviceName,
@ -45,7 +46,7 @@ func advertisedReferences(s *session, serviceName string) (ref *packp.AdvRefs, e
s.ApplyAuthToRequest(req) s.ApplyAuthToRequest(req)
applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName) applyHeadersToRequest(req, nil, s.endpoint.Host, serviceName)
res, err := s.client.Do(req) res, err := s.client.Do(req.WithContext(ctx))
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -25,7 +25,11 @@ func newReceivePackSession(c *http.Client, ep *transport.Endpoint, auth transpor
} }
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) { func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
return advertisedReferences(s.session, transport.ReceivePackServiceName) return advertisedReferences(context.TODO(), s.session, transport.ReceivePackServiceName)
}
func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
return advertisedReferences(ctx, s.session, transport.ReceivePackServiceName)
} }
func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) ( func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (

@ -25,7 +25,11 @@ func newUploadPackSession(c *http.Client, ep *transport.Endpoint, auth transport
} }
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) { func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
return advertisedReferences(s.session, transport.UploadPackServiceName) return advertisedReferences(context.TODO(), s.session, transport.UploadPackServiceName)
}
func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
return advertisedReferences(ctx, s.session, transport.UploadPackServiceName)
} }
func (s *upSession) UploadPack( func (s *upSession) UploadPack(

@ -162,14 +162,18 @@ func (c *client) listenFirstError(r io.Reader) chan string {
return errLine return errLine
} }
// AdvertisedReferences retrieves the advertised references from the server.
func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) { func (s *session) AdvertisedReferences() (*packp.AdvRefs, error) {
return s.AdvertisedReferencesContext(context.TODO())
}
// AdvertisedReferences retrieves the advertised references from the server.
func (s *session) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
if s.advRefs != nil { if s.advRefs != nil {
return s.advRefs, nil return s.advRefs, nil
} }
ar := packp.NewAdvRefs() ar := packp.NewAdvRefs()
if err := ar.Decode(s.Stdout); err != nil { if err := ar.Decode(s.StdoutContext(ctx)); err != nil {
if err := s.handleAdvRefDecodeError(err); err != nil { if err := s.handleAdvRefDecodeError(err); err != nil {
return nil, err return nil, err
} }
@ -237,7 +241,7 @@ func (s *session) UploadPack(ctx context.Context, req *packp.UploadPackRequest)
return nil, err return nil, err
} }
if _, err := s.AdvertisedReferences(); err != nil { if _, err := s.AdvertisedReferencesContext(ctx); err != nil {
return nil, err return nil, err
} }

@ -108,6 +108,10 @@ type upSession struct {
} }
func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) { func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) {
return s.AdvertisedReferencesContext(context.TODO())
}
func (s *upSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
ar := packp.NewAdvRefs() ar := packp.NewAdvRefs()
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil { if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {
@ -204,6 +208,10 @@ type rpSession struct {
} }
func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) { func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) {
return s.AdvertisedReferencesContext(context.TODO())
}
func (s *rpSession) AdvertisedReferencesContext(ctx context.Context) (*packp.AdvRefs, error) {
ar := packp.NewAdvRefs() ar := packp.NewAdvRefs()
if err := s.setSupportedCapabilities(ar.Capabilities); err != nil { if err := s.setSupportedCapabilities(ar.Capabilities); err != nil {

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"strconv" "strconv"
"strings"
"github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/internal/common" "github.com/go-git/go-git/v5/plumbing/transport/internal/common"
@ -90,8 +91,14 @@ func (c *command) Close() error {
//XXX: If did read the full packfile, then the session might be already //XXX: If did read the full packfile, then the session might be already
// closed. // closed.
_ = c.Session.Close() _ = c.Session.Close()
err := c.client.Close()
return c.client.Close() //XXX: in go1.16+ we can use errors.Is(err, net.ErrClosed)
if err != nil && strings.HasSuffix(err.Error(), "use of closed network connection") {
return nil
}
return err
} }
// connect connects to the SSH server, unless a AuthMethod was set with // connect connects to the SSH server, unless a AuthMethod was set with

@ -102,14 +102,14 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
return fmt.Errorf("remote names don't match: %s != %s", o.RemoteName, r.c.Name) return fmt.Errorf("remote names don't match: %s != %s", o.RemoteName, r.c.Name)
} }
s, err := newSendPackSession(r.c.URLs[0], o.Auth) s, err := newSendPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
if err != nil { if err != nil {
return err return err
} }
defer ioutil.CheckClose(s, &err) defer ioutil.CheckClose(s, &err)
ar, err := s.AdvertisedReferences() ar, err := s.AdvertisedReferencesContext(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -119,6 +119,10 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) (err error) {
return err return err
} }
if err := r.checkRequireRemoteRefs(o.RequireRemoteRefs, remoteRefs); err != nil {
return err
}
isDelete := false isDelete := false
allDelete := true allDelete := true
for _, rs := range o.RefSpecs { for _, rs := range o.RefSpecs {
@ -309,14 +313,14 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
o.RefSpecs = r.c.Fetch o.RefSpecs = r.c.Fetch
} }
s, err := newUploadPackSession(r.c.URLs[0], o.Auth) s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer ioutil.CheckClose(s, &err) defer ioutil.CheckClose(s, &err)
ar, err := s.AdvertisedReferences() ar, err := s.AdvertisedReferencesContext(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -369,8 +373,8 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (sto storer.Referen
return remoteRefs, nil return remoteRefs, nil
} }
func newUploadPackSession(url string, auth transport.AuthMethod) (transport.UploadPackSession, error) { func newUploadPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.UploadPackSession, error) {
c, ep, err := newClient(url) c, ep, err := newClient(url, auth, insecure, cabundle)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -378,8 +382,8 @@ func newUploadPackSession(url string, auth transport.AuthMethod) (transport.Uplo
return c.NewUploadPackSession(ep, auth) return c.NewUploadPackSession(ep, auth)
} }
func newSendPackSession(url string, auth transport.AuthMethod) (transport.ReceivePackSession, error) { func newSendPackSession(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.ReceivePackSession, error) {
c, ep, err := newClient(url) c, ep, err := newClient(url, auth, insecure, cabundle)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -387,11 +391,13 @@ func newSendPackSession(url string, auth transport.AuthMethod) (transport.Receiv
return c.NewReceivePackSession(ep, auth) return c.NewReceivePackSession(ep, auth)
} }
func newClient(url string) (transport.Transport, *transport.Endpoint, error) { func newClient(url string, auth transport.AuthMethod, insecure bool, cabundle []byte) (transport.Transport, *transport.Endpoint, error) {
ep, err := transport.NewEndpoint(url) ep, err := transport.NewEndpoint(url)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
ep.InsecureSkipTLS = insecure
ep.CaBundle = cabundle
c, err := client.NewClient(ep) c, err := client.NewClient(ep)
if err != nil { if err != nil {
@ -1025,14 +1031,14 @@ func (r *Remote) buildFetchedTags(refs memory.ReferenceStorage) (updated bool, e
// List the references on the remote repository. // List the references on the remote repository.
func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) { func (r *Remote) List(o *ListOptions) (rfs []*plumbing.Reference, err error) {
s, err := newUploadPackSession(r.c.URLs[0], o.Auth) s, err := newUploadPackSession(r.c.URLs[0], o.Auth, o.InsecureSkipTLS, o.CABundle)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer ioutil.CheckClose(s, &err) defer ioutil.CheckClose(s, &err)
ar, err := s.AdvertisedReferences() ar, err := s.AdvertisedReferencesContext(context.TODO())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1164,3 +1170,33 @@ outer:
return r.s.SetShallow(shallows) return r.s.SetShallow(shallows)
} }
func (r *Remote) checkRequireRemoteRefs(requires []config.RefSpec, remoteRefs storer.ReferenceStorer) error {
for _, require := range requires {
if require.IsWildcard() {
return fmt.Errorf("wildcards not supported in RequireRemoteRefs, got %s", require.String())
}
name := require.Dst("")
remote, err := remoteRefs.Reference(name)
if err != nil {
return fmt.Errorf("remote ref %s required to be %s but is absent", name.String(), require.Src())
}
var requireHash string
if require.IsExactSHA1() {
requireHash = require.Src()
} else {
target, err := storer.ResolveReference(remoteRefs, plumbing.ReferenceName(require.Src()))
if err != nil {
return fmt.Errorf("could not resolve ref %s in RequireRemoteRefs", require.Src())
}
requireHash = target.Hash().String()
}
if remote.Hash().String() != requireHash {
return fmt.Errorf("remote ref %s required to be %s but is %s", name.String(), requireHash, remote.Hash().String())
}
}
return nil
}

@ -841,12 +841,14 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
} }
ref, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{ ref, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{
RefSpecs: c.Fetch, RefSpecs: c.Fetch,
Depth: o.Depth, Depth: o.Depth,
Auth: o.Auth, Auth: o.Auth,
Progress: o.Progress, Progress: o.Progress,
Tags: o.Tags, Tags: o.Tags,
RemoteName: o.RemoteName, RemoteName: o.RemoteName,
InsecureSkipTLS: o.InsecureSkipTLS,
CABundle: o.CABundle,
}, o.ReferenceName) }, o.ReferenceName)
if err != nil { if err != nil {
return err return err

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

Loading…
Cancel
Save