Repository: lestrrat-go/jwx
Pull request #679 (2022-04-08 02:24:18)

Update golangci lint

codecov-commenter: # [Codecov](https://codecov.io/gh/lestrrat-go/jwx/pull/679?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lestrrat-go) Report
> :exclamation: No coverage uploaded for pull request base (`develop/v2@8da38b0`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lestrrat-go#section-missing-base-commit).
> The diff coverage is `n/a`.

```diff
@@              Coverage Diff              @@
##             develop/v2     #679   +/-   ##
=============================================
  Coverage              ?   71.88%           
=============================================
  Files                 ?       90           
  Lines                 ?     9675           
  Branches              ?        0           
=============================================
  Hits                  ?     6955           
  Misses                ?     1923           
  Partials              ?      797           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/lestrrat-go/jwx/pull/679?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lestrrat-go).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lestrrat-go)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/lestrrat-go/jwx/pull/679?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lestrrat-go). Last update [8da38b0...655732a](https://codecov.io/gh/lestrrat-go/jwx/pull/679?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lestrrat-go). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lestrrat-go).


Patch:
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index d928ef42..226e337f 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -8,7 +8,7 @@ jobs:
       - uses: actions/checkout@v2
       - uses: golangci/golangci-lint-action@v2
         with:
-          version: v1.41.1
+          version: v1.45.2
       - name: Run go vet
         run: |
           go vet ./...
diff --git a/.golangci.yml b/.golangci.yml
index b5afb667..33508e1e 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -32,7 +32,9 @@ linters:
     - govet
     - interfacer # deprecated
     - ifshort
+    - ireturn # No, I _LIKE_ returning interfaces
     - lll
+    - maintidx # Do this in code review
     - maligned # deprecated
     - makezero
     - nakedret
@@ -42,7 +44,8 @@ linters:
     - scopelint # deprecated
     - tagliatelle
     - testpackage
-    - thelper
+    - thelper    # Tests are fine
+    - varnamelen # Short names are ok
     - wrapcheck
     - wsl
 
@@ -63,9 +66,15 @@ issues:
     - path: internal/codegen/codegen.go
       linters:
         - errcheck
+    - path: internal/jwxtest/jwxtest.go
+      linters:
+        - errcheck
+        - errchkjson
+        - forcetypeassert
     - path: /*_test.go
       linters:
         - errcheck
+        - errchkjson
         - forcetypeassert
     - path: /*_example_test.go
       linters:
diff --git a/internal/ecutil/ecutil.go b/internal/ecutil/ecutil.go
index c3fa4359..e70f8165 100644
--- a/internal/ecutil/ecutil.go
+++ b/internal/ecutil/ecutil.go
@@ -61,6 +61,7 @@ var ecpointBufferPool = sync.Pool{
 }
 
 func getCrvFixedBuffer(size int) []byte {
+	//nolint:forcetypeassert
 	buf := *(ecpointBufferPool.Get().(*[]byte))
 	if size > ec521BufferSize && cap(buf) < size {
 		buf = append(buf, make([]byte, size-cap(buf))...)
diff --git a/internal/iter/mapiter.go b/internal/iter/mapiter.go
index 609c5231..c98fd46c 100644
--- a/internal/iter/mapiter.go
+++ b/internal/iter/mapiter.go
@@ -22,6 +22,7 @@ func (fn MapVisitorFunc) Visit(s string, v interface{}) error {
 
 func WalkMap(ctx context.Context, src mapiter.Source, visitor MapVisitor) error {
 	return mapiter.Walk(ctx, src, mapiter.VisitorFunc(func(k, v interface{}) error {
+		//nolint:forcetypeassert
 		return visitor.Visit(k.(string), v)
 	}))
 }
diff --git a/internal/json/json.go b/internal/json/json.go
index 466f8e79..e8d6a2d1 100644
--- a/internal/json/json.go
+++ b/internal/json/json.go
@@ -108,5 +108,6 @@ func (dc *decodeCtx) Registry() *Registry {
 func Dump(v interface{}) {
 	enc := NewEncoder(os.Stdout)
 	enc.SetIndent("", "  ")
+	//nolint:errchkjson
 	_ = enc.Encode(v)
 }
diff --git a/internal/pool/pool.go b/internal/pool/pool.go
index 09a4af8b..fae560b7 100644
--- a/internal/pool/pool.go
+++ b/internal/pool/pool.go
@@ -15,6 +15,7 @@ func allocBytesBuffer() interface{} {
 }
 
 func GetBytesBuffer() *bytes.Buffer {
+	//nolint:forcetypeassert
 	return bytesBufferPool.Get().(*bytes.Buffer)
 }
 
@@ -32,6 +33,7 @@ func allocBigInt() interface{} {
 }
 
 func GetBigInt() *big.Int {
+	//nolint:forcetypeassert
 	return bigIntPool.Get().(*big.Int)
 }
 
@@ -48,6 +50,7 @@ func allocKeyToErrorMap() interface{} {
 }
 
 func GetKeyToErrorMap() map[string]error {
+	//nolint:forcetypeassert
 	return keyToErrorMapPool.Get().(map[string]error)
 }
 
diff --git a/jwe/headers.go b/jwe/headers.go
index 3a327301..11455911 100644
--- a/jwe/headers.go
+++ b/jwe/headers.go
@@ -71,8 +71,10 @@ func (h *stdHeaders) Clone(ctx context.Context) (Headers, error) {
 
 func (h *stdHeaders) Copy(ctx context.Context, dst Headers) error {
 	for _, pair := range h.makePairs() {
-		if err := dst.Set(pair.Key.(string), pair.Value); err != nil {
-			return fmt.Errorf(`failed to set header: %w`, err)
+		//nolint:forcetypeassert
+		key := pair.Key.(string)
+		if err := dst.Set(key, pair.Value); err != nil {
+			return fmt.Errorf(`failed to set header %q: %w`, key, err)
 		}
 	}
 	return nil
diff --git a/jwe/internal/cipher/cipher.go b/jwe/internal/cipher/cipher.go
index f0fe240e..23f437e8 100644
--- a/jwe/internal/cipher/cipher.go
+++ b/jwe/internal/cipher/cipher.go
@@ -95,10 +95,8 @@ func (c AesContentCipher) Encrypt(cek, plaintext, aad []byte) (iv, ciphertxt, ta
 			switch e := e.(type) {
 			case error:
 				err = e
-			case string:
-				err = fmt.Errorf("%s", e)
 			default:
-				err = fmt.Errorf("%w", e)
+				err = fmt.Errorf("%s", e)
 			}
 			err = fmt.Errorf(`failed to encrypt: %w`, err)
 		}
@@ -141,10 +139,8 @@ func (c AesContentCipher) Decrypt(cek, iv, ciphertxt, tag, aad []byte) (plaintex
 			switch e := e.(type) {
 			case error:
 				err = e
-			case string:
-				err = fmt.Errorf(`%s`, e)
 			default:
-				err = fmt.Errorf("%w", e)
+				err = fmt.Errorf(`%s`, e)
 			}
 			err = fmt.Errorf(`failed to decrypt: %w`, err)
 			return
diff --git a/jwe/message.go b/jwe/message.go
index 079b127b..0088082d 100644
--- a/jwe/message.go
+++ b/jwe/message.go
@@ -438,8 +438,10 @@ func (m *Message) UnmarshalJSON(buf []byte) error {
 		m.rawProtectedHeaders = base64.Encode(protectedHeadersRaw)
 	}
 
-	if !proxy.UnprotectedHeaders.(isZeroer).isZero() {
-		m.unprotectedHeaders = proxy.UnprotectedHeaders
+	if iz, ok := proxy.UnprotectedHeaders.(isZeroer); ok {
+		if !iz.isZero() {
+			m.unprotectedHeaders = proxy.UnprotectedHeaders
+		}
 	}
 
 	if len(m.recipients) == 0 {
diff --git a/jwk/cache.go b/jwk/cache.go
index 74268c36..c7cf1b74 100644
--- a/jwk/cache.go
+++ b/jwk/cache.go
@@ -90,6 +90,7 @@ func (t *jwksTransform) Transform(u string, res *http.Response) (interface{}, er
 func NewCache(ctx context.Context, options ...CacheOption) *Cache {
 	var hrcopts []httprc.CacheOption
 	for _, option := range options {
+		//nolint:forcetypeassert
 		switch option.Ident() {
 		case identRefreshWindow{}:
 			hrcopts = append(hrcopts, httprc.WithRefreshWindow(option.Value().(time.Duration)))
diff --git a/jwk/ecdsa.go b/jwk/ecdsa.go
index 26bd02b9..67a14ba6 100644
--- a/jwk/ecdsa.go
+++ b/jwk/ecdsa.go
@@ -148,8 +148,10 @@ func makeECDSAPublicKey(v interface {
 		case ECDSADKey:
 			continue
 		default:
-			if err := newKey.Set(pair.Key.(string), pair.Value); err != nil {
-				return nil, fmt.Errorf(`failed to set field %s: %w`, pair.Key, err)
+			//nolint:forcetypeassert
+			key := pair.Key.(string)
+			if err := newKey.Set(key, pair.Value); err != nil {
+				return nil, fmt.Errorf(`failed to set field %q: %w`, key, err)
 			}
 		}
 	}
diff --git a/jwk/fetch.go b/jwk/fetch.go
index 6994e171..daca1773 100644
--- a/jwk/fetch.go
+++ b/jwk/fetch.go
@@ -52,6 +52,7 @@ func Fetch(ctx context.Context, u string, options ...FetchOption) (Set, error) {
 			continue
 		}
 
+		//nolint:forcetypeassert
 		switch option.Ident() {
 		case identHTTPClient{}:
 			hrfopts = append(hrfopts, httprc.WithHTTPClient(option.Value().(HTTPClient)))
diff --git a/jwk/jwk.go b/jwk/jwk.go
index 035b5199..d53dc458 100644
--- a/jwk/jwk.go
+++ b/jwk/jwk.go
@@ -619,8 +619,10 @@ func cloneKey(src Key) (Key, error) {
 	}
 
 	for _, pair := range src.makePairs() {
-		if err := dst.Set(pair.Key.(string), pair.Value); err != nil {
-			return nil, fmt.Errorf(`failed to set %s: %w`, pair.Key.(string), err)
+		//nolint:forcetypeassert
+		key := pair.Key.(string)
+		if err := dst.Set(key, pair.Value); err != nil {
+			return nil, fmt.Errorf(`failed to set %q: %w`, key, err)
 		}
 	}
 	return dst, nil
diff --git a/jwk/okp.go b/jwk/okp.go
index f69910f2..2686ba51 100644
--- a/jwk/okp.go
+++ b/jwk/okp.go
@@ -84,6 +84,7 @@ func buildOKPPrivateKey(alg jwa.EllipticCurveAlgorithm, xbuf []byte, dbuf []byte
 	switch alg {
 	case jwa.Ed25519:
 		ret := ed25519.NewKeyFromSeed(dbuf)
+		//nolint:forcetypeassert
 		if !bytes.Equal(xbuf, ret.Public().(ed25519.PublicKey)) {
 			return nil, fmt.Errorf(`invalid x value given d value`)
 		}
@@ -93,6 +94,7 @@ func buildOKPPrivateKey(alg jwa.EllipticCurveAlgorithm, xbuf []byte, dbuf []byte
 		if err != nil {
 			return nil, fmt.Errorf(`unable to construct x25519 private key from seed: %w`, err)
 		}
+		//nolint:forcetypeassert
 		if !bytes.Equal(xbuf, ret.Public().(x25519.PublicKey)) {
 			return nil, fmt.Errorf(`invalid x value given d value`)
 		}
@@ -125,8 +127,10 @@ func makeOKPPublicKey(v interface {
 		case OKPDKey:
 			continue
 		default:
-			if err := newKey.Set(pair.Key.(string), pair.Value); err != nil {
-				return nil, fmt.Errorf(`failed to set field %s: %w`, pair.Key, err)
+			//nolint:forcetypeassert
+			key := pair.Key.(string)
+			if err := newKey.Set(key, pair.Value); err != nil {
+				return nil, fmt.Errorf(`failed to set field %q: %w`, key, err)
 			}
 		}
 	}
diff --git a/jwk/rsa.go b/jwk/rsa.go
index 4215a776..5de6b635 100644
--- a/jwk/rsa.go
+++ b/jwk/rsa.go
@@ -182,8 +182,10 @@ func makeRSAPublicKey(v interface {
 		case RSADKey, RSADPKey, RSADQKey, RSAPKey, RSAQKey, RSAQIKey:
 			continue
 		default:
-			if err := newKey.Set(pair.Key.(string), pair.Value); err != nil {
-				return nil, fmt.Errorf(`failed to set field %s: %w`, pair.Key, err)
+			//nolint:forcetypeassert
+			key := pair.Key.(string)
+			if err := newKey.Set(key, pair.Value); err != nil {
+				return nil, fmt.Errorf(`failed to set field %q: %w`, key, err)
 			}
 		}
 	}
diff --git a/jwk/symmetric.go b/jwk/symmetric.go
index f47161e4..d2498e33 100644
--- a/jwk/symmetric.go
+++ b/jwk/symmetric.go
@@ -50,8 +50,10 @@ func (k *symmetricKey) PublicKey() (Key, error) {
 	newKey := newSymmetricKey()
 
 	for _, pair := range k.makePairs() {
-		if err := newKey.Set(pair.Key.(string), pair.Value); err != nil {
-			return nil, fmt.Errorf(`failed to set field %s: %w`, pair.Key, err)
+		//nolint:forcetypeassert
+		key := pair.Key.(string)
+		if err := newKey.Set(key, pair.Value); err != nil {
+			return nil, fmt.Errorf(`failed to set field %q: %w`, key, err)
 		}
 	}
 	return newKey, nil
diff --git a/jws/headers.go b/jws/headers.go
index eb3488b3..dce72895 100644
--- a/jws/headers.go
+++ b/jws/headers.go
@@ -36,8 +36,10 @@ func (h *stdHeaders) AsMap(ctx context.Context) (map[string]interface{}, error)
 
 func (h *stdHeaders) Copy(ctx context.Context, dst Headers) error {
 	for _, pair := range h.makePairs() {
-		if err := dst.Set(pair.Key.(string), pair.Value); err != nil {
-			return fmt.Errorf(`failed to set header: %w`, err)
+		//nolint:forcetypeassert
+		key := pair.Key.(string)
+		if err := dst.Set(key, pair.Value); err != nil {
+			return fmt.Errorf(`failed to set header %q: %w`, key, err)
 		}
 	}
 	return nil
diff --git a/jws/message.go b/jws/message.go
index 1f7a7d4d..e0284223 100644
--- a/jws/message.go
+++ b/jws/message.go
@@ -75,10 +75,12 @@ func (s *Signature) UnmarshalJSON(data []byte) error {
 		}
 
 		prt := NewHeaders()
+		//nolint:forcetypeassert
 		prt.(*stdHeaders).SetDecodeCtx(s.DecodeCtx())
 		if err := json.Unmarshal(src, prt); err != nil {
 			return fmt.Errorf(`failed to unmarshal protected headers: %w`, err)
 		}
+		//nolint:forcetypeassert
 		prt.(*stdHeaders).SetDecodeCtx(nil)
 		s.protected = prt
 	}
@@ -299,10 +301,12 @@ func (m *Message) UnmarshalJSON(buf []byte) error {
 				return fmt.Errorf(`failed to base64 decode flattened protected headers: %w`, err)
 			}
 			prt := NewHeaders()
+			//nolint:forcetypeassert
 			prt.(*stdHeaders).SetDecodeCtx(m.DecodeCtx())
 			if err := json.Unmarshal(decoded, prt); err != nil {
 				return fmt.Errorf(`failed to unmarshal flattened protected headers: %w`, err)
 			}
+			//nolint:forcetypeassert
 			prt.(*stdHeaders).SetDecodeCtx(nil)
 			sig.protected = prt
 		}
diff --git a/jwt/http.go b/jwt/http.go
index 8ec4a840..08b73bca 100644
--- a/jwt/http.go
+++ b/jwt/http.go
@@ -63,6 +63,7 @@ func ParseRequest(req *http.Request, options ...ParseOption) (Token, error) {
 	var formkeys []string
 	var parseOptions []ParseOption
 	for _, option := range options {
+		//nolint:forcetypeassert
 		switch option.Ident() {
 		case identHeaderKey{}:
 			hdrkeys = append(hdrkeys, option.Value().(string))
diff --git a/jwt/jwt.go b/jwt/jwt.go
index c97e2f12..c859d4e9 100644
--- a/jwt/jwt.go
+++ b/jwt/jwt.go
@@ -382,8 +382,10 @@ func (t *stdToken) Clone() (Token, error) {
 	dst := New()
 
 	for _, pair := range t.makePairs() {
-		if err := dst.Set(pair.Key.(string), pair.Value); err != nil {
-			return nil, fmt.Errorf(`failed to set %s: %w`, pair.Key.(string), err)
+		//nolint:forcetypeassert
+		key := pair.Key.(string)
+		if err := dst.Set(key, pair.Value); err != nil {
+			return nil, fmt.Errorf(`failed to set %s: %w`, key, err)
 		}
 	}
 	return dst, nil
diff --git a/jwt/openid/openid.go b/jwt/openid/openid.go
index a8723278..414507aa 100644
--- a/jwt/openid/openid.go
+++ b/jwt/openid/openid.go
@@ -20,8 +20,10 @@ func (t *stdToken) Clone() (jwt.Token, error) {
 	var dst jwt.Token = New()
 
 	for _, pair := range t.makePairs() {
-		if err := dst.Set(pair.Key.(string), pair.Value); err != nil {
-			return nil, fmt.Errorf(`failed to set %s: %w`, pair.Key.(string), err)
+		//nolint:forcetypeassert
+		key := pair.Key.(string)
+		if err := dst.Set(key, pair.Value); err != nil {
+			return nil, fmt.Errorf(`failed to set %s: %w`, key, err)
 		}
 	}
 	return dst, nil
diff --git a/jwt/validate.go b/jwt/validate.go
index b9271804..750b165c 100644
--- a/jwt/validate.go
+++ b/jwt/validate.go
@@ -203,6 +203,7 @@ func SetValidationCtxClock(ctx context.Context, cl Clock) context.Context {
 // the current validation context. This value will always be available
 // during validation of tokens.
 func ValidationCtxClock(ctx context.Context) Clock {
+	//nolint:forcetypeassert
 	return ctx.Value(identValidationCtxClock{}).(Clock)
 }
 
@@ -211,6 +212,7 @@ func SetValidationCtxSkew(ctx context.Context, dur time.Duration) context.Contex
 }
 
 func ValidationCtxSkew(ctx context.Context) time.Duration {
+	//nolint:forcetypeassert
 	return ctx.Value(identValidationCtxSkew{}).(time.Duration)
 }
 


Test patch:
diff --git a/internal/jwxtest/jwxtest.go b/internal/jwxtest/jwxtest.go
index c66e75dc..76594f41 100644
--- a/internal/jwxtest/jwxtest.go
+++ b/internal/jwxtest/jwxtest.go
@@ -88,7 +88,6 @@ func GenerateEcdsaPublicJwk() (jwk.Key, error) {
 
 func GenerateSymmetricKey() []byte {
 	sharedKey := make([]byte, 64)
-	//nolint:errcheck
 	rand.Read(sharedKey)
 	return sharedKey
 }