= len(out) {
- break
- }
- out[off] |= bb
- }
- }
-
- return out[:]
-}
-
-// Equal returns 1 if v and u are equal, and 0 otherwise.
-func (v *Element) Equal(u *Element) int {
- sa, sv := u.Bytes(), v.Bytes()
- return subtle.ConstantTimeCompare(sa, sv)
-}
-
-// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
-func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
-
-// Select sets v to a if cond == 1, and to b if cond == 0.
-func (v *Element) Select(a, b *Element, cond int) *Element {
- m := mask64Bits(cond)
- v.l0 = (m & a.l0) | (^m & b.l0)
- v.l1 = (m & a.l1) | (^m & b.l1)
- v.l2 = (m & a.l2) | (^m & b.l2)
- v.l3 = (m & a.l3) | (^m & b.l3)
- v.l4 = (m & a.l4) | (^m & b.l4)
- return v
-}
-
-// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
-func (v *Element) Swap(u *Element, cond int) {
- m := mask64Bits(cond)
- t := m & (v.l0 ^ u.l0)
- v.l0 ^= t
- u.l0 ^= t
- t = m & (v.l1 ^ u.l1)
- v.l1 ^= t
- u.l1 ^= t
- t = m & (v.l2 ^ u.l2)
- v.l2 ^= t
- u.l2 ^= t
- t = m & (v.l3 ^ u.l3)
- v.l3 ^= t
- u.l3 ^= t
- t = m & (v.l4 ^ u.l4)
- v.l4 ^= t
- u.l4 ^= t
-}
-
-// IsNegative returns 1 if v is negative, and 0 otherwise.
-func (v *Element) IsNegative() int {
- return int(v.Bytes()[0] & 1)
-}
-
-// Absolute sets v to |u|, and returns v.
-func (v *Element) Absolute(u *Element) *Element {
- return v.Select(new(Element).Negate(u), u, u.IsNegative())
-}
-
-// Multiply sets v = x * y, and returns v.
-func (v *Element) Multiply(x, y *Element) *Element {
- feMul(v, x, y)
- return v
-}
-
-// Square sets v = x * x, and returns v.
-func (v *Element) Square(x *Element) *Element {
- feSquare(v, x)
- return v
-}
-
-// Mult32 sets v = x * y, and returns v.
-func (v *Element) Mult32(x *Element, y uint32) *Element {
- x0lo, x0hi := mul51(x.l0, y)
- x1lo, x1hi := mul51(x.l1, y)
- x2lo, x2hi := mul51(x.l2, y)
- x3lo, x3hi := mul51(x.l3, y)
- x4lo, x4hi := mul51(x.l4, y)
- v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
- v.l1 = x1lo + x0hi
- v.l2 = x2lo + x1hi
- v.l3 = x3lo + x2hi
- v.l4 = x4lo + x3hi
- // The hi portions are going to be only 32 bits, plus any previous excess,
- // so we can skip the carry propagation.
- return v
-}
-
-// mul51 returns lo + hi * 2⁵¹ = a * b.
-func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
- mh, ml := bits.Mul64(a, uint64(b))
- lo = ml & maskLow51Bits
- hi = (mh << 13) | (ml >> 51)
- return
-}
-
-// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
-func (v *Element) Pow22523(x *Element) *Element {
- var t0, t1, t2 Element
-
- t0.Square(x) // x^2
- t1.Square(&t0) // x^4
- t1.Square(&t1) // x^8
- t1.Multiply(x, &t1) // x^9
- t0.Multiply(&t0, &t1) // x^11
- t0.Square(&t0) // x^22
- t0.Multiply(&t1, &t0) // x^31
- t1.Square(&t0) // x^62
- for i := 1; i < 5; i++ { // x^992
- t1.Square(&t1)
- }
- t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1
- t1.Square(&t0) // 2^11 - 2
- for i := 1; i < 10; i++ { // 2^20 - 2^10
- t1.Square(&t1)
- }
- t1.Multiply(&t1, &t0) // 2^20 - 1
- t2.Square(&t1) // 2^21 - 2
- for i := 1; i < 20; i++ { // 2^40 - 2^20
- t2.Square(&t2)
- }
- t1.Multiply(&t2, &t1) // 2^40 - 1
- t1.Square(&t1) // 2^41 - 2
- for i := 1; i < 10; i++ { // 2^50 - 2^10
- t1.Square(&t1)
- }
- t0.Multiply(&t1, &t0) // 2^50 - 1
- t1.Square(&t0) // 2^51 - 2
- for i := 1; i < 50; i++ { // 2^100 - 2^50
- t1.Square(&t1)
- }
- t1.Multiply(&t1, &t0) // 2^100 - 1
- t2.Square(&t1) // 2^101 - 2
- for i := 1; i < 100; i++ { // 2^200 - 2^100
- t2.Square(&t2)
- }
- t1.Multiply(&t2, &t1) // 2^200 - 1
- t1.Square(&t1) // 2^201 - 2
- for i := 1; i < 50; i++ { // 2^250 - 2^50
- t1.Square(&t1)
- }
- t0.Multiply(&t1, &t0) // 2^250 - 1
- t0.Square(&t0) // 2^251 - 2
- t0.Square(&t0) // 2^252 - 4
- return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
-}
-
-// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
-var sqrtM1 = &Element{1718705420411056, 234908883556509,
- 2233514472574048, 2117202627021982, 765476049583133}
-
-// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
-//
-// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
-// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
-// and returns r and 0.
-func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
- var a, b Element
-
- // r = (u * v3) * (u * v7)^((p-5)/8)
- v2 := a.Square(v)
- uv3 := b.Multiply(u, b.Multiply(v2, v))
- uv7 := a.Multiply(uv3, a.Square(v2))
- r.Multiply(uv3, r.Pow22523(uv7))
-
- check := a.Multiply(v, a.Square(r)) // check = v * r^2
-
- uNeg := b.Negate(u)
- correctSignSqrt := check.Equal(u)
- flippedSignSqrt := check.Equal(uNeg)
- flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
-
- rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
- // r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
- r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
-
- r.Absolute(r) // Choose the nonnegative square root.
- return r, correctSignSqrt | flippedSignSqrt
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
deleted file mode 100644
index 70c541692c3..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-
-package field
-
-// feMul sets out = a * b. It works like feMulGeneric.
-//
-//go:noescape
-func feMul(out *Element, a *Element, b *Element)
-
-// feSquare sets out = a * a. It works like feSquareGeneric.
-//
-//go:noescape
-func feSquare(out *Element, a *Element)
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
deleted file mode 100644
index 60817acc413..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
+++ /dev/null
@@ -1,378 +0,0 @@
-// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-
-#include "textflag.h"
-
-// func feMul(out *Element, a *Element, b *Element)
-TEXT ·feMul(SB), NOSPLIT, $0-24
- MOVQ a+8(FP), CX
- MOVQ b+16(FP), BX
-
- // r0 = a0×b0
- MOVQ (CX), AX
- MULQ (BX)
- MOVQ AX, DI
- MOVQ DX, SI
-
- // r0 += 19×a1×b4
- MOVQ 8(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 32(BX)
- ADDQ AX, DI
- ADCQ DX, SI
-
- // r0 += 19×a2×b3
- MOVQ 16(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 24(BX)
- ADDQ AX, DI
- ADCQ DX, SI
-
- // r0 += 19×a3×b2
- MOVQ 24(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 16(BX)
- ADDQ AX, DI
- ADCQ DX, SI
-
- // r0 += 19×a4×b1
- MOVQ 32(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 8(BX)
- ADDQ AX, DI
- ADCQ DX, SI
-
- // r1 = a0×b1
- MOVQ (CX), AX
- MULQ 8(BX)
- MOVQ AX, R9
- MOVQ DX, R8
-
- // r1 += a1×b0
- MOVQ 8(CX), AX
- MULQ (BX)
- ADDQ AX, R9
- ADCQ DX, R8
-
- // r1 += 19×a2×b4
- MOVQ 16(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 32(BX)
- ADDQ AX, R9
- ADCQ DX, R8
-
- // r1 += 19×a3×b3
- MOVQ 24(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 24(BX)
- ADDQ AX, R9
- ADCQ DX, R8
-
- // r1 += 19×a4×b2
- MOVQ 32(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 16(BX)
- ADDQ AX, R9
- ADCQ DX, R8
-
- // r2 = a0×b2
- MOVQ (CX), AX
- MULQ 16(BX)
- MOVQ AX, R11
- MOVQ DX, R10
-
- // r2 += a1×b1
- MOVQ 8(CX), AX
- MULQ 8(BX)
- ADDQ AX, R11
- ADCQ DX, R10
-
- // r2 += a2×b0
- MOVQ 16(CX), AX
- MULQ (BX)
- ADDQ AX, R11
- ADCQ DX, R10
-
- // r2 += 19×a3×b4
- MOVQ 24(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 32(BX)
- ADDQ AX, R11
- ADCQ DX, R10
-
- // r2 += 19×a4×b3
- MOVQ 32(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 24(BX)
- ADDQ AX, R11
- ADCQ DX, R10
-
- // r3 = a0×b3
- MOVQ (CX), AX
- MULQ 24(BX)
- MOVQ AX, R13
- MOVQ DX, R12
-
- // r3 += a1×b2
- MOVQ 8(CX), AX
- MULQ 16(BX)
- ADDQ AX, R13
- ADCQ DX, R12
-
- // r3 += a2×b1
- MOVQ 16(CX), AX
- MULQ 8(BX)
- ADDQ AX, R13
- ADCQ DX, R12
-
- // r3 += a3×b0
- MOVQ 24(CX), AX
- MULQ (BX)
- ADDQ AX, R13
- ADCQ DX, R12
-
- // r3 += 19×a4×b4
- MOVQ 32(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 32(BX)
- ADDQ AX, R13
- ADCQ DX, R12
-
- // r4 = a0×b4
- MOVQ (CX), AX
- MULQ 32(BX)
- MOVQ AX, R15
- MOVQ DX, R14
-
- // r4 += a1×b3
- MOVQ 8(CX), AX
- MULQ 24(BX)
- ADDQ AX, R15
- ADCQ DX, R14
-
- // r4 += a2×b2
- MOVQ 16(CX), AX
- MULQ 16(BX)
- ADDQ AX, R15
- ADCQ DX, R14
-
- // r4 += a3×b1
- MOVQ 24(CX), AX
- MULQ 8(BX)
- ADDQ AX, R15
- ADCQ DX, R14
-
- // r4 += a4×b0
- MOVQ 32(CX), AX
- MULQ (BX)
- ADDQ AX, R15
- ADCQ DX, R14
-
- // First reduction chain
- MOVQ $0x0007ffffffffffff, AX
- SHLQ $0x0d, DI, SI
- SHLQ $0x0d, R9, R8
- SHLQ $0x0d, R11, R10
- SHLQ $0x0d, R13, R12
- SHLQ $0x0d, R15, R14
- ANDQ AX, DI
- IMUL3Q $0x13, R14, R14
- ADDQ R14, DI
- ANDQ AX, R9
- ADDQ SI, R9
- ANDQ AX, R11
- ADDQ R8, R11
- ANDQ AX, R13
- ADDQ R10, R13
- ANDQ AX, R15
- ADDQ R12, R15
-
- // Second reduction chain (carryPropagate)
- MOVQ DI, SI
- SHRQ $0x33, SI
- MOVQ R9, R8
- SHRQ $0x33, R8
- MOVQ R11, R10
- SHRQ $0x33, R10
- MOVQ R13, R12
- SHRQ $0x33, R12
- MOVQ R15, R14
- SHRQ $0x33, R14
- ANDQ AX, DI
- IMUL3Q $0x13, R14, R14
- ADDQ R14, DI
- ANDQ AX, R9
- ADDQ SI, R9
- ANDQ AX, R11
- ADDQ R8, R11
- ANDQ AX, R13
- ADDQ R10, R13
- ANDQ AX, R15
- ADDQ R12, R15
-
- // Store output
- MOVQ out+0(FP), AX
- MOVQ DI, (AX)
- MOVQ R9, 8(AX)
- MOVQ R11, 16(AX)
- MOVQ R13, 24(AX)
- MOVQ R15, 32(AX)
- RET
-
-// func feSquare(out *Element, a *Element)
-TEXT ·feSquare(SB), NOSPLIT, $0-16
- MOVQ a+8(FP), CX
-
- // r0 = l0×l0
- MOVQ (CX), AX
- MULQ (CX)
- MOVQ AX, SI
- MOVQ DX, BX
-
- // r0 += 38×l1×l4
- MOVQ 8(CX), AX
- IMUL3Q $0x26, AX, AX
- MULQ 32(CX)
- ADDQ AX, SI
- ADCQ DX, BX
-
- // r0 += 38×l2×l3
- MOVQ 16(CX), AX
- IMUL3Q $0x26, AX, AX
- MULQ 24(CX)
- ADDQ AX, SI
- ADCQ DX, BX
-
- // r1 = 2×l0×l1
- MOVQ (CX), AX
- SHLQ $0x01, AX
- MULQ 8(CX)
- MOVQ AX, R8
- MOVQ DX, DI
-
- // r1 += 38×l2×l4
- MOVQ 16(CX), AX
- IMUL3Q $0x26, AX, AX
- MULQ 32(CX)
- ADDQ AX, R8
- ADCQ DX, DI
-
- // r1 += 19×l3×l3
- MOVQ 24(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 24(CX)
- ADDQ AX, R8
- ADCQ DX, DI
-
- // r2 = 2×l0×l2
- MOVQ (CX), AX
- SHLQ $0x01, AX
- MULQ 16(CX)
- MOVQ AX, R10
- MOVQ DX, R9
-
- // r2 += l1×l1
- MOVQ 8(CX), AX
- MULQ 8(CX)
- ADDQ AX, R10
- ADCQ DX, R9
-
- // r2 += 38×l3×l4
- MOVQ 24(CX), AX
- IMUL3Q $0x26, AX, AX
- MULQ 32(CX)
- ADDQ AX, R10
- ADCQ DX, R9
-
- // r3 = 2×l0×l3
- MOVQ (CX), AX
- SHLQ $0x01, AX
- MULQ 24(CX)
- MOVQ AX, R12
- MOVQ DX, R11
-
- // r3 += 2×l1×l2
- MOVQ 8(CX), AX
- IMUL3Q $0x02, AX, AX
- MULQ 16(CX)
- ADDQ AX, R12
- ADCQ DX, R11
-
- // r3 += 19×l4×l4
- MOVQ 32(CX), AX
- IMUL3Q $0x13, AX, AX
- MULQ 32(CX)
- ADDQ AX, R12
- ADCQ DX, R11
-
- // r4 = 2×l0×l4
- MOVQ (CX), AX
- SHLQ $0x01, AX
- MULQ 32(CX)
- MOVQ AX, R14
- MOVQ DX, R13
-
- // r4 += 2×l1×l3
- MOVQ 8(CX), AX
- IMUL3Q $0x02, AX, AX
- MULQ 24(CX)
- ADDQ AX, R14
- ADCQ DX, R13
-
- // r4 += l2×l2
- MOVQ 16(CX), AX
- MULQ 16(CX)
- ADDQ AX, R14
- ADCQ DX, R13
-
- // First reduction chain
- MOVQ $0x0007ffffffffffff, AX
- SHLQ $0x0d, SI, BX
- SHLQ $0x0d, R8, DI
- SHLQ $0x0d, R10, R9
- SHLQ $0x0d, R12, R11
- SHLQ $0x0d, R14, R13
- ANDQ AX, SI
- IMUL3Q $0x13, R13, R13
- ADDQ R13, SI
- ANDQ AX, R8
- ADDQ BX, R8
- ANDQ AX, R10
- ADDQ DI, R10
- ANDQ AX, R12
- ADDQ R9, R12
- ANDQ AX, R14
- ADDQ R11, R14
-
- // Second reduction chain (carryPropagate)
- MOVQ SI, BX
- SHRQ $0x33, BX
- MOVQ R8, DI
- SHRQ $0x33, DI
- MOVQ R10, R9
- SHRQ $0x33, R9
- MOVQ R12, R11
- SHRQ $0x33, R11
- MOVQ R14, R13
- SHRQ $0x33, R13
- ANDQ AX, SI
- IMUL3Q $0x13, R13, R13
- ADDQ R13, SI
- ANDQ AX, R8
- ADDQ BX, R8
- ANDQ AX, R10
- ADDQ DI, R10
- ANDQ AX, R12
- ADDQ R9, R12
- ANDQ AX, R14
- ADDQ R11, R14
-
- // Store output
- MOVQ out+0(FP), AX
- MOVQ SI, (AX)
- MOVQ R8, 8(AX)
- MOVQ R10, 16(AX)
- MOVQ R12, 24(AX)
- MOVQ R14, 32(AX)
- RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
deleted file mode 100644
index 9da280d1d88..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !amd64 || !gc || purego
-
-package field
-
-func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
-
-func feSquare(v, x *Element) { feSquareGeneric(v, x) }
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
deleted file mode 100644
index 075fe9b9257..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build arm64 && gc && !purego
-
-package field
-
-//go:noescape
-func carryPropagate(v *Element)
-
-func (v *Element) carryPropagate() *Element {
- carryPropagate(v)
- return v
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
deleted file mode 100644
index 3126a434191..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build arm64 && gc && !purego
-
-#include "textflag.h"
-
-// carryPropagate works exactly like carryPropagateGeneric and uses the
-// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
-// avoids loading R0-R4 twice and uses LDP and STP.
-//
-// See https://golang.org/issues/43145 for the main compiler issue.
-//
-// func carryPropagate(v *Element)
-TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
- MOVD v+0(FP), R20
-
- LDP 0(R20), (R0, R1)
- LDP 16(R20), (R2, R3)
- MOVD 32(R20), R4
-
- AND $0x7ffffffffffff, R0, R10
- AND $0x7ffffffffffff, R1, R11
- AND $0x7ffffffffffff, R2, R12
- AND $0x7ffffffffffff, R3, R13
- AND $0x7ffffffffffff, R4, R14
-
- ADD R0>>51, R11, R11
- ADD R1>>51, R12, R12
- ADD R2>>51, R13, R13
- ADD R3>>51, R14, R14
- // R4>>51 * 19 + R10 -> R10
- LSR $51, R4, R21
- MOVD $19, R22
- MADD R22, R10, R21, R10
-
- STP (R10, R11), 0(R20)
- STP (R12, R13), 16(R20)
- MOVD R14, 32(R20)
-
- RET
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
deleted file mode 100644
index fc029ac12da..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !arm64 || !gc || purego
-
-package field
-
-func (v *Element) carryPropagate() *Element {
- return v.carryPropagateGeneric()
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go b/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
deleted file mode 100644
index 2671217da59..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package field
-
-import "math/bits"
-
-// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
-// bits.Mul64 and bits.Add64 intrinsics.
-type uint128 struct {
- lo, hi uint64
-}
-
-// mul64 returns a * b.
-func mul64(a, b uint64) uint128 {
- hi, lo := bits.Mul64(a, b)
- return uint128{lo, hi}
-}
-
-// addMul64 returns v + a * b.
-func addMul64(v uint128, a, b uint64) uint128 {
- hi, lo := bits.Mul64(a, b)
- lo, c := bits.Add64(lo, v.lo, 0)
- hi, _ = bits.Add64(hi, v.hi, c)
- return uint128{lo, hi}
-}
-
-// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
-func shiftRightBy51(a uint128) uint64 {
- return (a.hi << (64 - 51)) | (a.lo >> 51)
-}
-
-func feMulGeneric(v, a, b *Element) {
- a0 := a.l0
- a1 := a.l1
- a2 := a.l2
- a3 := a.l3
- a4 := a.l4
-
- b0 := b.l0
- b1 := b.l1
- b2 := b.l2
- b3 := b.l3
- b4 := b.l4
-
- // Limb multiplication works like pen-and-paper columnar multiplication, but
- // with 51-bit limbs instead of digits.
- //
- // a4 a3 a2 a1 a0 x
- // b4 b3 b2 b1 b0 =
- // ------------------------
- // a4b0 a3b0 a2b0 a1b0 a0b0 +
- // a4b1 a3b1 a2b1 a1b1 a0b1 +
- // a4b2 a3b2 a2b2 a1b2 a0b2 +
- // a4b3 a3b3 a2b3 a1b3 a0b3 +
- // a4b4 a3b4 a2b4 a1b4 a0b4 =
- // ----------------------------------------------
- // r8 r7 r6 r5 r4 r3 r2 r1 r0
- //
- // We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
- // reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
- // r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
- //
- // Reduction can be carried out simultaneously to multiplication. For
- // example, we do not compute r5: whenever the result of a multiplication
- // belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
- //
- // a4b0 a3b0 a2b0 a1b0 a0b0 +
- // a3b1 a2b1 a1b1 a0b1 19×a4b1 +
- // a2b2 a1b2 a0b2 19×a4b2 19×a3b2 +
- // a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 +
- // a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 =
- // --------------------------------------
- // r4 r3 r2 r1 r0
- //
- // Finally we add up the columns into wide, overlapping limbs.
-
- a1_19 := a1 * 19
- a2_19 := a2 * 19
- a3_19 := a3 * 19
- a4_19 := a4 * 19
-
- // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
- r0 := mul64(a0, b0)
- r0 = addMul64(r0, a1_19, b4)
- r0 = addMul64(r0, a2_19, b3)
- r0 = addMul64(r0, a3_19, b2)
- r0 = addMul64(r0, a4_19, b1)
-
- // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
- r1 := mul64(a0, b1)
- r1 = addMul64(r1, a1, b0)
- r1 = addMul64(r1, a2_19, b4)
- r1 = addMul64(r1, a3_19, b3)
- r1 = addMul64(r1, a4_19, b2)
-
- // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
- r2 := mul64(a0, b2)
- r2 = addMul64(r2, a1, b1)
- r2 = addMul64(r2, a2, b0)
- r2 = addMul64(r2, a3_19, b4)
- r2 = addMul64(r2, a4_19, b3)
-
- // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
- r3 := mul64(a0, b3)
- r3 = addMul64(r3, a1, b2)
- r3 = addMul64(r3, a2, b1)
- r3 = addMul64(r3, a3, b0)
- r3 = addMul64(r3, a4_19, b4)
-
- // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
- r4 := mul64(a0, b4)
- r4 = addMul64(r4, a1, b3)
- r4 = addMul64(r4, a2, b2)
- r4 = addMul64(r4, a3, b1)
- r4 = addMul64(r4, a4, b0)
-
- // After the multiplication, we need to reduce (carry) the five coefficients
- // to obtain a result with limbs that are at most slightly larger than 2⁵¹,
- // to respect the Element invariant.
- //
- // Overall, the reduction works the same as carryPropagate, except with
- // wider inputs: we take the carry for each coefficient by shifting it right
- // by 51, and add it to the limb above it. The top carry is multiplied by 19
- // according to the reduction identity and added to the lowest limb.
- //
- // The largest coefficient (r0) will be at most 111 bits, which guarantees
- // that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
- //
- // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
- // r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
- // r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
- // r0 < 2⁷ × 2⁵² × 2⁵²
- // r0 < 2¹¹¹
- //
- // Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
- // 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
- // allows us to easily apply the reduction identity.
- //
- // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
- // r4 < 5 × 2⁵² × 2⁵²
- // r4 < 2¹⁰⁷
- //
-
- c0 := shiftRightBy51(r0)
- c1 := shiftRightBy51(r1)
- c2 := shiftRightBy51(r2)
- c3 := shiftRightBy51(r3)
- c4 := shiftRightBy51(r4)
-
- rr0 := r0.lo&maskLow51Bits + c4*19
- rr1 := r1.lo&maskLow51Bits + c0
- rr2 := r2.lo&maskLow51Bits + c1
- rr3 := r3.lo&maskLow51Bits + c2
- rr4 := r4.lo&maskLow51Bits + c3
-
- // Now all coefficients fit into 64-bit registers but are still too large to
- // be passed around as a Element. We therefore do one last carry chain,
- // where the carries will be small enough to fit in the wiggle room above 2⁵¹.
- *v = Element{rr0, rr1, rr2, rr3, rr4}
- v.carryPropagate()
-}
-
-func feSquareGeneric(v, a *Element) {
- l0 := a.l0
- l1 := a.l1
- l2 := a.l2
- l3 := a.l3
- l4 := a.l4
-
- // Squaring works precisely like multiplication above, but thanks to its
- // symmetry we get to group a few terms together.
- //
- // l4 l3 l2 l1 l0 x
- // l4 l3 l2 l1 l0 =
- // ------------------------
- // l4l0 l3l0 l2l0 l1l0 l0l0 +
- // l4l1 l3l1 l2l1 l1l1 l0l1 +
- // l4l2 l3l2 l2l2 l1l2 l0l2 +
- // l4l3 l3l3 l2l3 l1l3 l0l3 +
- // l4l4 l3l4 l2l4 l1l4 l0l4 =
- // ----------------------------------------------
- // r8 r7 r6 r5 r4 r3 r2 r1 r0
- //
- // l4l0 l3l0 l2l0 l1l0 l0l0 +
- // l3l1 l2l1 l1l1 l0l1 19×l4l1 +
- // l2l2 l1l2 l0l2 19×l4l2 19×l3l2 +
- // l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 +
- // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 =
- // --------------------------------------
- // r4 r3 r2 r1 r0
- //
- // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
- // only three Mul64 and four Add64, instead of five and eight.
-
- l0_2 := l0 * 2
- l1_2 := l1 * 2
-
- l1_38 := l1 * 38
- l2_38 := l2 * 38
- l3_38 := l3 * 38
-
- l3_19 := l3 * 19
- l4_19 := l4 * 19
-
- // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
- r0 := mul64(l0, l0)
- r0 = addMul64(r0, l1_38, l4)
- r0 = addMul64(r0, l2_38, l3)
-
- // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
- r1 := mul64(l0_2, l1)
- r1 = addMul64(r1, l2_38, l4)
- r1 = addMul64(r1, l3_19, l3)
-
- // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
- r2 := mul64(l0_2, l2)
- r2 = addMul64(r2, l1, l1)
- r2 = addMul64(r2, l3_38, l4)
-
- // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
- r3 := mul64(l0_2, l3)
- r3 = addMul64(r3, l1_2, l2)
- r3 = addMul64(r3, l4_19, l4)
-
- // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
- r4 := mul64(l0_2, l4)
- r4 = addMul64(r4, l1_2, l3)
- r4 = addMul64(r4, l2, l2)
-
- c0 := shiftRightBy51(r0)
- c1 := shiftRightBy51(r1)
- c2 := shiftRightBy51(r2)
- c3 := shiftRightBy51(r3)
- c4 := shiftRightBy51(r4)
-
- rr0 := r0.lo&maskLow51Bits + c4*19
- rr1 := r1.lo&maskLow51Bits + c0
- rr2 := r2.lo&maskLow51Bits + c1
- rr3 := r3.lo&maskLow51Bits + c2
- rr4 := r4.lo&maskLow51Bits + c3
-
- *v = Element{rr0, rr1, rr2, rr3, rr4}
- v.carryPropagate()
-}
-
-// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
-// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
-func (v *Element) carryPropagateGeneric() *Element {
- c0 := v.l0 >> 51
- c1 := v.l1 >> 51
- c2 := v.l2 >> 51
- c3 := v.l3 >> 51
- c4 := v.l4 >> 51
-
- v.l0 = v.l0&maskLow51Bits + c4*19
- v.l1 = v.l1&maskLow51Bits + c0
- v.l2 = v.l2&maskLow51Bits + c1
- v.l3 = v.l3&maskLow51Bits + c2
- v.l4 = v.l4&maskLow51Bits + c3
-
- return v
-}
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
deleted file mode 100644
index e3685f95cab..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
+++ /dev/null
@@ -1 +0,0 @@
-b0c49ae9f59d233526f8934262c5bbbe14d4358d
diff --git a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh b/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
deleted file mode 100644
index 1ba22a8b4c9..00000000000
--- a/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/bash
-set -euo pipefail
-
-cd "$(git rev-parse --show-toplevel)"
-
-STD_PATH=src/crypto/ed25519/internal/edwards25519/field
-LOCAL_PATH=curve25519/internal/field
-LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint)
-
-git fetch https://go.googlesource.com/go master
-
-if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then
- echo "No changes."
-else
- NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint)
- echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..."
- git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \
- git apply -3 --directory=$LOCAL_PATH
-fi
diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go
index a7828345fcc..59b3a95a7d2 100644
--- a/vendor/golang.org/x/crypto/ed25519/ed25519.go
+++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go
@@ -11,9 +11,7 @@
// operations with the same key more efficient. This package refers to the RFC
// 8032 private key as the “seed”.
//
-// Beginning with Go 1.13, the functionality of this package was moved to the
-// standard library as crypto/ed25519. This package only acts as a compatibility
-// wrapper.
+// This package is a wrapper around the standard library crypto/ed25519 package.
package ed25519
import (
diff --git a/vendor/golang.org/x/crypto/hkdf/hkdf.go b/vendor/golang.org/x/crypto/hkdf/hkdf.go
index f4ded5fee2f..3bee66294ec 100644
--- a/vendor/golang.org/x/crypto/hkdf/hkdf.go
+++ b/vendor/golang.org/x/crypto/hkdf/hkdf.go
@@ -8,7 +8,7 @@
// HKDF is a cryptographic key derivation function (KDF) with the goal of
// expanding limited input keying material into one or more cryptographically
// strong secret keys.
-package hkdf // import "golang.org/x/crypto/hkdf"
+package hkdf
import (
"crypto/hmac"
diff --git a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
index f3c3242a047..1fe600ad034 100644
--- a/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
+++ b/vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
@@ -32,7 +32,7 @@ chunk size.
This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
*/
-package secretbox // import "golang.org/x/crypto/nacl/secretbox"
+package secretbox
import (
"golang.org/x/crypto/internal/alias"
diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp.go b/vendor/golang.org/x/crypto/ocsp/ocsp.go
index bf2259537d2..e6c645e7ceb 100644
--- a/vendor/golang.org/x/crypto/ocsp/ocsp.go
+++ b/vendor/golang.org/x/crypto/ocsp/ocsp.go
@@ -5,7 +5,7 @@
// Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses
// are signed messages attesting to the validity of a certificate for a small
// period of time. This is used to manage revocation for X.509 certificates.
-package ocsp // import "golang.org/x/crypto/ocsp"
+package ocsp
import (
"crypto"
diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
index 904b57e01d7..28cd99c7f3f 100644
--- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
+++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
@@ -16,7 +16,7 @@ Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To
choose, you can pass the `New` functions from the different SHA packages to
pbkdf2.Key.
*/
-package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
+package pbkdf2
import (
"crypto/hmac"
diff --git a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go
index cf3eeb158a9..b6d33ef074b 100644
--- a/vendor/golang.org/x/crypto/ripemd160/ripemd160.go
+++ b/vendor/golang.org/x/crypto/ripemd160/ripemd160.go
@@ -7,7 +7,7 @@
// Deprecated: RIPEMD-160 is a legacy hash and should not be used for new
// applications. Also, this package does not and will not provide an optimized
// implementation. Instead, use a modern hash like SHA-256 (from crypto/sha256).
-package ripemd160 // import "golang.org/x/crypto/ripemd160"
+package ripemd160
// RIPEMD-160 is designed by Hans Dobbertin, Antoon Bosselaers, and Bart
// Preneel with specifications available at:
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
index 3fd05b27516..3685b344587 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
+++ b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// Package salsa provides low-level access to functions in the Salsa family.
-package salsa // import "golang.org/x/crypto/salsa20/salsa"
+package salsa
import "math/bits"
diff --git a/vendor/golang.org/x/crypto/scrypt/scrypt.go b/vendor/golang.org/x/crypto/scrypt/scrypt.go
index c971a99fa67..76fa40fb20a 100644
--- a/vendor/golang.org/x/crypto/scrypt/scrypt.go
+++ b/vendor/golang.org/x/crypto/scrypt/scrypt.go
@@ -5,7 +5,7 @@
// Package scrypt implements the scrypt key derivation function as defined in
// Colin Percival's paper "Stronger Key Derivation via Sequential Memory-Hard
// Functions" (https://www.tarsnap.com/scrypt/scrypt.pdf).
-package scrypt // import "golang.org/x/crypto/scrypt"
+package scrypt
import (
"crypto/sha256"
diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go
index decd8cf9bf7..7e023090707 100644
--- a/vendor/golang.org/x/crypto/sha3/doc.go
+++ b/vendor/golang.org/x/crypto/sha3/doc.go
@@ -59,4 +59,4 @@
// They produce output of the same length, with the same security strengths
// against all attacks. This means, in particular, that SHA3-256 only has
// 128-bit collision resistance, because its output length is 32 bytes.
-package sha3 // import "golang.org/x/crypto/sha3"
+package sha3
diff --git a/vendor/golang.org/x/crypto/sha3/hashes.go b/vendor/golang.org/x/crypto/sha3/hashes.go
index 0d8043fd2a1..c544b29e5f2 100644
--- a/vendor/golang.org/x/crypto/sha3/hashes.go
+++ b/vendor/golang.org/x/crypto/sha3/hashes.go
@@ -9,6 +9,7 @@ package sha3
// bytes.
import (
+ "crypto"
"hash"
)
@@ -16,39 +17,50 @@ import (
// Its generic security strength is 224 bits against preimage attacks,
// and 112 bits against collision attacks.
func New224() hash.Hash {
- if h := new224Asm(); h != nil {
- return h
- }
- return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
+ return new224()
}
// New256 creates a new SHA3-256 hash.
// Its generic security strength is 256 bits against preimage attacks,
// and 128 bits against collision attacks.
func New256() hash.Hash {
- if h := new256Asm(); h != nil {
- return h
- }
- return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
+ return new256()
}
// New384 creates a new SHA3-384 hash.
// Its generic security strength is 384 bits against preimage attacks,
// and 192 bits against collision attacks.
func New384() hash.Hash {
- if h := new384Asm(); h != nil {
- return h
- }
- return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
+ return new384()
}
// New512 creates a new SHA3-512 hash.
// Its generic security strength is 512 bits against preimage attacks,
// and 256 bits against collision attacks.
func New512() hash.Hash {
- if h := new512Asm(); h != nil {
- return h
- }
+ return new512()
+}
+
+func init() {
+ crypto.RegisterHash(crypto.SHA3_224, New224)
+ crypto.RegisterHash(crypto.SHA3_256, New256)
+ crypto.RegisterHash(crypto.SHA3_384, New384)
+ crypto.RegisterHash(crypto.SHA3_512, New512)
+}
+
+func new224Generic() *state {
+ return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
+}
+
+func new256Generic() *state {
+ return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
+}
+
+func new384Generic() *state {
+ return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
+}
+
+func new512Generic() *state {
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
}
diff --git a/vendor/golang.org/x/crypto/sha3/hashes_generic.go b/vendor/golang.org/x/crypto/sha3/hashes_generic.go
deleted file mode 100644
index fe8c84793c0..00000000000
--- a/vendor/golang.org/x/crypto/sha3/hashes_generic.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !gc || purego || !s390x
-
-package sha3
-
-import (
- "hash"
-)
-
-// new224Asm returns an assembly implementation of SHA3-224 if available,
-// otherwise it returns nil.
-func new224Asm() hash.Hash { return nil }
-
-// new256Asm returns an assembly implementation of SHA3-256 if available,
-// otherwise it returns nil.
-func new256Asm() hash.Hash { return nil }
-
-// new384Asm returns an assembly implementation of SHA3-384 if available,
-// otherwise it returns nil.
-func new384Asm() hash.Hash { return nil }
-
-// new512Asm returns an assembly implementation of SHA3-512 if available,
-// otherwise it returns nil.
-func new512Asm() hash.Hash { return nil }
diff --git a/vendor/golang.org/x/crypto/sha3/hashes_noasm.go b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go
new file mode 100644
index 00000000000..9d85fb62144
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go
@@ -0,0 +1,23 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !gc || purego || !s390x
+
+package sha3
+
+func new224() *state {
+ return new224Generic()
+}
+
+func new256() *state {
+ return new256Generic()
+}
+
+func new384() *state {
+ return new384Generic()
+}
+
+func new512() *state {
+ return new512Generic()
+}
diff --git a/vendor/golang.org/x/crypto/sha3/register.go b/vendor/golang.org/x/crypto/sha3/register.go
deleted file mode 100644
index addfd5049bb..00000000000
--- a/vendor/golang.org/x/crypto/sha3/register.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.4
-
-package sha3
-
-import (
- "crypto"
-)
-
-func init() {
- crypto.RegisterHash(crypto.SHA3_224, New224)
- crypto.RegisterHash(crypto.SHA3_256, New256)
- crypto.RegisterHash(crypto.SHA3_384, New384)
- crypto.RegisterHash(crypto.SHA3_512, New512)
-}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3.go b/vendor/golang.org/x/crypto/sha3/sha3.go
index 4884d172a49..afedde5abf1 100644
--- a/vendor/golang.org/x/crypto/sha3/sha3.go
+++ b/vendor/golang.org/x/crypto/sha3/sha3.go
@@ -23,7 +23,6 @@ const (
type state struct {
// Generic sponge components.
a [25]uint64 // main state of the hash
- buf []byte // points into storage
rate int // the number of bytes of state to use
// dsbyte contains the "domain separation" bits and the first bit of
@@ -40,7 +39,8 @@ type state struct {
// Extendable-Output Functions (May 2014)"
dsbyte byte
- storage storageBuf
+ i, n int // storage[i:n] is the buffer, i is only used while squeezing
+ storage [maxRate]byte
// Specific to SHA-3 and SHAKE.
outputLen int // the default output size in bytes
@@ -54,24 +54,18 @@ func (d *state) BlockSize() int { return d.rate }
func (d *state) Size() int { return d.outputLen }
// Reset clears the internal state by zeroing the sponge state and
-// the byte buffer, and setting Sponge.state to absorbing.
+// the buffer indexes, and setting Sponge.state to absorbing.
func (d *state) Reset() {
// Zero the permutation's state.
for i := range d.a {
d.a[i] = 0
}
d.state = spongeAbsorbing
- d.buf = d.storage.asBytes()[:0]
+ d.i, d.n = 0, 0
}
func (d *state) clone() *state {
ret := *d
- if ret.state == spongeAbsorbing {
- ret.buf = ret.storage.asBytes()[:len(ret.buf)]
- } else {
- ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
- }
-
return &ret
}
@@ -82,43 +76,40 @@ func (d *state) permute() {
case spongeAbsorbing:
// If we're absorbing, we need to xor the input into the state
// before applying the permutation.
- xorIn(d, d.buf)
- d.buf = d.storage.asBytes()[:0]
+ xorIn(d, d.storage[:d.rate])
+ d.n = 0
keccakF1600(&d.a)
case spongeSqueezing:
// If we're squeezing, we need to apply the permutation before
// copying more output.
keccakF1600(&d.a)
- d.buf = d.storage.asBytes()[:d.rate]
- copyOut(d, d.buf)
+ d.i = 0
+ copyOut(d, d.storage[:d.rate])
}
}
// pads appends the domain separation bits in dsbyte, applies
// the multi-bitrate 10..1 padding rule, and permutes the state.
-func (d *state) padAndPermute(dsbyte byte) {
- if d.buf == nil {
- d.buf = d.storage.asBytes()[:0]
- }
+func (d *state) padAndPermute() {
// Pad with this instance's domain-separator bits. We know that there's
// at least one byte of space in d.buf because, if it were full,
// permute would have been called to empty it. dsbyte also contains the
// first one bit for the padding. See the comment in the state struct.
- d.buf = append(d.buf, dsbyte)
- zerosStart := len(d.buf)
- d.buf = d.storage.asBytes()[:d.rate]
- for i := zerosStart; i < d.rate; i++ {
- d.buf[i] = 0
+ d.storage[d.n] = d.dsbyte
+ d.n++
+ for d.n < d.rate {
+ d.storage[d.n] = 0
+ d.n++
}
// This adds the final one bit for the padding. Because of the way that
// bits are numbered from the LSB upwards, the final bit is the MSB of
// the last byte.
- d.buf[d.rate-1] ^= 0x80
+ d.storage[d.rate-1] ^= 0x80
// Apply the permutation
d.permute()
d.state = spongeSqueezing
- d.buf = d.storage.asBytes()[:d.rate]
- copyOut(d, d.buf)
+ d.n = d.rate
+ copyOut(d, d.storage[:d.rate])
}
// Write absorbs more data into the hash's state. It panics if any
@@ -127,28 +118,25 @@ func (d *state) Write(p []byte) (written int, err error) {
if d.state != spongeAbsorbing {
panic("sha3: Write after Read")
}
- if d.buf == nil {
- d.buf = d.storage.asBytes()[:0]
- }
written = len(p)
for len(p) > 0 {
- if len(d.buf) == 0 && len(p) >= d.rate {
+ if d.n == 0 && len(p) >= d.rate {
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
xorIn(d, p[:d.rate])
p = p[d.rate:]
keccakF1600(&d.a)
} else {
// The slow path; buffer the input until we can fill the sponge, and then xor it in.
- todo := d.rate - len(d.buf)
+ todo := d.rate - d.n
if todo > len(p) {
todo = len(p)
}
- d.buf = append(d.buf, p[:todo]...)
+ d.n += copy(d.storage[d.n:], p[:todo])
p = p[todo:]
// If the sponge is full, apply the permutation.
- if len(d.buf) == d.rate {
+ if d.n == d.rate {
d.permute()
}
}
@@ -161,19 +149,19 @@ func (d *state) Write(p []byte) (written int, err error) {
func (d *state) Read(out []byte) (n int, err error) {
// If we're still absorbing, pad and apply the permutation.
if d.state == spongeAbsorbing {
- d.padAndPermute(d.dsbyte)
+ d.padAndPermute()
}
n = len(out)
// Now, do the squeezing.
for len(out) > 0 {
- n := copy(out, d.buf)
- d.buf = d.buf[n:]
+ n := copy(out, d.storage[d.i:d.n])
+ d.i += n
out = out[n:]
// Apply the permutation if we've squeezed the sponge dry.
- if len(d.buf) == 0 {
+ if d.i == d.rate {
d.permute()
}
}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
index b4fbbf8695c..00d8034ae62 100644
--- a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
+++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
@@ -248,56 +248,56 @@ func (s *asmState) Clone() ShakeHash {
return s.clone()
}
-// new224Asm returns an assembly implementation of SHA3-224 if available,
-// otherwise it returns nil.
-func new224Asm() hash.Hash {
+// new224 returns an assembly implementation of SHA3-224 if available,
+// otherwise it returns a generic implementation.
+func new224() hash.Hash {
if cpu.S390X.HasSHA3 {
return newAsmState(sha3_224)
}
- return nil
+ return new224Generic()
}
-// new256Asm returns an assembly implementation of SHA3-256 if available,
-// otherwise it returns nil.
-func new256Asm() hash.Hash {
+// new256 returns an assembly implementation of SHA3-256 if available,
+// otherwise it returns a generic implementation.
+func new256() hash.Hash {
if cpu.S390X.HasSHA3 {
return newAsmState(sha3_256)
}
- return nil
+ return new256Generic()
}
-// new384Asm returns an assembly implementation of SHA3-384 if available,
-// otherwise it returns nil.
-func new384Asm() hash.Hash {
+// new384 returns an assembly implementation of SHA3-384 if available,
+// otherwise it returns a generic implementation.
+func new384() hash.Hash {
if cpu.S390X.HasSHA3 {
return newAsmState(sha3_384)
}
- return nil
+ return new384Generic()
}
-// new512Asm returns an assembly implementation of SHA3-512 if available,
-// otherwise it returns nil.
-func new512Asm() hash.Hash {
+// new512 returns an assembly implementation of SHA3-512 if available,
+// otherwise it returns a generic implementation.
+func new512() hash.Hash {
if cpu.S390X.HasSHA3 {
return newAsmState(sha3_512)
}
- return nil
+ return new512Generic()
}
-// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
-// otherwise it returns nil.
-func newShake128Asm() ShakeHash {
+// newShake128 returns an assembly implementation of SHAKE-128 if available,
+// otherwise it returns a generic implementation.
+func newShake128() ShakeHash {
if cpu.S390X.HasSHA3 {
return newAsmState(shake_128)
}
- return nil
+ return newShake128Generic()
}
-// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
-// otherwise it returns nil.
-func newShake256Asm() ShakeHash {
+// newShake256 returns an assembly implementation of SHAKE-256 if available,
+// otherwise it returns a generic implementation.
+func newShake256() ShakeHash {
if cpu.S390X.HasSHA3 {
return newAsmState(shake_256)
}
- return nil
+ return newShake256Generic()
}
diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go
index bb69984027f..1ea9275b8b7 100644
--- a/vendor/golang.org/x/crypto/sha3/shake.go
+++ b/vendor/golang.org/x/crypto/sha3/shake.go
@@ -115,19 +115,21 @@ func (c *state) Clone() ShakeHash {
// Its generic security strength is 128 bits against all attacks if at
// least 32 bytes of its output are used.
func NewShake128() ShakeHash {
- if h := newShake128Asm(); h != nil {
- return h
- }
- return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
+ return newShake128()
}
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
// Its generic security strength is 256 bits against all attacks if
// at least 64 bytes of its output are used.
func NewShake256() ShakeHash {
- if h := newShake256Asm(); h != nil {
- return h
- }
+ return newShake256()
+}
+
+func newShake128Generic() *state {
+ return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
+}
+
+func newShake256Generic() *state {
return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
}
diff --git a/vendor/golang.org/x/crypto/sha3/shake_generic.go b/vendor/golang.org/x/crypto/sha3/shake_generic.go
deleted file mode 100644
index 8d31cf5be2d..00000000000
--- a/vendor/golang.org/x/crypto/sha3/shake_generic.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !gc || purego || !s390x
-
-package sha3
-
-// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
-// otherwise it returns nil.
-func newShake128Asm() ShakeHash {
- return nil
-}
-
-// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
-// otherwise it returns nil.
-func newShake256Asm() ShakeHash {
- return nil
-}
diff --git a/vendor/golang.org/x/crypto/sha3/shake_noasm.go b/vendor/golang.org/x/crypto/sha3/shake_noasm.go
new file mode 100644
index 00000000000..4276ba4ab2c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/shake_noasm.go
@@ -0,0 +1,15 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !gc || purego || !s390x
+
+package sha3
+
+func newShake128() *state {
+ return newShake128Generic()
+}
+
+func newShake256() *state {
+ return newShake256Generic()
+}
diff --git a/vendor/golang.org/x/crypto/sha3/xor.go b/vendor/golang.org/x/crypto/sha3/xor.go
index 7337cca88ed..6ada5c9574e 100644
--- a/vendor/golang.org/x/crypto/sha3/xor.go
+++ b/vendor/golang.org/x/crypto/sha3/xor.go
@@ -2,22 +2,39 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build (!amd64 && !386 && !ppc64le) || purego
-
package sha3
-// A storageBuf is an aligned array of maxRate bytes.
-type storageBuf [maxRate]byte
-
-func (b *storageBuf) asBytes() *[maxRate]byte {
- return (*[maxRate]byte)(b)
-}
+import (
+ "crypto/subtle"
+ "encoding/binary"
+ "unsafe"
-var (
- xorIn = xorInGeneric
- copyOut = copyOutGeneric
- xorInUnaligned = xorInGeneric
- copyOutUnaligned = copyOutGeneric
+ "golang.org/x/sys/cpu"
)
-const xorImplementationUnaligned = "generic"
+// xorIn xors the bytes in buf into the state.
+func xorIn(d *state, buf []byte) {
+ if cpu.IsBigEndian {
+ for i := 0; len(buf) >= 8; i++ {
+ a := binary.LittleEndian.Uint64(buf)
+ d.a[i] ^= a
+ buf = buf[8:]
+ }
+ } else {
+ ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
+ subtle.XORBytes(ab[:], ab[:], buf)
+ }
+}
+
+// copyOut copies uint64s to a byte buffer.
+func copyOut(d *state, b []byte) {
+ if cpu.IsBigEndian {
+ for i := 0; len(b) >= 8; i++ {
+ binary.LittleEndian.PutUint64(b, d.a[i])
+ b = b[8:]
+ }
+ } else {
+ ab := (*[25 * 64 / 8]byte)(unsafe.Pointer(&d.a))
+ copy(b, ab[:])
+ }
+}
diff --git a/vendor/golang.org/x/crypto/sha3/xor_generic.go b/vendor/golang.org/x/crypto/sha3/xor_generic.go
deleted file mode 100644
index 8d947711272..00000000000
--- a/vendor/golang.org/x/crypto/sha3/xor_generic.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sha3
-
-import "encoding/binary"
-
-// xorInGeneric xors the bytes in buf into the state; it
-// makes no non-portable assumptions about memory layout
-// or alignment.
-func xorInGeneric(d *state, buf []byte) {
- n := len(buf) / 8
-
- for i := 0; i < n; i++ {
- a := binary.LittleEndian.Uint64(buf)
- d.a[i] ^= a
- buf = buf[8:]
- }
-}
-
-// copyOutGeneric copies uint64s to a byte buffer.
-func copyOutGeneric(d *state, b []byte) {
- for i := 0; len(b) >= 8; i++ {
- binary.LittleEndian.PutUint64(b, d.a[i])
- b = b[8:]
- }
-}
diff --git a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go b/vendor/golang.org/x/crypto/sha3/xor_unaligned.go
deleted file mode 100644
index 870e2d16e07..00000000000
--- a/vendor/golang.org/x/crypto/sha3/xor_unaligned.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build (amd64 || 386 || ppc64le) && !purego
-
-package sha3
-
-import "unsafe"
-
-// A storageBuf is an aligned array of maxRate bytes.
-type storageBuf [maxRate / 8]uint64
-
-func (b *storageBuf) asBytes() *[maxRate]byte {
- return (*[maxRate]byte)(unsafe.Pointer(b))
-}
-
-// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
-// XOR buf.
-func xorInUnaligned(d *state, buf []byte) {
- n := len(buf)
- bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
- if n >= 72 {
- d.a[0] ^= bw[0]
- d.a[1] ^= bw[1]
- d.a[2] ^= bw[2]
- d.a[3] ^= bw[3]
- d.a[4] ^= bw[4]
- d.a[5] ^= bw[5]
- d.a[6] ^= bw[6]
- d.a[7] ^= bw[7]
- d.a[8] ^= bw[8]
- }
- if n >= 104 {
- d.a[9] ^= bw[9]
- d.a[10] ^= bw[10]
- d.a[11] ^= bw[11]
- d.a[12] ^= bw[12]
- }
- if n >= 136 {
- d.a[13] ^= bw[13]
- d.a[14] ^= bw[14]
- d.a[15] ^= bw[15]
- d.a[16] ^= bw[16]
- }
- if n >= 144 {
- d.a[17] ^= bw[17]
- }
- if n >= 168 {
- d.a[18] ^= bw[18]
- d.a[19] ^= bw[19]
- d.a[20] ^= bw[20]
- }
-}
-
-func copyOutUnaligned(d *state, buf []byte) {
- ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
- copy(buf, ab[:])
-}
-
-var (
- xorIn = xorInUnaligned
- copyOut = copyOutUnaligned
-)
-
-const xorImplementationUnaligned = "unaligned"
diff --git a/vendor/golang.org/x/crypto/ssh/agent/client.go b/vendor/golang.org/x/crypto/ssh/agent/client.go
index fecba8eb384..106708d289e 100644
--- a/vendor/golang.org/x/crypto/ssh/agent/client.go
+++ b/vendor/golang.org/x/crypto/ssh/agent/client.go
@@ -10,7 +10,7 @@
// References:
//
// [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
-package agent // import "golang.org/x/crypto/ssh/agent"
+package agent
import (
"bytes"
diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go
index 9486c598623..b93961010d3 100644
--- a/vendor/golang.org/x/crypto/ssh/client_auth.go
+++ b/vendor/golang.org/x/crypto/ssh/client_auth.go
@@ -71,6 +71,10 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
for auth := AuthMethod(new(noneAuth)); auth != nil; {
ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
if err != nil {
+ // On disconnect, return error immediately
+ if _, ok := err.(*disconnectMsg); ok {
+ return err
+ }
// We return the error later if there is no other method left to
// try.
ok = authFailure
diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go
index edbe63340d3..f5d352fe3a0 100644
--- a/vendor/golang.org/x/crypto/ssh/doc.go
+++ b/vendor/golang.org/x/crypto/ssh/doc.go
@@ -20,4 +20,4 @@ References:
This package does not fall under the stability promise of the Go language itself,
so its API may be changed when pressing needs arise.
*/
-package ssh // import "golang.org/x/crypto/ssh"
+package ssh
diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go
index df4ebdada50..7967665f174 100644
--- a/vendor/golang.org/x/crypto/ssh/keys.go
+++ b/vendor/golang.org/x/crypto/ssh/keys.go
@@ -904,6 +904,10 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
return errors.New("ssh: signature did not verify")
}
+func (k *skECDSAPublicKey) CryptoPublicKey() crypto.PublicKey {
+ return &k.PublicKey
+}
+
type skEd25519PublicKey struct {
// application is a URL-like string, typically "ssh:" for SSH.
// see openssh/PROTOCOL.u2f for details.
@@ -1000,6 +1004,10 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
return nil
}
+func (k *skEd25519PublicKey) CryptoPublicKey() crypto.PublicKey {
+ return k.PublicKey
+}
+
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
// *ecdsa.PrivateKey or any other crypto.Signer and returns a
// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
index e2ae4f891bb..3ca9e89e22e 100644
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -462,6 +462,24 @@ func (p *PartialSuccessError) Error() string {
// It is returned in ServerAuthError.Errors from NewServerConn.
var ErrNoAuth = errors.New("ssh: no auth passed yet")
+// BannerError is an error that can be returned by authentication handlers in
+// ServerConfig to send a banner message to the client.
+type BannerError struct {
+ Err error
+ Message string
+}
+
+func (b *BannerError) Unwrap() error {
+ return b.Err
+}
+
+func (b *BannerError) Error() string {
+ if b.Err == nil {
+ return b.Message
+ }
+ return b.Err.Error()
+}
+
func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
sessionID := s.transport.getSessionID()
var cache pubKeyCache
@@ -734,6 +752,18 @@ userAuthLoop:
config.AuthLogCallback(s, userAuthReq.Method, authErr)
}
+ var bannerErr *BannerError
+ if errors.As(authErr, &bannerErr) {
+ if bannerErr.Message != "" {
+ bannerMsg := &userAuthBannerMsg{
+ Message: bannerErr.Message,
+ }
+ if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
+ return nil, err
+ }
+ }
+ }
+
if authErr == nil {
break userAuthLoop
}
diff --git a/vendor/golang.org/x/exp/slices/cmp.go b/vendor/golang.org/x/exp/slices/cmp.go
new file mode 100644
index 00000000000..fbf1934a061
--- /dev/null
+++ b/vendor/golang.org/x/exp/slices/cmp.go
@@ -0,0 +1,44 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package slices
+
+import "golang.org/x/exp/constraints"
+
+// min is a version of the predeclared function from the Go 1.21 release.
+func min[T constraints.Ordered](a, b T) T {
+ if a < b || isNaN(a) {
+ return a
+ }
+ return b
+}
+
+// max is a version of the predeclared function from the Go 1.21 release.
+func max[T constraints.Ordered](a, b T) T {
+ if a > b || isNaN(a) {
+ return a
+ }
+ return b
+}
+
+// cmpLess is a copy of cmp.Less from the Go 1.21 release.
+func cmpLess[T constraints.Ordered](x, y T) bool {
+ return (isNaN(x) && !isNaN(y)) || x < y
+}
+
+// cmpCompare is a copy of cmp.Compare from the Go 1.21 release.
+func cmpCompare[T constraints.Ordered](x, y T) int {
+ xNaN := isNaN(x)
+ yNaN := isNaN(y)
+ if xNaN && yNaN {
+ return 0
+ }
+ if xNaN || x < y {
+ return -1
+ }
+ if yNaN || x > y {
+ return +1
+ }
+ return 0
+}
diff --git a/vendor/golang.org/x/exp/slices/slices.go b/vendor/golang.org/x/exp/slices/slices.go
index 2540bd68255..5e8158bba86 100644
--- a/vendor/golang.org/x/exp/slices/slices.go
+++ b/vendor/golang.org/x/exp/slices/slices.go
@@ -3,23 +3,20 @@
// license that can be found in the LICENSE file.
// Package slices defines various functions useful with slices of any type.
-// Unless otherwise specified, these functions all apply to the elements
-// of a slice at index 0 <= i < len(s).
-//
-// Note that the less function in IsSortedFunc, SortFunc, SortStableFunc requires a
-// strict weak ordering (https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings),
-// or the sorting may fail to sort correctly. A common case is when sorting slices of
-// floating-point numbers containing NaN values.
package slices
-import "golang.org/x/exp/constraints"
+import (
+ "unsafe"
+
+ "golang.org/x/exp/constraints"
+)
// Equal reports whether two slices are equal: the same length and all
// elements equal. If the lengths are different, Equal returns false.
// Otherwise, the elements are compared in increasing index order, and the
// comparison stops at the first unequal pair.
// Floating point NaNs are not considered equal.
-func Equal[E comparable](s1, s2 []E) bool {
+func Equal[S ~[]E, E comparable](s1, s2 S) bool {
if len(s1) != len(s2) {
return false
}
@@ -31,12 +28,12 @@ func Equal[E comparable](s1, s2 []E) bool {
return true
}
-// EqualFunc reports whether two slices are equal using a comparison
+// EqualFunc reports whether two slices are equal using an equality
// function on each pair of elements. If the lengths are different,
// EqualFunc returns false. Otherwise, the elements are compared in
// increasing index order, and the comparison stops at the first index
// for which eq returns false.
-func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool {
+func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
if len(s1) != len(s2) {
return false
}
@@ -49,45 +46,37 @@ func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool {
return true
}
-// Compare compares the elements of s1 and s2.
-// The elements are compared sequentially, starting at index 0,
+// Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair
+// of elements. The elements are compared sequentially, starting at index 0,
// until one element is not equal to the other.
// The result of comparing the first non-matching elements is returned.
// If both slices are equal until one of them ends, the shorter slice is
// considered less than the longer one.
// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
-// Comparisons involving floating point NaNs are ignored.
-func Compare[E constraints.Ordered](s1, s2 []E) int {
- s2len := len(s2)
+func Compare[S ~[]E, E constraints.Ordered](s1, s2 S) int {
for i, v1 := range s1 {
- if i >= s2len {
+ if i >= len(s2) {
return +1
}
v2 := s2[i]
- switch {
- case v1 < v2:
- return -1
- case v1 > v2:
- return +1
+ if c := cmpCompare(v1, v2); c != 0 {
+ return c
}
}
- if len(s1) < s2len {
+ if len(s1) < len(s2) {
return -1
}
return 0
}
-// CompareFunc is like Compare but uses a comparison function
-// on each pair of elements. The elements are compared in increasing
-// index order, and the comparisons stop after the first time cmp
-// returns non-zero.
+// CompareFunc is like [Compare] but uses a custom comparison function on each
+// pair of elements.
// The result is the first non-zero result of cmp; if cmp always
// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
// and +1 if len(s1) > len(s2).
-func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
- s2len := len(s2)
+func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
for i, v1 := range s1 {
- if i >= s2len {
+ if i >= len(s2) {
return +1
}
v2 := s2[i]
@@ -95,7 +84,7 @@ func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
return c
}
}
- if len(s1) < s2len {
+ if len(s1) < len(s2) {
return -1
}
return 0
@@ -103,7 +92,7 @@ func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
// Index returns the index of the first occurrence of v in s,
// or -1 if not present.
-func Index[E comparable](s []E, v E) int {
+func Index[S ~[]E, E comparable](s S, v E) int {
for i := range s {
if v == s[i] {
return i
@@ -114,7 +103,7 @@ func Index[E comparable](s []E, v E) int {
// IndexFunc returns the first index i satisfying f(s[i]),
// or -1 if none do.
-func IndexFunc[E any](s []E, f func(E) bool) int {
+func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
for i := range s {
if f(s[i]) {
return i
@@ -124,39 +113,104 @@ func IndexFunc[E any](s []E, f func(E) bool) int {
}
// Contains reports whether v is present in s.
-func Contains[E comparable](s []E, v E) bool {
+func Contains[S ~[]E, E comparable](s S, v E) bool {
return Index(s, v) >= 0
}
// ContainsFunc reports whether at least one
// element e of s satisfies f(e).
-func ContainsFunc[E any](s []E, f func(E) bool) bool {
+func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
return IndexFunc(s, f) >= 0
}
// Insert inserts the values v... into s at index i,
// returning the modified slice.
-// In the returned slice r, r[i] == v[0].
+// The elements at s[i:] are shifted up to make room.
+// In the returned slice r, r[i] == v[0],
+// and r[i+len(v)] == value originally at r[i].
// Insert panics if i is out of range.
// This function is O(len(s) + len(v)).
func Insert[S ~[]E, E any](s S, i int, v ...E) S {
- tot := len(s) + len(v)
- if tot <= cap(s) {
- s2 := s[:tot]
- copy(s2[i+len(v):], s[i:])
+ m := len(v)
+ if m == 0 {
+ return s
+ }
+ n := len(s)
+ if i == n {
+ return append(s, v...)
+ }
+ if n+m > cap(s) {
+ // Use append rather than make so that we bump the size of
+ // the slice up to the next storage class.
+ // This is what Grow does but we don't call Grow because
+ // that might copy the values twice.
+ s2 := append(s[:i], make(S, n+m-i)...)
copy(s2[i:], v)
+ copy(s2[i+m:], s[i:])
return s2
}
- s2 := make(S, tot)
- copy(s2, s[:i])
- copy(s2[i:], v)
- copy(s2[i+len(v):], s[i:])
- return s2
+ s = s[:n+m]
+
+ // before:
+ // s: aaaaaaaabbbbccccccccdddd
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // after:
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ //
+ // a are the values that don't move in s.
+ // v are the values copied in from v.
+ // b and c are the values from s that are shifted up in index.
+ // d are the values that get overwritten, never to be seen again.
+
+ if !overlaps(v, s[i+m:]) {
+ // Easy case - v does not overlap either the c or d regions.
+ // (It might be in some of a or b, or elsewhere entirely.)
+ // The data we copy up doesn't write to v at all, so just do it.
+
+ copy(s[i+m:], s[i:])
+
+ // Now we have
+ // s: aaaaaaaabbbbbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // Note the b values are duplicated.
+
+ copy(s[i:], v)
+
+ // Now we have
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // That's the result we want.
+ return s
+ }
+
+ // The hard case - v overlaps c or d. We can't just shift up
+ // the data because we'd move or clobber the values we're trying
+ // to insert.
+ // So instead, write v on top of d, then rotate.
+ copy(s[n:], v)
+
+ // Now we have
+ // s: aaaaaaaabbbbccccccccvvvv
+ // ^ ^ ^ ^
+ // i i+m n n+m
+
+ rotateRight(s[i:], m)
+
+ // Now we have
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // That's the result we want.
+ return s
}
// Delete removes the elements s[i:j] from s, returning the modified slice.
// Delete panics if s[i:j] is not a valid slice of s.
-// Delete modifies the contents of the slice s; it does not create a new slice.
// Delete is O(len(s)-j), so if many items must be deleted, it is better to
// make a single call deleting them all together than to delete one at a time.
// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those
@@ -168,22 +222,113 @@ func Delete[S ~[]E, E any](s S, i, j int) S {
return append(s[:i], s[j:]...)
}
+// DeleteFunc removes any elements from s for which del returns true,
+// returning the modified slice.
+// When DeleteFunc removes m elements, it might not modify the elements
+// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
+// zeroing those elements so that objects they reference can be garbage
+// collected.
+func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
+ i := IndexFunc(s, del)
+ if i == -1 {
+ return s
+ }
+ // Don't start copying elements until we find one to delete.
+ for j := i + 1; j < len(s); j++ {
+ if v := s[j]; !del(v) {
+ s[i] = v
+ i++
+ }
+ }
+ return s[:i]
+}
+
// Replace replaces the elements s[i:j] by the given v, and returns the
// modified slice. Replace panics if s[i:j] is not a valid slice of s.
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
_ = s[i:j] // verify that i:j is a valid subslice
+
+ if i == j {
+ return Insert(s, i, v...)
+ }
+ if j == len(s) {
+ return append(s[:i], v...)
+ }
+
tot := len(s[:i]) + len(v) + len(s[j:])
- if tot <= cap(s) {
- s2 := s[:tot]
- copy(s2[i+len(v):], s[j:])
+ if tot > cap(s) {
+ // Too big to fit, allocate and copy over.
+ s2 := append(s[:i], make(S, tot-i)...) // See Insert
copy(s2[i:], v)
+ copy(s2[i+len(v):], s[j:])
return s2
}
- s2 := make(S, tot)
- copy(s2, s[:i])
- copy(s2[i:], v)
- copy(s2[i+len(v):], s[j:])
- return s2
+
+ r := s[:tot]
+
+ if i+len(v) <= j {
+ // Easy, as v fits in the deleted portion.
+ copy(r[i:], v)
+ if i+len(v) != j {
+ copy(r[i+len(v):], s[j:])
+ }
+ return r
+ }
+
+ // We are expanding (v is bigger than j-i).
+ // The situation is something like this:
+ // (example has i=4,j=8,len(s)=16,len(v)=6)
+ // s: aaaaxxxxbbbbbbbbyy
+ // ^ ^ ^ ^
+ // i j len(s) tot
+ // a: prefix of s
+ // x: deleted range
+ // b: more of s
+ // y: area to expand into
+
+ if !overlaps(r[i+len(v):], v) {
+ // Easy, as v is not clobbered by the first copy.
+ copy(r[i+len(v):], s[j:])
+ copy(r[i:], v)
+ return r
+ }
+
+ // This is a situation where we don't have a single place to which
+ // we can copy v. Parts of it need to go to two different places.
+ // We want to copy the prefix of v into y and the suffix into x, then
+ // rotate |y| spots to the right.
+ //
+ // v[2:] v[:2]
+ // | |
+ // s: aaaavvvvbbbbbbbbvv
+ // ^ ^ ^ ^
+ // i j len(s) tot
+ //
+ // If either of those two destinations don't alias v, then we're good.
+ y := len(v) - (j - i) // length of y portion
+
+ if !overlaps(r[i:j], v) {
+ copy(r[i:j], v[y:])
+ copy(r[len(s):], v[:y])
+ rotateRight(r[i:], y)
+ return r
+ }
+ if !overlaps(r[len(s):], v) {
+ copy(r[len(s):], v[:y])
+ copy(r[i:j], v[y:])
+ rotateRight(r[i:], y)
+ return r
+ }
+
+ // Now we know that v overlaps both x and y.
+ // That means that the entirety of b is *inside* v.
+ // So we don't need to preserve b at all; instead we
+ // can copy v first, then copy the b part of v out of
+ // v to the right destination.
+ k := startIdx(v, s[j:])
+ copy(r[i:], v)
+ copy(r[i+len(v):], r[i+k:])
+ return r
}
// Clone returns a copy of the slice.
@@ -198,7 +343,8 @@ func Clone[S ~[]E, E any](s S) S {
// Compact replaces consecutive runs of equal elements with a single copy.
// This is like the uniq command found on Unix.
-// Compact modifies the contents of the slice s; it does not create a new slice.
+// Compact modifies the contents of the slice s and returns the modified slice,
+// which may have a smaller length.
// When Compact discards m elements in total, it might not modify the elements
// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
// zeroing those elements so that objects they reference can be garbage collected.
@@ -218,7 +364,8 @@ func Compact[S ~[]E, E comparable](s S) S {
return s[:i]
}
-// CompactFunc is like Compact but uses a comparison function.
+// CompactFunc is like [Compact] but uses an equality function to compare elements.
+// For runs of elements that compare equal, CompactFunc keeps the first one.
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
if len(s) < 2 {
return s
@@ -256,3 +403,97 @@ func Grow[S ~[]E, E any](s S, n int) S {
func Clip[S ~[]E, E any](s S) S {
return s[:len(s):len(s)]
}
+
+// Rotation algorithm explanation:
+//
+// rotate left by 2
+// start with
+// 0123456789
+// split up like this
+// 01 234567 89
+// swap first 2 and last 2
+// 89 234567 01
+// join first parts
+// 89234567 01
+// recursively rotate first left part by 2
+// 23456789 01
+// join at the end
+// 2345678901
+//
+// rotate left by 8
+// start with
+// 0123456789
+// split up like this
+// 01 234567 89
+// swap first 2 and last 2
+// 89 234567 01
+// join last parts
+// 89 23456701
+// recursively rotate second part left by 6
+// 89 01234567
+// join at the end
+// 8901234567
+
+// TODO: There are other rotate algorithms.
+// This algorithm has the desirable property that it moves each element exactly twice.
+// The triple-reverse algorithm is simpler and more cache friendly, but takes more writes.
+// The follow-cycles algorithm can be 1-write but it is not very cache friendly.
+
+// rotateLeft rotates b left by n spaces.
+// s_final[i] = s_orig[i+r], wrapping around.
+func rotateLeft[E any](s []E, r int) {
+ for r != 0 && r != len(s) {
+ if r*2 <= len(s) {
+ swap(s[:r], s[len(s)-r:])
+ s = s[:len(s)-r]
+ } else {
+ swap(s[:len(s)-r], s[r:])
+ s, r = s[len(s)-r:], r*2-len(s)
+ }
+ }
+}
+func rotateRight[E any](s []E, r int) {
+ rotateLeft(s, len(s)-r)
+}
+
+// swap swaps the contents of x and y. x and y must be equal length and disjoint.
+func swap[E any](x, y []E) {
+ for i := 0; i < len(x); i++ {
+ x[i], y[i] = y[i], x[i]
+ }
+}
+
+// overlaps reports whether the memory ranges a[0:len(a)] and b[0:len(b)] overlap.
+func overlaps[E any](a, b []E) bool {
+ if len(a) == 0 || len(b) == 0 {
+ return false
+ }
+ elemSize := unsafe.Sizeof(a[0])
+ if elemSize == 0 {
+ return false
+ }
+ // TODO: use a runtime/unsafe facility once one becomes available. See issue 12445.
+ // Also see crypto/internal/alias/alias.go:AnyOverlap
+ return uintptr(unsafe.Pointer(&a[0])) <= uintptr(unsafe.Pointer(&b[len(b)-1]))+(elemSize-1) &&
+ uintptr(unsafe.Pointer(&b[0])) <= uintptr(unsafe.Pointer(&a[len(a)-1]))+(elemSize-1)
+}
+
+// startIdx returns the index in haystack where the needle starts.
+// prerequisite: the needle must be aliased entirely inside the haystack.
+func startIdx[E any](haystack, needle []E) int {
+ p := &needle[0]
+ for i := range haystack {
+ if p == &haystack[i] {
+ return i
+ }
+ }
+ // TODO: what if the overlap is by a non-integral number of Es?
+ panic("needle not found")
+}
+
+// Reverse reverses the elements of the slice in place.
+func Reverse[S ~[]E, E any](s S) {
+ for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
+ s[i], s[j] = s[j], s[i]
+ }
+}
diff --git a/vendor/golang.org/x/exp/slices/sort.go b/vendor/golang.org/x/exp/slices/sort.go
index 231b6448acd..b67897f76b5 100644
--- a/vendor/golang.org/x/exp/slices/sort.go
+++ b/vendor/golang.org/x/exp/slices/sort.go
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:generate go run $GOROOT/src/sort/gen_sort_variants.go -exp
+
package slices
import (
@@ -11,57 +13,116 @@ import (
)
// Sort sorts a slice of any ordered type in ascending order.
-// Sort may fail to sort correctly when sorting slices of floating-point
-// numbers containing Not-a-number (NaN) values.
-// Use slices.SortFunc(x, func(a, b float64) bool {return a < b || (math.IsNaN(a) && !math.IsNaN(b))})
-// instead if the input may contain NaNs.
-func Sort[E constraints.Ordered](x []E) {
+// When sorting floating-point numbers, NaNs are ordered before other values.
+func Sort[S ~[]E, E constraints.Ordered](x S) {
n := len(x)
pdqsortOrdered(x, 0, n, bits.Len(uint(n)))
}
-// SortFunc sorts the slice x in ascending order as determined by the less function.
-// This sort is not guaranteed to be stable.
+// SortFunc sorts the slice x in ascending order as determined by the cmp
+// function. This sort is not guaranteed to be stable.
+// cmp(a, b) should return a negative number when a < b, a positive number when
+// a > b and zero when a == b.
//
-// SortFunc requires that less is a strict weak ordering.
+// SortFunc requires that cmp is a strict weak ordering.
// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
-func SortFunc[E any](x []E, less func(a, b E) bool) {
+func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
n := len(x)
- pdqsortLessFunc(x, 0, n, bits.Len(uint(n)), less)
+ pdqsortCmpFunc(x, 0, n, bits.Len(uint(n)), cmp)
}
// SortStableFunc sorts the slice x while keeping the original order of equal
-// elements, using less to compare elements.
-func SortStableFunc[E any](x []E, less func(a, b E) bool) {
- stableLessFunc(x, len(x), less)
+// elements, using cmp to compare elements in the same way as [SortFunc].
+func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
+ stableCmpFunc(x, len(x), cmp)
}
// IsSorted reports whether x is sorted in ascending order.
-func IsSorted[E constraints.Ordered](x []E) bool {
+func IsSorted[S ~[]E, E constraints.Ordered](x S) bool {
for i := len(x) - 1; i > 0; i-- {
- if x[i] < x[i-1] {
+ if cmpLess(x[i], x[i-1]) {
return false
}
}
return true
}
-// IsSortedFunc reports whether x is sorted in ascending order, with less as the
-// comparison function.
-func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool {
+// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
+// comparison function as defined by [SortFunc].
+func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
for i := len(x) - 1; i > 0; i-- {
- if less(x[i], x[i-1]) {
+ if cmp(x[i], x[i-1]) < 0 {
return false
}
}
return true
}
+// Min returns the minimal value in x. It panics if x is empty.
+// For floating-point numbers, Min propagates NaNs (any NaN value in x
+// forces the output to be NaN).
+func Min[S ~[]E, E constraints.Ordered](x S) E {
+ if len(x) < 1 {
+ panic("slices.Min: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ m = min(m, x[i])
+ }
+ return m
+}
+
+// MinFunc returns the minimal value in x, using cmp to compare elements.
+// It panics if x is empty. If there is more than one minimal element
+// according to the cmp function, MinFunc returns the first one.
+func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
+ if len(x) < 1 {
+ panic("slices.MinFunc: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ if cmp(x[i], m) < 0 {
+ m = x[i]
+ }
+ }
+ return m
+}
+
+// Max returns the maximal value in x. It panics if x is empty.
+// For floating-point E, Max propagates NaNs (any NaN value in x
+// forces the output to be NaN).
+func Max[S ~[]E, E constraints.Ordered](x S) E {
+ if len(x) < 1 {
+ panic("slices.Max: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ m = max(m, x[i])
+ }
+ return m
+}
+
+// MaxFunc returns the maximal value in x, using cmp to compare elements.
+// It panics if x is empty. If there is more than one maximal element
+// according to the cmp function, MaxFunc returns the first one.
+func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
+ if len(x) < 1 {
+ panic("slices.MaxFunc: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ if cmp(x[i], m) > 0 {
+ m = x[i]
+ }
+ }
+ return m
+}
+
// BinarySearch searches for target in a sorted slice and returns the position
// where target is found, or the position where target would appear in the
// sort order; it also returns a bool saying whether the target is really found
// in the slice. The slice must be sorted in increasing order.
-func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) {
+func BinarySearch[S ~[]E, E constraints.Ordered](x S, target E) (int, bool) {
// Inlining is faster than calling BinarySearchFunc with a lambda.
n := len(x)
// Define x[-1] < target and x[n] >= target.
@@ -70,24 +131,24 @@ func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) {
for i < j {
h := int(uint(i+j) >> 1) // avoid overflow when computing h
// i ≤ h < j
- if x[h] < target {
+ if cmpLess(x[h], target) {
i = h + 1 // preserves x[i-1] < target
} else {
j = h // preserves x[j] >= target
}
}
// i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i.
- return i, i < n && x[i] == target
+ return i, i < n && (x[i] == target || (isNaN(x[i]) && isNaN(target)))
}
-// BinarySearchFunc works like BinarySearch, but uses a custom comparison
+// BinarySearchFunc works like [BinarySearch], but uses a custom comparison
// function. The slice must be sorted in increasing order, where "increasing"
// is defined by cmp. cmp should return 0 if the slice element matches
// the target, a negative number if the slice element precedes the target,
// or a positive number if the slice element follows the target.
// cmp must implement the same ordering as the slice, such that if
// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
-func BinarySearchFunc[E, T any](x []E, target T, cmp func(E, T) int) (int, bool) {
+func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
n := len(x)
// Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 .
// Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0.
@@ -126,3 +187,9 @@ func (r *xorshift) Next() uint64 {
func nextPowerOfTwo(length int) uint {
return 1 << bits.Len(uint(length))
}
+
+// isNaN reports whether x is a NaN without requiring the math package.
+// This will always return false if T is not floating-point.
+func isNaN[T constraints.Ordered](x T) bool {
+ return x != x
+}
diff --git a/vendor/golang.org/x/exp/slices/zsortfunc.go b/vendor/golang.org/x/exp/slices/zsortanyfunc.go
similarity index 64%
rename from vendor/golang.org/x/exp/slices/zsortfunc.go
rename to vendor/golang.org/x/exp/slices/zsortanyfunc.go
index 2a632476c50..06f2c7a2481 100644
--- a/vendor/golang.org/x/exp/slices/zsortfunc.go
+++ b/vendor/golang.org/x/exp/slices/zsortanyfunc.go
@@ -6,28 +6,28 @@
package slices
-// insertionSortLessFunc sorts data[a:b] using insertion sort.
-func insertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+// insertionSortCmpFunc sorts data[a:b] using insertion sort.
+func insertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
for i := a + 1; i < b; i++ {
- for j := i; j > a && less(data[j], data[j-1]); j-- {
+ for j := i; j > a && (cmp(data[j], data[j-1]) < 0); j-- {
data[j], data[j-1] = data[j-1], data[j]
}
}
}
-// siftDownLessFunc implements the heap property on data[lo:hi].
+// siftDownCmpFunc implements the heap property on data[lo:hi].
// first is an offset into the array where the root of the heap lies.
-func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool) {
+func siftDownCmpFunc[E any](data []E, lo, hi, first int, cmp func(a, b E) int) {
root := lo
for {
child := 2*root + 1
if child >= hi {
break
}
- if child+1 < hi && less(data[first+child], data[first+child+1]) {
+ if child+1 < hi && (cmp(data[first+child], data[first+child+1]) < 0) {
child++
}
- if !less(data[first+root], data[first+child]) {
+ if !(cmp(data[first+root], data[first+child]) < 0) {
return
}
data[first+root], data[first+child] = data[first+child], data[first+root]
@@ -35,30 +35,30 @@ func siftDownLessFunc[E any](data []E, lo, hi, first int, less func(a, b E) bool
}
}
-func heapSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+func heapSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
first := a
lo := 0
hi := b - a
// Build heap with greatest element at top.
for i := (hi - 1) / 2; i >= 0; i-- {
- siftDownLessFunc(data, i, hi, first, less)
+ siftDownCmpFunc(data, i, hi, first, cmp)
}
// Pop elements, largest first, into end of data.
for i := hi - 1; i >= 0; i-- {
data[first], data[first+i] = data[first+i], data[first]
- siftDownLessFunc(data, lo, i, first, less)
+ siftDownCmpFunc(data, lo, i, first, cmp)
}
}
-// pdqsortLessFunc sorts data[a:b].
+// pdqsortCmpFunc sorts data[a:b].
// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort.
// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf
// C++ implementation: https://github.com/orlp/pdqsort
// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/
// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort.
-func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
+func pdqsortCmpFunc[E any](data []E, a, b, limit int, cmp func(a, b E) int) {
const maxInsertion = 12
var (
@@ -70,25 +70,25 @@ func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
length := b - a
if length <= maxInsertion {
- insertionSortLessFunc(data, a, b, less)
+ insertionSortCmpFunc(data, a, b, cmp)
return
}
// Fall back to heapsort if too many bad choices were made.
if limit == 0 {
- heapSortLessFunc(data, a, b, less)
+ heapSortCmpFunc(data, a, b, cmp)
return
}
// If the last partitioning was imbalanced, we need to breaking patterns.
if !wasBalanced {
- breakPatternsLessFunc(data, a, b, less)
+ breakPatternsCmpFunc(data, a, b, cmp)
limit--
}
- pivot, hint := choosePivotLessFunc(data, a, b, less)
+ pivot, hint := choosePivotCmpFunc(data, a, b, cmp)
if hint == decreasingHint {
- reverseRangeLessFunc(data, a, b, less)
+ reverseRangeCmpFunc(data, a, b, cmp)
// The chosen pivot was pivot-a elements after the start of the array.
// After reversing it is pivot-a elements before the end of the array.
// The idea came from Rust's implementation.
@@ -98,48 +98,48 @@ func pdqsortLessFunc[E any](data []E, a, b, limit int, less func(a, b E) bool) {
// The slice is likely already sorted.
if wasBalanced && wasPartitioned && hint == increasingHint {
- if partialInsertionSortLessFunc(data, a, b, less) {
+ if partialInsertionSortCmpFunc(data, a, b, cmp) {
return
}
}
// Probably the slice contains many duplicate elements, partition the slice into
// elements equal to and elements greater than the pivot.
- if a > 0 && !less(data[a-1], data[pivot]) {
- mid := partitionEqualLessFunc(data, a, b, pivot, less)
+ if a > 0 && !(cmp(data[a-1], data[pivot]) < 0) {
+ mid := partitionEqualCmpFunc(data, a, b, pivot, cmp)
a = mid
continue
}
- mid, alreadyPartitioned := partitionLessFunc(data, a, b, pivot, less)
+ mid, alreadyPartitioned := partitionCmpFunc(data, a, b, pivot, cmp)
wasPartitioned = alreadyPartitioned
leftLen, rightLen := mid-a, b-mid
balanceThreshold := length / 8
if leftLen < rightLen {
wasBalanced = leftLen >= balanceThreshold
- pdqsortLessFunc(data, a, mid, limit, less)
+ pdqsortCmpFunc(data, a, mid, limit, cmp)
a = mid + 1
} else {
wasBalanced = rightLen >= balanceThreshold
- pdqsortLessFunc(data, mid+1, b, limit, less)
+ pdqsortCmpFunc(data, mid+1, b, limit, cmp)
b = mid
}
}
}
-// partitionLessFunc does one quicksort partition.
+// partitionCmpFunc does one quicksort partition.
// Let p = data[pivot]
// Moves elements in data[a:b] around, so that data[i]=p for inewpivot.
// On return, data[newpivot] = p
-func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int, alreadyPartitioned bool) {
+func partitionCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int, alreadyPartitioned bool) {
data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
- for i <= j && less(data[i], data[a]) {
+ for i <= j && (cmp(data[i], data[a]) < 0) {
i++
}
- for i <= j && !less(data[j], data[a]) {
+ for i <= j && !(cmp(data[j], data[a]) < 0) {
j--
}
if i > j {
@@ -151,10 +151,10 @@ func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool)
j--
for {
- for i <= j && less(data[i], data[a]) {
+ for i <= j && (cmp(data[i], data[a]) < 0) {
i++
}
- for i <= j && !less(data[j], data[a]) {
+ for i <= j && !(cmp(data[j], data[a]) < 0) {
j--
}
if i > j {
@@ -168,17 +168,17 @@ func partitionLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool)
return j, false
}
-// partitionEqualLessFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot].
+// partitionEqualCmpFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot].
// It assumed that data[a:b] does not contain elements smaller than the data[pivot].
-func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E) bool) (newpivot int) {
+func partitionEqualCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int) {
data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for {
- for i <= j && !less(data[a], data[i]) {
+ for i <= j && !(cmp(data[a], data[i]) < 0) {
i++
}
- for i <= j && less(data[a], data[j]) {
+ for i <= j && (cmp(data[a], data[j]) < 0) {
j--
}
if i > j {
@@ -191,15 +191,15 @@ func partitionEqualLessFunc[E any](data []E, a, b, pivot int, less func(a, b E)
return i
}
-// partialInsertionSortLessFunc partially sorts a slice, returns true if the slice is sorted at the end.
-func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) bool) bool {
+// partialInsertionSortCmpFunc partially sorts a slice, returns true if the slice is sorted at the end.
+func partialInsertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) bool {
const (
maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted
shortestShifting = 50 // don't shift any elements on short arrays
)
i := a + 1
for j := 0; j < maxSteps; j++ {
- for i < b && !less(data[i], data[i-1]) {
+ for i < b && !(cmp(data[i], data[i-1]) < 0) {
i++
}
@@ -216,7 +216,7 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
// Shift the smaller one to the left.
if i-a >= 2 {
for j := i - 1; j >= 1; j-- {
- if !less(data[j], data[j-1]) {
+ if !(cmp(data[j], data[j-1]) < 0) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -225,7 +225,7 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
// Shift the greater one to the right.
if b-i >= 2 {
for j := i + 1; j < b; j++ {
- if !less(data[j], data[j-1]) {
+ if !(cmp(data[j], data[j-1]) < 0) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -235,9 +235,9 @@ func partialInsertionSortLessFunc[E any](data []E, a, b int, less func(a, b E) b
return false
}
-// breakPatternsLessFunc scatters some elements around in an attempt to break some patterns
+// breakPatternsCmpFunc scatters some elements around in an attempt to break some patterns
// that might cause imbalanced partitions in quicksort.
-func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+func breakPatternsCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
length := b - a
if length >= 8 {
random := xorshift(length)
@@ -253,12 +253,12 @@ func breakPatternsLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
}
}
-// choosePivotLessFunc chooses a pivot in data[a:b].
+// choosePivotCmpFunc chooses a pivot in data[a:b].
//
// [0,8): chooses a static pivot.
// [8,shortestNinther): uses the simple median-of-three method.
// [shortestNinther,∞): uses the Tukey ninther method.
-func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (pivot int, hint sortedHint) {
+func choosePivotCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) (pivot int, hint sortedHint) {
const (
shortestNinther = 50
maxSwaps = 4 * 3
@@ -276,12 +276,12 @@ func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (piv
if l >= 8 {
if l >= shortestNinther {
// Tukey ninther method, the idea came from Rust's implementation.
- i = medianAdjacentLessFunc(data, i, &swaps, less)
- j = medianAdjacentLessFunc(data, j, &swaps, less)
- k = medianAdjacentLessFunc(data, k, &swaps, less)
+ i = medianAdjacentCmpFunc(data, i, &swaps, cmp)
+ j = medianAdjacentCmpFunc(data, j, &swaps, cmp)
+ k = medianAdjacentCmpFunc(data, k, &swaps, cmp)
}
// Find the median among i, j, k and stores it into j.
- j = medianLessFunc(data, i, j, k, &swaps, less)
+ j = medianCmpFunc(data, i, j, k, &swaps, cmp)
}
switch swaps {
@@ -294,29 +294,29 @@ func choosePivotLessFunc[E any](data []E, a, b int, less func(a, b E) bool) (piv
}
}
-// order2LessFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
-func order2LessFunc[E any](data []E, a, b int, swaps *int, less func(a, b E) bool) (int, int) {
- if less(data[b], data[a]) {
+// order2CmpFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
+func order2CmpFunc[E any](data []E, a, b int, swaps *int, cmp func(a, b E) int) (int, int) {
+ if cmp(data[b], data[a]) < 0 {
*swaps++
return b, a
}
return a, b
}
-// medianLessFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c.
-func medianLessFunc[E any](data []E, a, b, c int, swaps *int, less func(a, b E) bool) int {
- a, b = order2LessFunc(data, a, b, swaps, less)
- b, c = order2LessFunc(data, b, c, swaps, less)
- a, b = order2LessFunc(data, a, b, swaps, less)
+// medianCmpFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c.
+func medianCmpFunc[E any](data []E, a, b, c int, swaps *int, cmp func(a, b E) int) int {
+ a, b = order2CmpFunc(data, a, b, swaps, cmp)
+ b, c = order2CmpFunc(data, b, c, swaps, cmp)
+ a, b = order2CmpFunc(data, a, b, swaps, cmp)
return b
}
-// medianAdjacentLessFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a.
-func medianAdjacentLessFunc[E any](data []E, a int, swaps *int, less func(a, b E) bool) int {
- return medianLessFunc(data, a-1, a, a+1, swaps, less)
+// medianAdjacentCmpFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a.
+func medianAdjacentCmpFunc[E any](data []E, a int, swaps *int, cmp func(a, b E) int) int {
+ return medianCmpFunc(data, a-1, a, a+1, swaps, cmp)
}
-func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
+func reverseRangeCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
i := a
j := b - 1
for i < j {
@@ -326,37 +326,37 @@ func reverseRangeLessFunc[E any](data []E, a, b int, less func(a, b E) bool) {
}
}
-func swapRangeLessFunc[E any](data []E, a, b, n int, less func(a, b E) bool) {
+func swapRangeCmpFunc[E any](data []E, a, b, n int, cmp func(a, b E) int) {
for i := 0; i < n; i++ {
data[a+i], data[b+i] = data[b+i], data[a+i]
}
}
-func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) {
+func stableCmpFunc[E any](data []E, n int, cmp func(a, b E) int) {
blockSize := 20 // must be > 0
a, b := 0, blockSize
for b <= n {
- insertionSortLessFunc(data, a, b, less)
+ insertionSortCmpFunc(data, a, b, cmp)
a = b
b += blockSize
}
- insertionSortLessFunc(data, a, n, less)
+ insertionSortCmpFunc(data, a, n, cmp)
for blockSize < n {
a, b = 0, 2*blockSize
for b <= n {
- symMergeLessFunc(data, a, a+blockSize, b, less)
+ symMergeCmpFunc(data, a, a+blockSize, b, cmp)
a = b
b += 2 * blockSize
}
if m := a + blockSize; m < n {
- symMergeLessFunc(data, a, m, n, less)
+ symMergeCmpFunc(data, a, m, n, cmp)
}
blockSize *= 2
}
}
-// symMergeLessFunc merges the two sorted subsequences data[a:m] and data[m:b] using
+// symMergeCmpFunc merges the two sorted subsequences data[a:m] and data[m:b] using
// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum
// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz
// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in
@@ -375,7 +375,7 @@ func stableLessFunc[E any](data []E, n int, less func(a, b E) bool) {
// symMerge assumes non-degenerate arguments: a < m && m < b.
// Having the caller check this condition eliminates many leaf recursion calls,
// which improves performance.
-func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
+func symMergeCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
// Avoid unnecessary recursions of symMerge
// by direct insertion of data[a] into data[m:b]
// if data[a:m] only contains one element.
@@ -387,7 +387,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
j := b
for i < j {
h := int(uint(i+j) >> 1)
- if less(data[h], data[a]) {
+ if cmp(data[h], data[a]) < 0 {
i = h + 1
} else {
j = h
@@ -411,7 +411,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
j := m
for i < j {
h := int(uint(i+j) >> 1)
- if !less(data[m], data[h]) {
+ if !(cmp(data[m], data[h]) < 0) {
i = h + 1
} else {
j = h
@@ -438,7 +438,7 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
for start < r {
c := int(uint(start+r) >> 1)
- if !less(data[p-c], data[c]) {
+ if !(cmp(data[p-c], data[c]) < 0) {
start = c + 1
} else {
r = c
@@ -447,33 +447,33 @@ func symMergeLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
end := n - start
if start < m && m < end {
- rotateLessFunc(data, start, m, end, less)
+ rotateCmpFunc(data, start, m, end, cmp)
}
if a < start && start < mid {
- symMergeLessFunc(data, a, start, mid, less)
+ symMergeCmpFunc(data, a, start, mid, cmp)
}
if mid < end && end < b {
- symMergeLessFunc(data, mid, end, b, less)
+ symMergeCmpFunc(data, mid, end, b, cmp)
}
}
-// rotateLessFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
+// rotateCmpFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
// Data of the form 'x u v y' is changed to 'x v u y'.
// rotate performs at most b-a many calls to data.Swap,
// and it assumes non-degenerate arguments: a < m && m < b.
-func rotateLessFunc[E any](data []E, a, m, b int, less func(a, b E) bool) {
+func rotateCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
i := m - a
j := b - m
for i != j {
if i > j {
- swapRangeLessFunc(data, m-i, m, j, less)
+ swapRangeCmpFunc(data, m-i, m, j, cmp)
i -= j
} else {
- swapRangeLessFunc(data, m-i, m+j-i, i, less)
+ swapRangeCmpFunc(data, m-i, m+j-i, i, cmp)
j -= i
}
}
// i == j
- swapRangeLessFunc(data, m-i, m, i, less)
+ swapRangeCmpFunc(data, m-i, m, i, cmp)
}
diff --git a/vendor/golang.org/x/exp/slices/zsortordered.go b/vendor/golang.org/x/exp/slices/zsortordered.go
index efaa1c8b714..99b47c3986a 100644
--- a/vendor/golang.org/x/exp/slices/zsortordered.go
+++ b/vendor/golang.org/x/exp/slices/zsortordered.go
@@ -11,7 +11,7 @@ import "golang.org/x/exp/constraints"
// insertionSortOrdered sorts data[a:b] using insertion sort.
func insertionSortOrdered[E constraints.Ordered](data []E, a, b int) {
for i := a + 1; i < b; i++ {
- for j := i; j > a && (data[j] < data[j-1]); j-- {
+ for j := i; j > a && cmpLess(data[j], data[j-1]); j-- {
data[j], data[j-1] = data[j-1], data[j]
}
}
@@ -26,10 +26,10 @@ func siftDownOrdered[E constraints.Ordered](data []E, lo, hi, first int) {
if child >= hi {
break
}
- if child+1 < hi && (data[first+child] < data[first+child+1]) {
+ if child+1 < hi && cmpLess(data[first+child], data[first+child+1]) {
child++
}
- if !(data[first+root] < data[first+child]) {
+ if !cmpLess(data[first+root], data[first+child]) {
return
}
data[first+root], data[first+child] = data[first+child], data[first+root]
@@ -107,7 +107,7 @@ func pdqsortOrdered[E constraints.Ordered](data []E, a, b, limit int) {
// Probably the slice contains many duplicate elements, partition the slice into
// elements equal to and elements greater than the pivot.
- if a > 0 && !(data[a-1] < data[pivot]) {
+ if a > 0 && !cmpLess(data[a-1], data[pivot]) {
mid := partitionEqualOrdered(data, a, b, pivot)
a = mid
continue
@@ -138,10 +138,10 @@ func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivo
data[a], data[pivot] = data[pivot], data[a]
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
- for i <= j && (data[i] < data[a]) {
+ for i <= j && cmpLess(data[i], data[a]) {
i++
}
- for i <= j && !(data[j] < data[a]) {
+ for i <= j && !cmpLess(data[j], data[a]) {
j--
}
if i > j {
@@ -153,10 +153,10 @@ func partitionOrdered[E constraints.Ordered](data []E, a, b, pivot int) (newpivo
j--
for {
- for i <= j && (data[i] < data[a]) {
+ for i <= j && cmpLess(data[i], data[a]) {
i++
}
- for i <= j && !(data[j] < data[a]) {
+ for i <= j && !cmpLess(data[j], data[a]) {
j--
}
if i > j {
@@ -177,10 +177,10 @@ func partitionEqualOrdered[E constraints.Ordered](data []E, a, b, pivot int) (ne
i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
for {
- for i <= j && !(data[a] < data[i]) {
+ for i <= j && !cmpLess(data[a], data[i]) {
i++
}
- for i <= j && (data[a] < data[j]) {
+ for i <= j && cmpLess(data[a], data[j]) {
j--
}
if i > j {
@@ -201,7 +201,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
)
i := a + 1
for j := 0; j < maxSteps; j++ {
- for i < b && !(data[i] < data[i-1]) {
+ for i < b && !cmpLess(data[i], data[i-1]) {
i++
}
@@ -218,7 +218,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
// Shift the smaller one to the left.
if i-a >= 2 {
for j := i - 1; j >= 1; j-- {
- if !(data[j] < data[j-1]) {
+ if !cmpLess(data[j], data[j-1]) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -227,7 +227,7 @@ func partialInsertionSortOrdered[E constraints.Ordered](data []E, a, b int) bool
// Shift the greater one to the right.
if b-i >= 2 {
for j := i + 1; j < b; j++ {
- if !(data[j] < data[j-1]) {
+ if !cmpLess(data[j], data[j-1]) {
break
}
data[j], data[j-1] = data[j-1], data[j]
@@ -298,7 +298,7 @@ func choosePivotOrdered[E constraints.Ordered](data []E, a, b int) (pivot int, h
// order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
func order2Ordered[E constraints.Ordered](data []E, a, b int, swaps *int) (int, int) {
- if data[b] < data[a] {
+ if cmpLess(data[b], data[a]) {
*swaps++
return b, a
}
@@ -389,7 +389,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
j := b
for i < j {
h := int(uint(i+j) >> 1)
- if data[h] < data[a] {
+ if cmpLess(data[h], data[a]) {
i = h + 1
} else {
j = h
@@ -413,7 +413,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
j := m
for i < j {
h := int(uint(i+j) >> 1)
- if !(data[m] < data[h]) {
+ if !cmpLess(data[m], data[h]) {
i = h + 1
} else {
j = h
@@ -440,7 +440,7 @@ func symMergeOrdered[E constraints.Ordered](data []E, a, m, b int) {
for start < r {
c := int(uint(start+r) >> 1)
- if !(data[p-c] < data[c]) {
+ if !cmpLess(data[p-c], data[c]) {
start = c + 1
} else {
r = c
diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go
index 6f2df281872..003e649f30c 100644
--- a/vendor/golang.org/x/net/http2/http2.go
+++ b/vendor/golang.org/x/net/http2/http2.go
@@ -17,6 +17,7 @@ package http2 // import "golang.org/x/net/http2"
import (
"bufio"
+ "context"
"crypto/tls"
"fmt"
"io"
@@ -26,6 +27,7 @@ import (
"strconv"
"strings"
"sync"
+ "time"
"golang.org/x/net/http/httpguts"
)
@@ -210,12 +212,6 @@ type stringWriter interface {
WriteString(s string) (n int, err error)
}
-// A gate lets two goroutines coordinate their activities.
-type gate chan struct{}
-
-func (g gate) Done() { g <- struct{}{} }
-func (g gate) Wait() { <-g }
-
// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
type closeWaiter chan struct{}
@@ -383,3 +379,14 @@ func validPseudoPath(v string) bool {
// makes that struct also non-comparable, and generally doesn't add
// any size (as long as it's first).
type incomparable [0]func()
+
+// synctestGroupInterface is the methods of synctestGroup used by Server and Transport.
+// It's defined as an interface here to let us keep synctestGroup entirely test-only
+// and not a part of non-test builds.
+type synctestGroupInterface interface {
+ Join()
+ Now() time.Time
+ NewTimer(d time.Duration) timer
+ AfterFunc(d time.Duration, f func()) timer
+ ContextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc)
+}
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index c5d08108137..6c349f3ec64 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -154,6 +154,39 @@ type Server struct {
// so that we don't embed a Mutex in this struct, which will make the
// struct non-copyable, which might break some callers.
state *serverInternalState
+
+ // Synchronization group used for testing.
+ // Outside of tests, this is nil.
+ group synctestGroupInterface
+}
+
+func (s *Server) markNewGoroutine() {
+ if s.group != nil {
+ s.group.Join()
+ }
+}
+
+func (s *Server) now() time.Time {
+ if s.group != nil {
+ return s.group.Now()
+ }
+ return time.Now()
+}
+
+// newTimer creates a new time.Timer, or a synthetic timer in tests.
+func (s *Server) newTimer(d time.Duration) timer {
+ if s.group != nil {
+ return s.group.NewTimer(d)
+ }
+ return timeTimer{time.NewTimer(d)}
+}
+
+// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
+func (s *Server) afterFunc(d time.Duration, f func()) timer {
+ if s.group != nil {
+ return s.group.AfterFunc(d, f)
+ }
+ return timeTimer{time.AfterFunc(d, f)}
}
func (s *Server) initialConnRecvWindowSize() int32 {
@@ -400,6 +433,10 @@ func (o *ServeConnOpts) handler() http.Handler {
//
// The opts parameter is optional. If nil, default values are used.
func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
+ s.serveConn(c, opts, nil)
+}
+
+func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverConn)) {
baseCtx, cancel := serverConnBaseContext(c, opts)
defer cancel()
@@ -426,6 +463,9 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
pushEnabled: true,
sawClientPreface: opts.SawClientPreface,
}
+ if newf != nil {
+ newf(sc)
+ }
s.state.registerConn(sc)
defer s.state.unregisterConn(sc)
@@ -599,8 +639,8 @@ type serverConn struct {
inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
needToSendGoAway bool // we need to schedule a GOAWAY frame write
goAwayCode ErrCode
- shutdownTimer *time.Timer // nil until used
- idleTimer *time.Timer // nil if unused
+ shutdownTimer timer // nil until used
+ idleTimer timer // nil if unused
// Owned by the writeFrameAsync goroutine:
headerWriteBuf bytes.Buffer
@@ -649,12 +689,12 @@ type stream struct {
flow outflow // limits writing from Handler to client
inflow inflow // what the client is allowed to POST/etc to us
state streamState
- resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
- gotTrailerHeader bool // HEADER frame for trailers was seen
- wroteHeaders bool // whether we wrote headers (not status 100)
- readDeadline *time.Timer // nil if unused
- writeDeadline *time.Timer // nil if unused
- closeErr error // set before cw is closed
+ resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
+ gotTrailerHeader bool // HEADER frame for trailers was seen
+ wroteHeaders bool // whether we wrote headers (not status 100)
+ readDeadline timer // nil if unused
+ writeDeadline timer // nil if unused
+ closeErr error // set before cw is closed
trailer http.Header // accumulated trailers
reqTrailer http.Header // handler's Request.Trailer
@@ -811,8 +851,9 @@ type readFrameResult struct {
// consumer is done with the frame.
// It's run on its own goroutine.
func (sc *serverConn) readFrames() {
- gate := make(gate)
- gateDone := gate.Done
+ sc.srv.markNewGoroutine()
+ gate := make(chan struct{})
+ gateDone := func() { gate <- struct{}{} }
for {
f, err := sc.framer.ReadFrame()
select {
@@ -843,6 +884,7 @@ type frameWriteResult struct {
// At most one goroutine can be running writeFrameAsync at a time per
// serverConn.
func (sc *serverConn) writeFrameAsync(wr FrameWriteRequest, wd *writeData) {
+ sc.srv.markNewGoroutine()
var err error
if wd == nil {
err = wr.write.writeFrame(sc)
@@ -922,13 +964,13 @@ func (sc *serverConn) serve() {
sc.setConnState(http.StateIdle)
if sc.srv.IdleTimeout > 0 {
- sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
+ sc.idleTimer = sc.srv.afterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
defer sc.idleTimer.Stop()
}
go sc.readFrames() // closed by defer sc.conn.Close above
- settingsTimer := time.AfterFunc(firstSettingsTimeout, sc.onSettingsTimer)
+ settingsTimer := sc.srv.afterFunc(firstSettingsTimeout, sc.onSettingsTimer)
defer settingsTimer.Stop()
loopNum := 0
@@ -1057,10 +1099,10 @@ func (sc *serverConn) readPreface() error {
errc <- nil
}
}()
- timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server?
+ timer := sc.srv.newTimer(prefaceTimeout) // TODO: configurable on *Server?
defer timer.Stop()
select {
- case <-timer.C:
+ case <-timer.C():
return errPrefaceTimeout
case err := <-errc:
if err == nil {
@@ -1425,7 +1467,7 @@ func (sc *serverConn) goAway(code ErrCode) {
func (sc *serverConn) shutDownIn(d time.Duration) {
sc.serveG.check()
- sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
+ sc.shutdownTimer = sc.srv.afterFunc(d, sc.onShutdownTimer)
}
func (sc *serverConn) resetStream(se StreamError) {
@@ -1639,7 +1681,7 @@ func (sc *serverConn) closeStream(st *stream, err error) {
delete(sc.streams, st.id)
if len(sc.streams) == 0 {
sc.setConnState(http.StateIdle)
- if sc.srv.IdleTimeout > 0 {
+ if sc.srv.IdleTimeout > 0 && sc.idleTimer != nil {
sc.idleTimer.Reset(sc.srv.IdleTimeout)
}
if h1ServerKeepAlivesDisabled(sc.hs) {
@@ -1661,6 +1703,7 @@ func (sc *serverConn) closeStream(st *stream, err error) {
}
}
st.closeErr = err
+ st.cancelCtx()
st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
sc.writeSched.CloseStream(st.id)
}
@@ -2021,7 +2064,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
// (in Go 1.8), though. That's a more sane option anyway.
if sc.hs.ReadTimeout > 0 {
sc.conn.SetReadDeadline(time.Time{})
- st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
+ st.readDeadline = sc.srv.afterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
}
return sc.scheduleHandler(id, rw, req, handler)
@@ -2119,7 +2162,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
st.flow.add(sc.initialStreamSendWindowSize)
st.inflow.init(sc.srv.initialStreamRecvWindowSize())
if sc.hs.WriteTimeout > 0 {
- st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
+ st.writeDeadline = sc.srv.afterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
}
sc.streams[id] = st
@@ -2343,6 +2386,7 @@ func (sc *serverConn) handlerDone() {
// Run on its own goroutine.
func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) {
+ sc.srv.markNewGoroutine()
defer sc.sendServeMsg(handlerDoneMsg)
didPanic := true
defer func() {
@@ -2639,7 +2683,7 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) {
var date string
if _, ok := rws.snapHeader["Date"]; !ok {
// TODO(bradfitz): be faster here, like net/http? measure.
- date = time.Now().UTC().Format(http.TimeFormat)
+ date = rws.conn.srv.now().UTC().Format(http.TimeFormat)
}
for _, v := range rws.snapHeader["Trailer"] {
@@ -2761,7 +2805,7 @@ func (rws *responseWriterState) promoteUndeclaredTrailers() {
func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
st := w.rws.stream
- if !deadline.IsZero() && deadline.Before(time.Now()) {
+ if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
// If we're setting a deadline in the past, reset the stream immediately
// so writes after SetWriteDeadline returns will fail.
st.onReadTimeout()
@@ -2777,9 +2821,9 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
if deadline.IsZero() {
st.readDeadline = nil
} else if st.readDeadline == nil {
- st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
+ st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout)
} else {
- st.readDeadline.Reset(deadline.Sub(time.Now()))
+ st.readDeadline.Reset(deadline.Sub(sc.srv.now()))
}
})
return nil
@@ -2787,7 +2831,7 @@ func (w *responseWriter) SetReadDeadline(deadline time.Time) error {
func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
st := w.rws.stream
- if !deadline.IsZero() && deadline.Before(time.Now()) {
+ if !deadline.IsZero() && deadline.Before(w.rws.conn.srv.now()) {
// If we're setting a deadline in the past, reset the stream immediately
// so writes after SetWriteDeadline returns will fail.
st.onWriteTimeout()
@@ -2803,9 +2847,9 @@ func (w *responseWriter) SetWriteDeadline(deadline time.Time) error {
if deadline.IsZero() {
st.writeDeadline = nil
} else if st.writeDeadline == nil {
- st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
+ st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout)
} else {
- st.writeDeadline.Reset(deadline.Sub(time.Now()))
+ st.writeDeadline.Reset(deadline.Sub(sc.srv.now()))
}
})
return nil
diff --git a/vendor/golang.org/x/net/http2/testsync.go b/vendor/golang.org/x/net/http2/testsync.go
deleted file mode 100644
index 61075bd16d3..00000000000
--- a/vendor/golang.org/x/net/http2/testsync.go
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright 2024 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-package http2
-
-import (
- "context"
- "sync"
- "time"
-)
-
-// testSyncHooks coordinates goroutines in tests.
-//
-// For example, a call to ClientConn.RoundTrip involves several goroutines, including:
-// - the goroutine running RoundTrip;
-// - the clientStream.doRequest goroutine, which writes the request; and
-// - the clientStream.readLoop goroutine, which reads the response.
-//
-// Using testSyncHooks, a test can start a RoundTrip and identify when all these goroutines
-// are blocked waiting for some condition such as reading the Request.Body or waiting for
-// flow control to become available.
-//
-// The testSyncHooks also manage timers and synthetic time in tests.
-// This permits us to, for example, start a request and cause it to time out waiting for
-// response headers without resorting to time.Sleep calls.
-type testSyncHooks struct {
- // active/inactive act as a mutex and condition variable.
- //
- // - neither chan contains a value: testSyncHooks is locked.
- // - active contains a value: unlocked, and at least one goroutine is not blocked
- // - inactive contains a value: unlocked, and all goroutines are blocked
- active chan struct{}
- inactive chan struct{}
-
- // goroutine counts
- total int // total goroutines
- condwait map[*sync.Cond]int // blocked in sync.Cond.Wait
- blocked []*testBlockedGoroutine // otherwise blocked
-
- // fake time
- now time.Time
- timers []*fakeTimer
-
- // Transport testing: Report various events.
- newclientconn func(*ClientConn)
- newstream func(*clientStream)
-}
-
-// testBlockedGoroutine is a blocked goroutine.
-type testBlockedGoroutine struct {
- f func() bool // blocked until f returns true
- ch chan struct{} // closed when unblocked
-}
-
-func newTestSyncHooks() *testSyncHooks {
- h := &testSyncHooks{
- active: make(chan struct{}, 1),
- inactive: make(chan struct{}, 1),
- condwait: map[*sync.Cond]int{},
- }
- h.inactive <- struct{}{}
- h.now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
- return h
-}
-
-// lock acquires the testSyncHooks mutex.
-func (h *testSyncHooks) lock() {
- select {
- case <-h.active:
- case <-h.inactive:
- }
-}
-
-// waitInactive waits for all goroutines to become inactive.
-func (h *testSyncHooks) waitInactive() {
- for {
- <-h.inactive
- if !h.unlock() {
- break
- }
- }
-}
-
-// unlock releases the testSyncHooks mutex.
-// It reports whether any goroutines are active.
-func (h *testSyncHooks) unlock() (active bool) {
- // Look for a blocked goroutine which can be unblocked.
- blocked := h.blocked[:0]
- unblocked := false
- for _, b := range h.blocked {
- if !unblocked && b.f() {
- unblocked = true
- close(b.ch)
- } else {
- blocked = append(blocked, b)
- }
- }
- h.blocked = blocked
-
- // Count goroutines blocked on condition variables.
- condwait := 0
- for _, count := range h.condwait {
- condwait += count
- }
-
- if h.total > condwait+len(blocked) {
- h.active <- struct{}{}
- return true
- } else {
- h.inactive <- struct{}{}
- return false
- }
-}
-
-// goRun starts a new goroutine.
-func (h *testSyncHooks) goRun(f func()) {
- h.lock()
- h.total++
- h.unlock()
- go func() {
- defer func() {
- h.lock()
- h.total--
- h.unlock()
- }()
- f()
- }()
-}
-
-// blockUntil indicates that a goroutine is blocked waiting for some condition to become true.
-// It waits until f returns true before proceeding.
-//
-// Example usage:
-//
-// h.blockUntil(func() bool {
-// // Is the context done yet?
-// select {
-// case <-ctx.Done():
-// default:
-// return false
-// }
-// return true
-// })
-// // Wait for the context to become done.
-// <-ctx.Done()
-//
-// The function f passed to blockUntil must be non-blocking and idempotent.
-func (h *testSyncHooks) blockUntil(f func() bool) {
- if f() {
- return
- }
- ch := make(chan struct{})
- h.lock()
- h.blocked = append(h.blocked, &testBlockedGoroutine{
- f: f,
- ch: ch,
- })
- h.unlock()
- <-ch
-}
-
-// broadcast is sync.Cond.Broadcast.
-func (h *testSyncHooks) condBroadcast(cond *sync.Cond) {
- h.lock()
- delete(h.condwait, cond)
- h.unlock()
- cond.Broadcast()
-}
-
-// broadcast is sync.Cond.Wait.
-func (h *testSyncHooks) condWait(cond *sync.Cond) {
- h.lock()
- h.condwait[cond]++
- h.unlock()
-}
-
-// newTimer creates a new fake timer.
-func (h *testSyncHooks) newTimer(d time.Duration) timer {
- h.lock()
- defer h.unlock()
- t := &fakeTimer{
- hooks: h,
- when: h.now.Add(d),
- c: make(chan time.Time),
- }
- h.timers = append(h.timers, t)
- return t
-}
-
-// afterFunc creates a new fake AfterFunc timer.
-func (h *testSyncHooks) afterFunc(d time.Duration, f func()) timer {
- h.lock()
- defer h.unlock()
- t := &fakeTimer{
- hooks: h,
- when: h.now.Add(d),
- f: f,
- }
- h.timers = append(h.timers, t)
- return t
-}
-
-func (h *testSyncHooks) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {
- ctx, cancel := context.WithCancel(ctx)
- t := h.afterFunc(d, cancel)
- return ctx, func() {
- t.Stop()
- cancel()
- }
-}
-
-func (h *testSyncHooks) timeUntilEvent() time.Duration {
- h.lock()
- defer h.unlock()
- var next time.Time
- for _, t := range h.timers {
- if next.IsZero() || t.when.Before(next) {
- next = t.when
- }
- }
- if d := next.Sub(h.now); d > 0 {
- return d
- }
- return 0
-}
-
-// advance advances time and causes synthetic timers to fire.
-func (h *testSyncHooks) advance(d time.Duration) {
- h.lock()
- defer h.unlock()
- h.now = h.now.Add(d)
- timers := h.timers[:0]
- for _, t := range h.timers {
- t := t // remove after go.mod depends on go1.22
- t.mu.Lock()
- switch {
- case t.when.After(h.now):
- timers = append(timers, t)
- case t.when.IsZero():
- // stopped timer
- default:
- t.when = time.Time{}
- if t.c != nil {
- close(t.c)
- }
- if t.f != nil {
- h.total++
- go func() {
- defer func() {
- h.lock()
- h.total--
- h.unlock()
- }()
- t.f()
- }()
- }
- }
- t.mu.Unlock()
- }
- h.timers = timers
-}
-
-// A timer wraps a time.Timer, or a synthetic equivalent in tests.
-// Unlike time.Timer, timer is single-use: The timer channel is closed when the timer expires.
-type timer interface {
- C() <-chan time.Time
- Stop() bool
- Reset(d time.Duration) bool
-}
-
-// timeTimer implements timer using real time.
-type timeTimer struct {
- t *time.Timer
- c chan time.Time
-}
-
-// newTimeTimer creates a new timer using real time.
-func newTimeTimer(d time.Duration) timer {
- ch := make(chan time.Time)
- t := time.AfterFunc(d, func() {
- close(ch)
- })
- return &timeTimer{t, ch}
-}
-
-// newTimeAfterFunc creates an AfterFunc timer using real time.
-func newTimeAfterFunc(d time.Duration, f func()) timer {
- return &timeTimer{
- t: time.AfterFunc(d, f),
- }
-}
-
-func (t timeTimer) C() <-chan time.Time { return t.c }
-func (t timeTimer) Stop() bool { return t.t.Stop() }
-func (t timeTimer) Reset(d time.Duration) bool { return t.t.Reset(d) }
-
-// fakeTimer implements timer using fake time.
-type fakeTimer struct {
- hooks *testSyncHooks
-
- mu sync.Mutex
- when time.Time // when the timer will fire
- c chan time.Time // closed when the timer fires; mutually exclusive with f
- f func() // called when the timer fires; mutually exclusive with c
-}
-
-func (t *fakeTimer) C() <-chan time.Time { return t.c }
-
-func (t *fakeTimer) Stop() bool {
- t.mu.Lock()
- defer t.mu.Unlock()
- stopped := t.when.IsZero()
- t.when = time.Time{}
- return stopped
-}
-
-func (t *fakeTimer) Reset(d time.Duration) bool {
- if t.c != nil || t.f == nil {
- panic("fakeTimer only supports Reset on AfterFunc timers")
- }
- t.mu.Lock()
- defer t.mu.Unlock()
- t.hooks.lock()
- defer t.hooks.unlock()
- active := !t.when.IsZero()
- t.when = t.hooks.now.Add(d)
- if !active {
- t.hooks.timers = append(t.hooks.timers, t)
- }
- return active
-}
diff --git a/vendor/golang.org/x/net/http2/timer.go b/vendor/golang.org/x/net/http2/timer.go
new file mode 100644
index 00000000000..0b1c17b8129
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/timer.go
@@ -0,0 +1,20 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package http2
+
+import "time"
+
+// A timer is a time.Timer, as an interface which can be replaced in tests.
+type timer = interface {
+ C() <-chan time.Time
+ Reset(d time.Duration) bool
+ Stop() bool
+}
+
+// timeTimer adapts a time.Timer to the timer interface.
+type timeTimer struct {
+ *time.Timer
+}
+
+func (t timeTimer) C() <-chan time.Time { return t.Timer.C }
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 2fa49490c9d..98a49c6b6ee 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -185,7 +185,45 @@ type Transport struct {
connPoolOnce sync.Once
connPoolOrDef ClientConnPool // non-nil version of ConnPool
- syncHooks *testSyncHooks
+ *transportTestHooks
+}
+
+// Hook points used for testing.
+// Outside of tests, t.transportTestHooks is nil and these all have minimal implementations.
+// Inside tests, see the testSyncHooks function docs.
+
+type transportTestHooks struct {
+ newclientconn func(*ClientConn)
+ group synctestGroupInterface
+}
+
+func (t *Transport) markNewGoroutine() {
+ if t != nil && t.transportTestHooks != nil {
+ t.transportTestHooks.group.Join()
+ }
+}
+
+// newTimer creates a new time.Timer, or a synthetic timer in tests.
+func (t *Transport) newTimer(d time.Duration) timer {
+ if t.transportTestHooks != nil {
+ return t.transportTestHooks.group.NewTimer(d)
+ }
+ return timeTimer{time.NewTimer(d)}
+}
+
+// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
+func (t *Transport) afterFunc(d time.Duration, f func()) timer {
+ if t.transportTestHooks != nil {
+ return t.transportTestHooks.group.AfterFunc(d, f)
+ }
+ return timeTimer{time.AfterFunc(d, f)}
+}
+
+func (t *Transport) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {
+ if t.transportTestHooks != nil {
+ return t.transportTestHooks.group.ContextWithTimeout(ctx, d)
+ }
+ return context.WithTimeout(ctx, d)
}
func (t *Transport) maxHeaderListSize() uint32 {
@@ -352,60 +390,6 @@ type ClientConn struct {
werr error // first write error that has occurred
hbuf bytes.Buffer // HPACK encoder writes into this
henc *hpack.Encoder
-
- syncHooks *testSyncHooks // can be nil
-}
-
-// Hook points used for testing.
-// Outside of tests, cc.syncHooks is nil and these all have minimal implementations.
-// Inside tests, see the testSyncHooks function docs.
-
-// goRun starts a new goroutine.
-func (cc *ClientConn) goRun(f func()) {
- if cc.syncHooks != nil {
- cc.syncHooks.goRun(f)
- return
- }
- go f()
-}
-
-// condBroadcast is cc.cond.Broadcast.
-func (cc *ClientConn) condBroadcast() {
- if cc.syncHooks != nil {
- cc.syncHooks.condBroadcast(cc.cond)
- }
- cc.cond.Broadcast()
-}
-
-// condWait is cc.cond.Wait.
-func (cc *ClientConn) condWait() {
- if cc.syncHooks != nil {
- cc.syncHooks.condWait(cc.cond)
- }
- cc.cond.Wait()
-}
-
-// newTimer creates a new time.Timer, or a synthetic timer in tests.
-func (cc *ClientConn) newTimer(d time.Duration) timer {
- if cc.syncHooks != nil {
- return cc.syncHooks.newTimer(d)
- }
- return newTimeTimer(d)
-}
-
-// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
-func (cc *ClientConn) afterFunc(d time.Duration, f func()) timer {
- if cc.syncHooks != nil {
- return cc.syncHooks.afterFunc(d, f)
- }
- return newTimeAfterFunc(d, f)
-}
-
-func (cc *ClientConn) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {
- if cc.syncHooks != nil {
- return cc.syncHooks.contextWithTimeout(ctx, d)
- }
- return context.WithTimeout(ctx, d)
}
// clientStream is the state for a single HTTP/2 stream. One of these
@@ -487,7 +471,7 @@ func (cs *clientStream) abortStreamLocked(err error) {
// TODO(dneil): Clean up tests where cs.cc.cond is nil.
if cs.cc.cond != nil {
// Wake up writeRequestBody if it is waiting on flow control.
- cs.cc.condBroadcast()
+ cs.cc.cond.Broadcast()
}
}
@@ -497,7 +481,7 @@ func (cs *clientStream) abortRequestBodyWrite() {
defer cc.mu.Unlock()
if cs.reqBody != nil && cs.reqBodyClosed == nil {
cs.closeReqBodyLocked()
- cc.condBroadcast()
+ cc.cond.Broadcast()
}
}
@@ -507,10 +491,11 @@ func (cs *clientStream) closeReqBodyLocked() {
}
cs.reqBodyClosed = make(chan struct{})
reqBodyClosed := cs.reqBodyClosed
- cs.cc.goRun(func() {
+ go func() {
+ cs.cc.t.markNewGoroutine()
cs.reqBody.Close()
close(reqBodyClosed)
- })
+ }()
}
type stickyErrWriter struct {
@@ -626,21 +611,7 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
backoff := float64(uint(1) << (uint(retry) - 1))
backoff += backoff * (0.1 * mathrand.Float64())
d := time.Second * time.Duration(backoff)
- var tm timer
- if t.syncHooks != nil {
- tm = t.syncHooks.newTimer(d)
- t.syncHooks.blockUntil(func() bool {
- select {
- case <-tm.C():
- case <-req.Context().Done():
- default:
- return false
- }
- return true
- })
- } else {
- tm = newTimeTimer(d)
- }
+ tm := t.newTimer(d)
select {
case <-tm.C():
t.vlogf("RoundTrip retrying after failure: %v", roundTripErr)
@@ -725,8 +696,8 @@ func canRetryError(err error) bool {
}
func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {
- if t.syncHooks != nil {
- return t.newClientConn(nil, singleUse, t.syncHooks)
+ if t.transportTestHooks != nil {
+ return t.newClientConn(nil, singleUse)
}
host, _, err := net.SplitHostPort(addr)
if err != nil {
@@ -736,7 +707,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b
if err != nil {
return nil, err
}
- return t.newClientConn(tconn, singleUse, nil)
+ return t.newClientConn(tconn, singleUse)
}
func (t *Transport) newTLSConfig(host string) *tls.Config {
@@ -802,10 +773,10 @@ func (t *Transport) maxEncoderHeaderTableSize() uint32 {
}
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
- return t.newClientConn(c, t.disableKeepAlives(), nil)
+ return t.newClientConn(c, t.disableKeepAlives())
}
-func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHooks) (*ClientConn, error) {
+func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {
cc := &ClientConn{
t: t,
tconn: c,
@@ -820,16 +791,12 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo
wantSettingsAck: true,
pings: make(map[[8]byte]chan struct{}),
reqHeaderMu: make(chan struct{}, 1),
- syncHooks: hooks,
}
- if hooks != nil {
- hooks.newclientconn(cc)
+ if t.transportTestHooks != nil {
+ t.markNewGoroutine()
+ t.transportTestHooks.newclientconn(cc)
c = cc.tconn
}
- if d := t.idleConnTimeout(); d != 0 {
- cc.idleTimeout = d
- cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout)
- }
if VerboseLogs {
t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
}
@@ -893,7 +860,13 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHoo
return nil, cc.werr
}
- cc.goRun(cc.readLoop)
+ // Start the idle timer after the connection is fully initialized.
+ if d := t.idleConnTimeout(); d != 0 {
+ cc.idleTimeout = d
+ cc.idleTimer = t.afterFunc(d, cc.onIdleTimeout)
+ }
+
+ go cc.readLoop()
return cc, nil
}
@@ -901,7 +874,7 @@ func (cc *ClientConn) healthCheck() {
pingTimeout := cc.t.pingTimeout()
// We don't need to periodically ping in the health check, because the readLoop of ClientConn will
// trigger the healthCheck again if there is no frame received.
- ctx, cancel := cc.contextWithTimeout(context.Background(), pingTimeout)
+ ctx, cancel := cc.t.contextWithTimeout(context.Background(), pingTimeout)
defer cancel()
cc.vlogf("http2: Transport sending health check")
err := cc.Ping(ctx)
@@ -1144,7 +1117,8 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
// Wait for all in-flight streams to complete or connection to close
done := make(chan struct{})
cancelled := false // guarded by cc.mu
- cc.goRun(func() {
+ go func() {
+ cc.t.markNewGoroutine()
cc.mu.Lock()
defer cc.mu.Unlock()
for {
@@ -1156,9 +1130,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
if cancelled {
break
}
- cc.condWait()
+ cc.cond.Wait()
}
- })
+ }()
shutdownEnterWaitStateHook()
select {
case <-done:
@@ -1168,7 +1142,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
cc.mu.Lock()
// Free the goroutine above
cancelled = true
- cc.condBroadcast()
+ cc.cond.Broadcast()
cc.mu.Unlock()
return ctx.Err()
}
@@ -1206,7 +1180,7 @@ func (cc *ClientConn) closeForError(err error) {
for _, cs := range cc.streams {
cs.abortStreamLocked(err)
}
- cc.condBroadcast()
+ cc.cond.Broadcast()
cc.mu.Unlock()
cc.closeConn()
}
@@ -1321,23 +1295,30 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream))
respHeaderRecv: make(chan struct{}),
donec: make(chan struct{}),
}
- cc.goRun(func() {
- cs.doRequest(req)
- })
+
+ // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
+ if !cc.t.disableCompression() &&
+ req.Header.Get("Accept-Encoding") == "" &&
+ req.Header.Get("Range") == "" &&
+ !cs.isHead {
+ // Request gzip only, not deflate. Deflate is ambiguous and
+ // not as universally supported anyway.
+ // See: https://zlib.net/zlib_faq.html#faq39
+ //
+ // Note that we don't request this for HEAD requests,
+ // due to a bug in nginx:
+ // http://trac.nginx.org/nginx/ticket/358
+ // https://golang.org/issue/5522
+ //
+ // We don't request gzip if the request is for a range, since
+ // auto-decoding a portion of a gzipped document will just fail
+ // anyway. See https://golang.org/issue/8923
+ cs.requestedGzip = true
+ }
+
+ go cs.doRequest(req, streamf)
waitDone := func() error {
- if cc.syncHooks != nil {
- cc.syncHooks.blockUntil(func() bool {
- select {
- case <-cs.donec:
- case <-ctx.Done():
- case <-cs.reqCancel:
- default:
- return false
- }
- return true
- })
- }
select {
case <-cs.donec:
return nil
@@ -1398,24 +1379,7 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream))
return err
}
- if streamf != nil {
- streamf(cs)
- }
-
for {
- if cc.syncHooks != nil {
- cc.syncHooks.blockUntil(func() bool {
- select {
- case <-cs.respHeaderRecv:
- case <-cs.abort:
- case <-ctx.Done():
- case <-cs.reqCancel:
- default:
- return false
- }
- return true
- })
- }
select {
case <-cs.respHeaderRecv:
return handleResponseHeaders()
@@ -1445,8 +1409,9 @@ func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream))
// doRequest runs for the duration of the request lifetime.
//
// It sends the request and performs post-request cleanup (closing Request.Body, etc.).
-func (cs *clientStream) doRequest(req *http.Request) {
- err := cs.writeRequest(req)
+func (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) {
+ cs.cc.t.markNewGoroutine()
+ err := cs.writeRequest(req, streamf)
cs.cleanupWriteRequest(err)
}
@@ -1457,7 +1422,7 @@ func (cs *clientStream) doRequest(req *http.Request) {
//
// It returns non-nil if the request ends otherwise.
// If the returned error is StreamError, the error Code may be used in resetting the stream.
-func (cs *clientStream) writeRequest(req *http.Request) (err error) {
+func (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStream)) (err error) {
cc := cs.cc
ctx := cs.ctx
@@ -1471,21 +1436,6 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
if cc.reqHeaderMu == nil {
panic("RoundTrip on uninitialized ClientConn") // for tests
}
- var newStreamHook func(*clientStream)
- if cc.syncHooks != nil {
- newStreamHook = cc.syncHooks.newstream
- cc.syncHooks.blockUntil(func() bool {
- select {
- case cc.reqHeaderMu <- struct{}{}:
- <-cc.reqHeaderMu
- case <-cs.reqCancel:
- case <-ctx.Done():
- default:
- return false
- }
- return true
- })
- }
select {
case cc.reqHeaderMu <- struct{}{}:
case <-cs.reqCancel:
@@ -1510,28 +1460,8 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
}
cc.mu.Unlock()
- if newStreamHook != nil {
- newStreamHook(cs)
- }
-
- // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
- if !cc.t.disableCompression() &&
- req.Header.Get("Accept-Encoding") == "" &&
- req.Header.Get("Range") == "" &&
- !cs.isHead {
- // Request gzip only, not deflate. Deflate is ambiguous and
- // not as universally supported anyway.
- // See: https://zlib.net/zlib_faq.html#faq39
- //
- // Note that we don't request this for HEAD requests,
- // due to a bug in nginx:
- // http://trac.nginx.org/nginx/ticket/358
- // https://golang.org/issue/5522
- //
- // We don't request gzip if the request is for a range, since
- // auto-decoding a portion of a gzipped document will just fail
- // anyway. See https://golang.org/issue/8923
- cs.requestedGzip = true
+ if streamf != nil {
+ streamf(cs)
}
continueTimeout := cc.t.expectContinueTimeout()
@@ -1594,7 +1524,7 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
var respHeaderTimer <-chan time.Time
var respHeaderRecv chan struct{}
if d := cc.responseHeaderTimeout(); d != 0 {
- timer := cc.newTimer(d)
+ timer := cc.t.newTimer(d)
defer timer.Stop()
respHeaderTimer = timer.C()
respHeaderRecv = cs.respHeaderRecv
@@ -1603,21 +1533,6 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
// or until the request is aborted (via context, error, or otherwise),
// whichever comes first.
for {
- if cc.syncHooks != nil {
- cc.syncHooks.blockUntil(func() bool {
- select {
- case <-cs.peerClosed:
- case <-respHeaderTimer:
- case <-respHeaderRecv:
- case <-cs.abort:
- case <-ctx.Done():
- case <-cs.reqCancel:
- default:
- return false
- }
- return true
- })
- }
select {
case <-cs.peerClosed:
return nil
@@ -1766,7 +1681,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error {
return nil
}
cc.pendingRequests++
- cc.condWait()
+ cc.cond.Wait()
cc.pendingRequests--
select {
case <-cs.abort:
@@ -2028,7 +1943,7 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error)
cs.flow.take(take)
return take, nil
}
- cc.condWait()
+ cc.cond.Wait()
}
}
@@ -2311,7 +2226,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) {
}
// Wake up writeRequestBody via clientStream.awaitFlowControl and
// wake up RoundTrip if there is a pending request.
- cc.condBroadcast()
+ cc.cond.Broadcast()
closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
@@ -2333,6 +2248,7 @@ type clientConnReadLoop struct {
// readLoop runs in its own goroutine and reads and dispatches frames.
func (cc *ClientConn) readLoop() {
+ cc.t.markNewGoroutine()
rl := &clientConnReadLoop{cc: cc}
defer rl.cleanup()
cc.readerErr = rl.run()
@@ -2399,7 +2315,7 @@ func (rl *clientConnReadLoop) cleanup() {
cs.abortStreamLocked(err)
}
}
- cc.condBroadcast()
+ cc.cond.Broadcast()
cc.mu.Unlock()
}
@@ -2436,7 +2352,7 @@ func (rl *clientConnReadLoop) run() error {
readIdleTimeout := cc.t.ReadIdleTimeout
var t timer
if readIdleTimeout != 0 {
- t = cc.afterFunc(readIdleTimeout, cc.healthCheck)
+ t = cc.t.afterFunc(readIdleTimeout, cc.healthCheck)
}
for {
f, err := cc.fr.ReadFrame()
@@ -3034,7 +2950,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error {
for _, cs := range cc.streams {
cs.flow.add(delta)
}
- cc.condBroadcast()
+ cc.cond.Broadcast()
cc.initialWindowSize = s.Val
case SettingHeaderTableSize:
@@ -3089,7 +3005,7 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
return ConnectionError(ErrCodeFlowControl)
}
- cc.condBroadcast()
+ cc.cond.Broadcast()
return nil
}
@@ -3133,7 +3049,8 @@ func (cc *ClientConn) Ping(ctx context.Context) error {
}
var pingError error
errc := make(chan struct{})
- cc.goRun(func() {
+ go func() {
+ cc.t.markNewGoroutine()
cc.wmu.Lock()
defer cc.wmu.Unlock()
if pingError = cc.fr.WritePing(false, p); pingError != nil {
@@ -3144,20 +3061,7 @@ func (cc *ClientConn) Ping(ctx context.Context) error {
close(errc)
return
}
- })
- if cc.syncHooks != nil {
- cc.syncHooks.blockUntil(func() bool {
- select {
- case <-c:
- case <-errc:
- case <-ctx.Done():
- case <-cc.readerDone:
- default:
- return false
- }
- return true
- })
- }
+ }()
select {
case <-c:
return nil
diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority.go
index 0a242c669e2..f6783339d11 100644
--- a/vendor/golang.org/x/net/http2/writesched_priority.go
+++ b/vendor/golang.org/x/net/http2/writesched_priority.go
@@ -443,8 +443,8 @@ func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, max
}
func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
- for k := n.kids; k != nil; k = k.next {
- k.setParent(n.parent)
+ for n.kids != nil {
+ n.kids.setParent(n.parent)
}
n.setParent(nil)
delete(ws.nodes, n.id)
diff --git a/vendor/golang.org/x/net/proxy/per_host.go b/vendor/golang.org/x/net/proxy/per_host.go
index 573fe79e86e..d7d4b8b6e35 100644
--- a/vendor/golang.org/x/net/proxy/per_host.go
+++ b/vendor/golang.org/x/net/proxy/per_host.go
@@ -137,9 +137,7 @@ func (p *PerHost) AddNetwork(net *net.IPNet) {
// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
// "example.com" matches "example.com" and all of its subdomains.
func (p *PerHost) AddZone(zone string) {
- if strings.HasSuffix(zone, ".") {
- zone = zone[:len(zone)-1]
- }
+ zone = strings.TrimSuffix(zone, ".")
if !strings.HasPrefix(zone, ".") {
zone = "." + zone
}
@@ -148,8 +146,6 @@ func (p *PerHost) AddZone(zone string) {
// AddHost specifies a host name that will use the bypass proxy.
func (p *PerHost) AddHost(host string) {
- if strings.HasSuffix(host, ".") {
- host = host[:len(host)-1]
- }
+ host = strings.TrimSuffix(host, ".")
p.bypassHosts = append(p.bypassHosts, host)
}
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index fdcaa974d23..4ed2e488b61 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -263,6 +263,7 @@ struct ltchars {
#include
#include
#include
+#include
#include
#include
#include
@@ -549,6 +550,7 @@ ccflags="$@"
$2 !~ "NLA_TYPE_MASK" &&
$2 !~ /^RTC_VL_(ACCURACY|BACKUP|DATA)/ &&
$2 ~ /^(NETLINK|NLM|NLMSG|NLA|IFA|IFAN|RT|RTC|RTCF|RTN|RTPROT|RTNH|ARPHRD|ETH_P|NETNSA)_/ ||
+ $2 ~ /^SOCK_|SK_DIAG_|SKNLGRP_$/ ||
$2 ~ /^FIORDCHK$/ ||
$2 ~ /^SIOC/ ||
$2 ~ /^TIOC/ ||
diff --git a/vendor/golang.org/x/sys/unix/mremap.go b/vendor/golang.org/x/sys/unix/mremap.go
index fd45fe529da..3a5e776f895 100644
--- a/vendor/golang.org/x/sys/unix/mremap.go
+++ b/vendor/golang.org/x/sys/unix/mremap.go
@@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
return mapper.Mremap(oldData, newLength, flags)
}
+
+func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) {
+ xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr))
+ return unsafe.Pointer(xaddr), err
+}
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go
index 59542a897d2..4cc7b005967 100644
--- a/vendor/golang.org/x/sys/unix/syscall_darwin.go
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go
@@ -542,6 +542,18 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
}
}
+//sys pthread_chdir_np(path string) (err error)
+
+func PthreadChdir(path string) (err error) {
+ return pthread_chdir_np(path)
+}
+
+//sys pthread_fchdir_np(fd int) (err error)
+
+func PthreadFchdir(fd int) (err error) {
+ return pthread_fchdir_np(fd)
+}
+
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go
index 77081de8c7d..4e92e5aa406 100644
--- a/vendor/golang.org/x/sys/unix/syscall_unix.go
+++ b/vendor/golang.org/x/sys/unix/syscall_unix.go
@@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) {
return mapper.Munmap(b)
}
+func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
+ xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
+ return unsafe.Pointer(xaddr), err
+}
+
+func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
+ return mapper.munmap(uintptr(addr), length)
+}
+
func Read(fd int, p []byte) (n int, err error) {
n, err = read(fd, p)
if raceenabled {
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go
index 93a38a97d9c..877a62b479a 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -502,6 +502,7 @@ const (
BPF_IMM = 0x0
BPF_IND = 0x40
BPF_JA = 0x0
+ BPF_JCOND = 0xe0
BPF_JEQ = 0x10
BPF_JGE = 0x30
BPF_JGT = 0x20
@@ -657,6 +658,9 @@ const (
CAN_NPROTO = 0x8
CAN_RAW = 0x1
CAN_RAW_FILTER_MAX = 0x200
+ CAN_RAW_XL_VCID_RX_FILTER = 0x4
+ CAN_RAW_XL_VCID_TX_PASS = 0x2
+ CAN_RAW_XL_VCID_TX_SET = 0x1
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
@@ -1339,6 +1343,7 @@ const (
F_OFD_SETLK = 0x25
F_OFD_SETLKW = 0x26
F_OK = 0x0
+ F_SEAL_EXEC = 0x20
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1
@@ -1627,6 +1632,7 @@ const (
IP_FREEBIND = 0xf
IP_HDRINCL = 0x3
IP_IPSEC_POLICY = 0x10
+ IP_LOCAL_PORT_RANGE = 0x33
IP_MAXPACKET = 0xffff
IP_MAX_MEMBERSHIPS = 0x14
IP_MF = 0x2000
@@ -1653,6 +1659,7 @@ const (
IP_PMTUDISC_OMIT = 0x5
IP_PMTUDISC_PROBE = 0x3
IP_PMTUDISC_WANT = 0x1
+ IP_PROTOCOL = 0x34
IP_RECVERR = 0xb
IP_RECVERR_RFC4884 = 0x1a
IP_RECVFRAGSIZE = 0x19
@@ -2169,7 +2176,7 @@ const (
NFT_SECMARK_CTX_MAXLEN = 0x100
NFT_SET_MAXNAMELEN = 0x100
NFT_SOCKET_MAX = 0x3
- NFT_TABLE_F_MASK = 0x3
+ NFT_TABLE_F_MASK = 0x7
NFT_TABLE_MAXNAMELEN = 0x100
NFT_TRACETYPE_MAX = 0x3
NFT_TUNNEL_F_MASK = 0x7
@@ -2403,6 +2410,7 @@ const (
PERF_RECORD_MISC_USER = 0x2
PERF_SAMPLE_BRANCH_PLM_ALL = 0x7
PERF_SAMPLE_WEIGHT_TYPE = 0x1004000
+ PID_FS_MAGIC = 0x50494446
PIPEFS_MAGIC = 0x50495045
PPPIOCGNPMODE = 0xc008744c
PPPIOCNEWUNIT = 0xc004743e
@@ -2896,8 +2904,9 @@ const (
RWF_APPEND = 0x10
RWF_DSYNC = 0x2
RWF_HIPRI = 0x1
+ RWF_NOAPPEND = 0x20
RWF_NOWAIT = 0x8
- RWF_SUPPORTED = 0x1f
+ RWF_SUPPORTED = 0x3f
RWF_SYNC = 0x4
RWF_WRITE_LIFE_NOT_SET = 0x0
SCHED_BATCH = 0x3
@@ -2918,7 +2927,9 @@ const (
SCHED_RESET_ON_FORK = 0x40000000
SCHED_RR = 0x2
SCM_CREDENTIALS = 0x2
+ SCM_PIDFD = 0x4
SCM_RIGHTS = 0x1
+ SCM_SECURITY = 0x3
SCM_TIMESTAMP = 0x1d
SC_LOG_FLUSH = 0x100000
SECCOMP_ADDFD_FLAG_SEND = 0x2
@@ -3051,6 +3062,8 @@ const (
SIOCSMIIREG = 0x8949
SIOCSRARP = 0x8962
SIOCWANDEV = 0x894a
+ SK_DIAG_BPF_STORAGE_MAX = 0x3
+ SK_DIAG_BPF_STORAGE_REQ_MAX = 0x1
SMACK_MAGIC = 0x43415d53
SMART_AUTOSAVE = 0xd2
SMART_AUTO_OFFLINE = 0xdb
@@ -3071,6 +3084,8 @@ const (
SOCKFS_MAGIC = 0x534f434b
SOCK_BUF_LOCK_MASK = 0x3
SOCK_DCCP = 0x6
+ SOCK_DESTROY = 0x15
+ SOCK_DIAG_BY_FAMILY = 0x14
SOCK_IOC_TYPE = 0x89
SOCK_PACKET = 0xa
SOCK_RAW = 0x3
@@ -3260,6 +3275,7 @@ const (
TCP_MAX_WINSHIFT = 0xe
TCP_MD5SIG = 0xe
TCP_MD5SIG_EXT = 0x20
+ TCP_MD5SIG_FLAG_IFINDEX = 0x2
TCP_MD5SIG_FLAG_PREFIX = 0x1
TCP_MD5SIG_MAXKEYLEN = 0x50
TCP_MSS = 0x200
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index 42ff8c3c1b0..e4bc0bd57c7 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -118,6 +118,7 @@ const (
IXOFF = 0x1000
IXON = 0x400
MAP_32BIT = 0x40
+ MAP_ABOVE4G = 0x80
MAP_ANON = 0x20
MAP_ANONYMOUS = 0x20
MAP_DENYWRITE = 0x800
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index dca436004fa..689317afdbf 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -118,6 +118,7 @@ const (
IXOFF = 0x1000
IXON = 0x400
MAP_32BIT = 0x40
+ MAP_ABOVE4G = 0x80
MAP_ANON = 0x20
MAP_ANONYMOUS = 0x20
MAP_DENYWRITE = 0x800
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index d8cae6d1534..14270508b04 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -87,6 +87,7 @@ const (
FICLONE = 0x40049409
FICLONERANGE = 0x4020940d
FLUSHO = 0x1000
+ FPMR_MAGIC = 0x46504d52
FPSIMD_MAGIC = 0x46508001
FS_IOC_ENABLE_VERITY = 0x40806685
FS_IOC_GETFLAGS = 0x80086601
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
index ccb02f240a4..07642c308d3 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
@@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func pthread_chdir_np(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_pthread_chdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pthread_fchdir_np(fd int) (err error) {
+ _, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_pthread_fchdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
index 8b8bb284028..923e08cb792 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
@@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_pthread_chdir_np(SB)
+GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
+DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
+
+TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_pthread_fchdir_np(SB)
+GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
+DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
+
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sendfile(SB)
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
index 1b40b997b52..7d73dda6473 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
@@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func pthread_chdir_np(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_pthread_chdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pthread_fchdir_np(fd int) (err error) {
+ _, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_pthread_fchdir_np_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
if e1 != 0 {
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
index 08362c1ab74..057700111e7 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
+++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
@@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_pthread_chdir_np(SB)
+GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
+DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
+
+TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
+ JMP libc_pthread_fchdir_np(SB)
+GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
+DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
+
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sendfile(SB)
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 0036746ea19..4740b834854 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -4605,7 +4605,7 @@ const (
NL80211_ATTR_MAC_HINT = 0xc8
NL80211_ATTR_MAC_MASK = 0xd7
NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca
- NL80211_ATTR_MAX = 0x149
+ NL80211_ATTR_MAX = 0x14a
NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4
NL80211_ATTR_MAX_CSA_COUNTERS = 0xce
NL80211_ATTR_MAX_MATCH_SETS = 0x85
@@ -5209,7 +5209,7 @@ const (
NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf
NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe
NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf
- NL80211_FREQUENCY_ATTR_MAX = 0x1f
+ NL80211_FREQUENCY_ATTR_MAX = 0x20
NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6
NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11
NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc
@@ -5703,7 +5703,7 @@ const (
NL80211_STA_FLAG_ASSOCIATED = 0x7
NL80211_STA_FLAG_AUTHENTICATED = 0x5
NL80211_STA_FLAG_AUTHORIZED = 0x1
- NL80211_STA_FLAG_MAX = 0x7
+ NL80211_STA_FLAG_MAX = 0x8
NL80211_STA_FLAG_MAX_OLD_API = 0x6
NL80211_STA_FLAG_MFP = 0x4
NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2
@@ -6001,3 +6001,34 @@ type CachestatRange struct {
Off uint64
Len uint64
}
+
+const (
+ SK_MEMINFO_RMEM_ALLOC = 0x0
+ SK_MEMINFO_RCVBUF = 0x1
+ SK_MEMINFO_WMEM_ALLOC = 0x2
+ SK_MEMINFO_SNDBUF = 0x3
+ SK_MEMINFO_FWD_ALLOC = 0x4
+ SK_MEMINFO_WMEM_QUEUED = 0x5
+ SK_MEMINFO_OPTMEM = 0x6
+ SK_MEMINFO_BACKLOG = 0x7
+ SK_MEMINFO_DROPS = 0x8
+ SK_MEMINFO_VARS = 0x9
+ SKNLGRP_NONE = 0x0
+ SKNLGRP_INET_TCP_DESTROY = 0x1
+ SKNLGRP_INET_UDP_DESTROY = 0x2
+ SKNLGRP_INET6_TCP_DESTROY = 0x3
+ SKNLGRP_INET6_UDP_DESTROY = 0x4
+ SK_DIAG_BPF_STORAGE_REQ_NONE = 0x0
+ SK_DIAG_BPF_STORAGE_REQ_MAP_FD = 0x1
+ SK_DIAG_BPF_STORAGE_REP_NONE = 0x0
+ SK_DIAG_BPF_STORAGE = 0x1
+ SK_DIAG_BPF_STORAGE_NONE = 0x0
+ SK_DIAG_BPF_STORAGE_PAD = 0x1
+ SK_DIAG_BPF_STORAGE_MAP_ID = 0x2
+ SK_DIAG_BPF_STORAGE_MAP_VALUE = 0x3
+)
+
+type SockDiagReq struct {
+ Family uint8
+ Protocol uint8
+}
diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go
index 26be94a8a7b..97651b5bd04 100644
--- a/vendor/golang.org/x/sys/windows/security_windows.go
+++ b/vendor/golang.org/x/sys/windows/security_windows.go
@@ -68,6 +68,7 @@ type UserInfo10 struct {
//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
+//sys NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) = netapi32.NetUserEnum
const (
// do not reorder
@@ -893,7 +894,7 @@ type ACL struct {
aclRevision byte
sbz1 byte
aclSize uint16
- aceCount uint16
+ AceCount uint16
sbz2 uint16
}
@@ -1086,6 +1087,27 @@ type EXPLICIT_ACCESS struct {
Trustee TRUSTEE
}
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
+type ACE_HEADER struct {
+ AceType uint8
+ AceFlags uint8
+ AceSize uint16
+}
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
+type ACCESS_ALLOWED_ACE struct {
+ Header ACE_HEADER
+ Mask ACCESS_MASK
+ SidStart uint32
+}
+
+const (
+ // Constants for AceType
+ // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
+ ACCESS_ALLOWED_ACE_TYPE = 0
+ ACCESS_DENIED_ACE_TYPE = 1
+)
+
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
type TrusteeValue uintptr
@@ -1157,6 +1179,7 @@ type OBJECTS_AND_NAME struct {
//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
+//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) = advapi32.GetAce
// Control returns the security descriptor control bits.
func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index 5c6035ddfa9..eba761018aa 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -91,6 +91,7 @@ var (
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
procEqualSid = modadvapi32.NewProc("EqualSid")
procFreeSid = modadvapi32.NewProc("FreeSid")
+ procGetAce = modadvapi32.NewProc("GetAce")
procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW")
procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl")
@@ -401,6 +402,7 @@ var (
procTransmitFile = modmswsock.NewProc("TransmitFile")
procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree")
procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
+ procNetUserEnum = modnetapi32.NewProc("NetUserEnum")
procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
procNtCreateFile = modntdll.NewProc("NtCreateFile")
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
@@ -1223,6 +1225,14 @@ func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCE
return
}
+func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) {
+ r0, _, _ := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce)))
+ if r0 == 0 {
+ ret = GetLastError()
+ }
+ return
+}
+
func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) {
r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor)))
if r1 == 0 {
@@ -3486,6 +3496,14 @@ func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (nete
return
}
+func NetUserEnum(serverName *uint16, level uint32, filter uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32, resumeHandle *uint32) (neterr error) {
+ r0, _, _ := syscall.Syscall9(procNetUserEnum.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(filter), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), uintptr(unsafe.Pointer(resumeHandle)), 0)
+ if r0 != 0 {
+ neterr = syscall.Errno(r0)
+ }
+ return
+}
+
func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
if r0 != 0 {
diff --git a/vendor/golang.org/x/tools/internal/event/tag/tag.go b/vendor/golang.org/x/tools/internal/event/tag/tag.go
deleted file mode 100644
index 581b26c2041..00000000000
--- a/vendor/golang.org/x/tools/internal/event/tag/tag.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package tag provides the labels used for telemetry throughout gopls.
-package tag
-
-import (
- "golang.org/x/tools/internal/event/keys"
-)
-
-var (
- // create the label keys we use
- Method = keys.NewString("method", "")
- StatusCode = keys.NewString("status.code", "")
- StatusMessage = keys.NewString("status.message", "")
- RPCID = keys.NewString("id", "")
- RPCDirection = keys.NewString("direction", "")
- File = keys.NewString("file", "")
- Directory = keys.New("directory", "")
- URI = keys.New("URI", "")
- Package = keys.NewString("package", "") // sorted comma-separated list of Package IDs
- PackagePath = keys.NewString("package_path", "")
- Query = keys.New("query", "")
- Snapshot = keys.NewUInt64("snapshot", "")
- Operation = keys.NewString("operation", "")
-
- Position = keys.New("position", "")
- Category = keys.NewString("category", "")
- PackageCount = keys.NewInt("packages", "")
- Files = keys.New("files", "")
- Port = keys.NewInt("port", "")
- Type = keys.New("type", "")
- HoverKind = keys.NewString("hoverkind", "")
-
- NewServer = keys.NewString("new_server", "A new server was added")
- EndServer = keys.NewString("end_server", "A server was shut down")
-
- ServerID = keys.NewString("server", "The server ID an event is related to")
- Logfile = keys.NewString("logfile", "")
- DebugAddress = keys.NewString("debug_address", "")
- GoplsPath = keys.NewString("gopls_path", "")
- ClientID = keys.NewString("client_id", "")
-
- Level = keys.NewInt("level", "The logging level")
-)
-
-var (
- // create the stats we measure
- Started = keys.NewInt64("started", "Count of started RPCs.")
- ReceivedBytes = keys.NewInt64("received_bytes", "Bytes received.") //, unit.Bytes)
- SentBytes = keys.NewInt64("sent_bytes", "Bytes sent.") //, unit.Bytes)
- Latency = keys.NewFloat64("latency_ms", "Elapsed time in milliseconds") //, unit.Milliseconds)
-)
-
-const (
- Inbound = "in"
- Outbound = "out"
-)
diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
index f7de3c8283b..eb7a8282f9e 100644
--- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go
+++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
@@ -25,7 +25,6 @@ import (
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
- "golang.org/x/tools/internal/event/tag"
)
// An Runner will run go command invocations and serialize
@@ -55,11 +54,14 @@ func (runner *Runner) initialize() {
// 1.14: go: updating go.mod: existing contents have changed since last read
var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`)
-// verb is an event label for the go command verb.
-var verb = keys.NewString("verb", "go command verb")
+// event keys for go command invocations
+var (
+ verb = keys.NewString("verb", "go command verb")
+ directory = keys.NewString("directory", "")
+)
func invLabels(inv Invocation) []label.Label {
- return []label.Label{verb.Of(inv.Verb), tag.Directory.Of(inv.WorkingDir)}
+ return []label.Label{verb.Of(inv.Verb), directory.Of(inv.WorkingDir)}
}
// Run is a convenience wrapper around RunRaw.
diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
index 2d3d408c0be..e38d1fb4888 100644
--- a/vendor/golang.org/x/tools/internal/gocommand/vendor.go
+++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
@@ -107,3 +107,57 @@ func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*Modul
}
return mod, lines[4] == "go1.14", nil
}
+
+// WorkspaceVendorEnabled reports whether workspace vendoring is enabled. It takes a *Runner to execute Go commands
+// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
+// of which only Verb and Args are modified to run the appropriate Go command.
+// Inspired by setDefaultBuildMod in modload/init.go
+func WorkspaceVendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, []*ModuleJSON, error) {
+ inv.Verb = "env"
+ inv.Args = []string{"GOWORK"}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return false, nil, err
+ }
+ goWork := string(bytes.TrimSpace(stdout.Bytes()))
+ if fi, err := os.Stat(filepath.Join(filepath.Dir(goWork), "vendor")); err == nil && fi.IsDir() {
+ mainMods, err := getWorkspaceMainModules(ctx, inv, r)
+ if err != nil {
+ return false, nil, err
+ }
+ return true, mainMods, nil
+ }
+ return false, nil, nil
+}
+
+// getWorkspaceMainModules gets the main modules' information.
+// This is the information needed to figure out if vendoring should be enabled.
+func getWorkspaceMainModules(ctx context.Context, inv Invocation, r *Runner) ([]*ModuleJSON, error) {
+ const format = `{{.Path}}
+{{.Dir}}
+{{.GoMod}}
+{{.GoVersion}}
+`
+ inv.Verb = "list"
+ inv.Args = []string{"-m", "-f", format}
+ stdout, err := r.Run(ctx, inv)
+ if err != nil {
+ return nil, err
+ }
+
+ lines := strings.Split(strings.TrimSuffix(stdout.String(), "\n"), "\n")
+ if len(lines) < 4 {
+ return nil, fmt.Errorf("unexpected stdout: %q", stdout.String())
+ }
+ mods := make([]*ModuleJSON, 0, len(lines)/4)
+ for i := 0; i < len(lines); i += 4 {
+ mods = append(mods, &ModuleJSON{
+ Path: lines[i],
+ Dir: lines[i+1],
+ GoMod: lines[i+2],
+ GoVersion: lines[i+3],
+ Main: true,
+ })
+ }
+ return mods, nil
+}
diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go
index 55980327616..93d49a6efd0 100644
--- a/vendor/golang.org/x/tools/internal/imports/fix.go
+++ b/vendor/golang.org/x/tools/internal/imports/fix.go
@@ -301,6 +301,20 @@ func (p *pass) loadPackageNames(imports []*ImportInfo) error {
return nil
}
+// if there is a trailing major version, remove it
+func withoutVersion(nm string) string {
+ if v := path.Base(nm); len(v) > 0 && v[0] == 'v' {
+ if _, err := strconv.Atoi(v[1:]); err == nil {
+ // this is, for instance, called with rand/v2 and returns rand
+ if len(v) < len(nm) {
+ xnm := nm[:len(nm)-len(v)-1]
+ return path.Base(xnm)
+ }
+ }
+ }
+ return nm
+}
+
// importIdentifier returns the identifier that imp will introduce. It will
// guess if the package name has not been loaded, e.g. because the source
// is not available.
@@ -310,7 +324,7 @@ func (p *pass) importIdentifier(imp *ImportInfo) string {
}
known := p.knownPackages[imp.ImportPath]
if known != nil && known.name != "" {
- return known.name
+ return withoutVersion(known.name)
}
return ImportPathToAssumedName(imp.ImportPath)
}
@@ -1059,6 +1073,18 @@ func addStdlibCandidates(pass *pass, refs references) error {
if err != nil {
return err
}
+ localbase := func(nm string) string {
+ ans := path.Base(nm)
+ if ans[0] == 'v' {
+ // this is called, for instance, with math/rand/v2 and returns rand/v2
+ if _, err := strconv.Atoi(ans[1:]); err == nil {
+ ix := strings.LastIndex(nm, ans)
+ more := path.Base(nm[:ix])
+ ans = path.Join(more, ans)
+ }
+ }
+ return ans
+ }
add := func(pkg string) {
// Prevent self-imports.
if path.Base(pkg) == pass.f.Name.Name && filepath.Join(goenv["GOROOT"], "src", pkg) == pass.srcDir {
@@ -1067,13 +1093,17 @@ func addStdlibCandidates(pass *pass, refs references) error {
exports := symbolNameSet(stdlib.PackageSymbols[pkg])
pass.addCandidate(
&ImportInfo{ImportPath: pkg},
- &packageInfo{name: path.Base(pkg), exports: exports})
+ &packageInfo{name: localbase(pkg), exports: exports})
}
for left := range refs {
if left == "rand" {
- // Make sure we try crypto/rand before math/rand.
+ // Make sure we try crypto/rand before any version of math/rand as both have Int()
+ // and our policy is to recommend crypto
add("crypto/rand")
- add("math/rand")
+ // if the user's no later than go1.21, this should be "math/rand"
+ // but we have no way of figuring out what the user is using
+ // TODO: investigate using the toolchain version to disambiguate in the stdlib
+ add("math/rand/v2")
continue
}
for importPath := range stdlib.PackageSymbols {
diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go
index 21ef938978e..82fe644a189 100644
--- a/vendor/golang.org/x/tools/internal/imports/mod.go
+++ b/vendor/golang.org/x/tools/internal/imports/mod.go
@@ -112,11 +112,11 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe
}
vendorEnabled := false
- var mainModVendor *gocommand.ModuleJSON
+ var mainModVendor *gocommand.ModuleJSON // for module vendoring
+ var mainModsVendor []*gocommand.ModuleJSON // for workspace vendoring
- // Module vendor directories are ignored in workspace mode:
- // https://go.googlesource.com/proposal/+/master/design/45713-workspace.md
- if len(r.env.Env["GOWORK"]) == 0 {
+ goWork := r.env.Env["GOWORK"]
+ if len(goWork) == 0 {
// TODO(rfindley): VendorEnabled runs the go command to get GOFLAGS, but
// they should be available from the ProcessEnv. Can we avoid the redundant
// invocation?
@@ -124,18 +124,35 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe
if err != nil {
return nil, err
}
+ } else {
+ vendorEnabled, mainModsVendor, err = gocommand.WorkspaceVendorEnabled(context.Background(), inv, r.env.GocmdRunner)
+ if err != nil {
+ return nil, err
+ }
}
- if mainModVendor != nil && vendorEnabled {
- // Vendor mode is on, so all the non-Main modules are irrelevant,
- // and we need to search /vendor for everything.
- r.mains = []*gocommand.ModuleJSON{mainModVendor}
- r.dummyVendorMod = &gocommand.ModuleJSON{
- Path: "",
- Dir: filepath.Join(mainModVendor.Dir, "vendor"),
+ if vendorEnabled {
+ if mainModVendor != nil {
+ // Module vendor mode is on, so all the non-Main modules are irrelevant,
+ // and we need to search /vendor for everything.
+ r.mains = []*gocommand.ModuleJSON{mainModVendor}
+ r.dummyVendorMod = &gocommand.ModuleJSON{
+ Path: "",
+ Dir: filepath.Join(mainModVendor.Dir, "vendor"),
+ }
+ r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
+ r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
+ } else {
+ // Workspace vendor mode is on, so all the non-Main modules are irrelevant,
+ // and we need to search /vendor for everything.
+ r.mains = mainModsVendor
+ r.dummyVendorMod = &gocommand.ModuleJSON{
+ Path: "",
+ Dir: filepath.Join(filepath.Dir(goWork), "vendor"),
+ }
+ r.modsByModPath = append(append([]*gocommand.ModuleJSON{}, mainModsVendor...), r.dummyVendorMod)
+ r.modsByDir = append(append([]*gocommand.ModuleJSON{}, mainModsVendor...), r.dummyVendorMod)
}
- r.modsByModPath = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
- r.modsByDir = []*gocommand.ModuleJSON{mainModVendor, r.dummyVendorMod}
} else {
// Vendor mode is off, so run go list -m ... to find everything.
err := r.initAllMods()
@@ -166,8 +183,9 @@ func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleRe
return count(j) < count(i) // descending order
})
- r.roots = []gopathwalk.Root{
- {Path: filepath.Join(goenv["GOROOT"], "/src"), Type: gopathwalk.RootGOROOT},
+ r.roots = []gopathwalk.Root{}
+ if goenv["GOROOT"] != "" { // "" happens in tests
+ r.roots = append(r.roots, gopathwalk.Root{Path: filepath.Join(goenv["GOROOT"], "/src"), Type: gopathwalk.RootGOROOT})
}
r.mainByDir = make(map[string]*gocommand.ModuleJSON)
for _, main := range r.mains {
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/.gitcookies.sh.enc b/vendor/gopkg.in/go-jose/go-jose.v2/.gitcookies.sh.enc
deleted file mode 100644
index 730e569b069..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/.gitcookies.sh.enc
+++ /dev/null
@@ -1 +0,0 @@
-'|&{tU|gG(Cy=+c:u:/p#~["4!nADK merged.coverprofile
-- $HOME/gopath/bin/goveralls -coverprofile merged.coverprofile -service=travis-ci
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/CHANGELOG.md b/vendor/gopkg.in/go-jose/go-jose.v2/CHANGELOG.md
deleted file mode 100644
index 8e6e9132395..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/CHANGELOG.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# v4.0.1
-
-## Fixed
-
- - An attacker could send a JWE containing compressed data that used large
- amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`.
- Those functions now return an error if the decompressed data would exceed
- 250kB or 10x the compressed size (whichever is larger). Thanks to
- Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj)
- for reporting.
-
-# v4.0.0
-
-This release makes some breaking changes in order to more thoroughly
-address the vulnerabilities discussed in [Three New Attacks Against JSON Web
-Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot
-token".
-
-## Changed
-
- - Limit JWT encryption types (exclude password or public key types) (#78)
- - Enforce minimum length for HMAC keys (#85)
- - jwt: match any audience in a list, rather than requiring all audiences (#81)
- - jwt: accept only Compact Serialization (#75)
- - jws: Add expected algorithms for signatures (#74)
- - Require specifying expected algorithms for ParseEncrypted,
- ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned,
- jwt.ParseSignedAndEncrypted (#69, #74)
- - Usually there is a small, known set of appropriate algorithms for a program
- to use and it's a mistake to allow unexpected algorithms. For instance the
- "billion hash attack" relies in part on programs accepting the PBES2
- encryption algorithm and doing the necessary work even if they weren't
- specifically configured to allow PBES2.
- - Revert "Strip padding off base64 strings" (#82)
- - The specs require base64url encoding without padding.
- - Minimum supported Go version is now 1.21
-
-## Added
-
- - ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON.
- - These allow parsing a specific serialization, as opposed to ParseSigned and
- ParseEncrypted, which try to automatically detect which serialization was
- provided. It's common to require a specific serialization for a specific
- protocol - for instance JWT requires Compact serialization.
-
-[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
-
-# v3.0.3
-
-## Fixed
-
- - Limit decompression output size to prevent a DoS. Backport from v4.0.1.
-
-# v3.0.2
-
-## Fixed
-
- - DecryptMulti: handle decompression error (#19)
-
-## Changed
-
- - jwe/CompactSerialize: improve performance (#67)
- - Increase the default number of PBKDF2 iterations to 600k (#48)
- - Return the proper algorithm for ECDSA keys (#45)
-
-## Added
-
- - Add Thumbprint support for opaque signers (#38)
-
-# v3.0.1
-
-## Fixed
-
- - Security issue: an attacker specifying a large "p2c" value can cause
- JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
- amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
- disclosure and to Tom Tervoort for originally publishing the category of attack.
- https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
-
-# v2.6.3
-
-## Fixed
-
- - Limit decompression output size to prevent a DoS. Backport from v4.0.1.
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/CONTRIBUTING.md b/vendor/gopkg.in/go-jose/go-jose.v2/CONTRIBUTING.md
deleted file mode 100644
index 61b183651c0..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/CONTRIBUTING.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Contributing
-
-If you would like to contribute code to go-jose you can do so through GitHub by
-forking the repository and sending a pull request.
-
-When submitting code, please make every effort to follow existing conventions
-and style in order to keep the code as readable as possible. Please also make
-sure all tests pass by running `go test`, and format your code with `go fmt`.
-We also recommend using `golint` and `errcheck`.
-
-Before your code can be accepted into the project you must also sign the
-[Individual Contributor License Agreement][1].
-
- [1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/LICENSE b/vendor/gopkg.in/go-jose/go-jose.v2/LICENSE
deleted file mode 100644
index d6456956733..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/README.md b/vendor/gopkg.in/go-jose/go-jose.v2/README.md
deleted file mode 100644
index b877f412c41..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# go-jose v2
-
-Version 2 of this library is no longer supported. [Please use v4
-instead](https://pkg.go.dev/github.com/go-jose/go-jose/v4).
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/asymmetric.go b/vendor/gopkg.in/go-jose/go-jose.v2/asymmetric.go
deleted file mode 100644
index 43f9ce2fc70..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/asymmetric.go
+++ /dev/null
@@ -1,595 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package jose
-
-import (
- "crypto"
- "crypto/aes"
- "crypto/ecdsa"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha1"
- "crypto/sha256"
- "errors"
- "fmt"
- "math/big"
-
- "golang.org/x/crypto/ed25519"
- josecipher "gopkg.in/go-jose/go-jose.v2/cipher"
- "gopkg.in/go-jose/go-jose.v2/json"
-)
-
-// A generic RSA-based encrypter/verifier
-type rsaEncrypterVerifier struct {
- publicKey *rsa.PublicKey
-}
-
-// A generic RSA-based decrypter/signer
-type rsaDecrypterSigner struct {
- privateKey *rsa.PrivateKey
-}
-
-// A generic EC-based encrypter/verifier
-type ecEncrypterVerifier struct {
- publicKey *ecdsa.PublicKey
-}
-
-type edEncrypterVerifier struct {
- publicKey ed25519.PublicKey
-}
-
-// A key generator for ECDH-ES
-type ecKeyGenerator struct {
- size int
- algID string
- publicKey *ecdsa.PublicKey
-}
-
-// A generic EC-based decrypter/signer
-type ecDecrypterSigner struct {
- privateKey *ecdsa.PrivateKey
-}
-
-type edDecrypterSigner struct {
- privateKey ed25519.PrivateKey
-}
-
-// newRSARecipient creates recipientKeyInfo based on the given key.
-func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) {
- // Verify that key management algorithm is supported by this encrypter
- switch keyAlg {
- case RSA1_5, RSA_OAEP, RSA_OAEP_256:
- default:
- return recipientKeyInfo{}, ErrUnsupportedAlgorithm
- }
-
- if publicKey == nil {
- return recipientKeyInfo{}, errors.New("invalid public key")
- }
-
- return recipientKeyInfo{
- keyAlg: keyAlg,
- keyEncrypter: &rsaEncrypterVerifier{
- publicKey: publicKey,
- },
- }, nil
-}
-
-// newRSASigner creates a recipientSigInfo based on the given key.
-func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) {
- // Verify that key management algorithm is supported by this encrypter
- switch sigAlg {
- case RS256, RS384, RS512, PS256, PS384, PS512:
- default:
- return recipientSigInfo{}, ErrUnsupportedAlgorithm
- }
-
- if privateKey == nil {
- return recipientSigInfo{}, errors.New("invalid private key")
- }
-
- return recipientSigInfo{
- sigAlg: sigAlg,
- publicKey: staticPublicKey(&JSONWebKey{
- Key: privateKey.Public(),
- }),
- signer: &rsaDecrypterSigner{
- privateKey: privateKey,
- },
- }, nil
-}
-
-func newEd25519Signer(sigAlg SignatureAlgorithm, privateKey ed25519.PrivateKey) (recipientSigInfo, error) {
- if sigAlg != EdDSA {
- return recipientSigInfo{}, ErrUnsupportedAlgorithm
- }
-
- if privateKey == nil {
- return recipientSigInfo{}, errors.New("invalid private key")
- }
- return recipientSigInfo{
- sigAlg: sigAlg,
- publicKey: staticPublicKey(&JSONWebKey{
- Key: privateKey.Public(),
- }),
- signer: &edDecrypterSigner{
- privateKey: privateKey,
- },
- }, nil
-}
-
-// newECDHRecipient creates recipientKeyInfo based on the given key.
-func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) {
- // Verify that key management algorithm is supported by this encrypter
- switch keyAlg {
- case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
- default:
- return recipientKeyInfo{}, ErrUnsupportedAlgorithm
- }
-
- if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
- return recipientKeyInfo{}, errors.New("invalid public key")
- }
-
- return recipientKeyInfo{
- keyAlg: keyAlg,
- keyEncrypter: &ecEncrypterVerifier{
- publicKey: publicKey,
- },
- }, nil
-}
-
-// newECDSASigner creates a recipientSigInfo based on the given key.
-func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) {
- // Verify that key management algorithm is supported by this encrypter
- switch sigAlg {
- case ES256, ES384, ES512:
- default:
- return recipientSigInfo{}, ErrUnsupportedAlgorithm
- }
-
- if privateKey == nil {
- return recipientSigInfo{}, errors.New("invalid private key")
- }
-
- return recipientSigInfo{
- sigAlg: sigAlg,
- publicKey: staticPublicKey(&JSONWebKey{
- Key: privateKey.Public(),
- }),
- signer: &ecDecrypterSigner{
- privateKey: privateKey,
- },
- }, nil
-}
-
-// Encrypt the given payload and update the object.
-func (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
- encryptedKey, err := ctx.encrypt(cek, alg)
- if err != nil {
- return recipientInfo{}, err
- }
-
- return recipientInfo{
- encryptedKey: encryptedKey,
- header: &rawHeader{},
- }, nil
-}
-
-// Encrypt the given payload. Based on the key encryption algorithm,
-// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
-func (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) {
- switch alg {
- case RSA1_5:
- return rsa.EncryptPKCS1v15(RandReader, ctx.publicKey, cek)
- case RSA_OAEP:
- return rsa.EncryptOAEP(sha1.New(), RandReader, ctx.publicKey, cek, []byte{})
- case RSA_OAEP_256:
- return rsa.EncryptOAEP(sha256.New(), RandReader, ctx.publicKey, cek, []byte{})
- }
-
- return nil, ErrUnsupportedAlgorithm
-}
-
-// Decrypt the given payload and return the content encryption key.
-func (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
- return ctx.decrypt(recipient.encryptedKey, headers.getAlgorithm(), generator)
-}
-
-// Decrypt the given payload. Based on the key encryption algorithm,
-// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
-func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) {
- // Note: The random reader on decrypt operations is only used for blinding,
- // so stubbing is meanlingless (hence the direct use of rand.Reader).
- switch alg {
- case RSA1_5:
- defer func() {
- // DecryptPKCS1v15SessionKey sometimes panics on an invalid payload
- // because of an index out of bounds error, which we want to ignore.
- // This has been fixed in Go 1.3.1 (released 2014/08/13), the recover()
- // only exists for preventing crashes with unpatched versions.
- // See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k
- // See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33
- _ = recover()
- }()
-
- // Perform some input validation.
- keyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8
- if keyBytes != len(jek) {
- // Input size is incorrect, the encrypted payload should always match
- // the size of the public modulus (e.g. using a 2048 bit key will
- // produce 256 bytes of output). Reject this since it's invalid input.
- return nil, ErrCryptoFailure
- }
-
- cek, _, err := generator.genKey()
- if err != nil {
- return nil, ErrCryptoFailure
- }
-
- // When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to
- // prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing
- // the Million Message Attack on Cryptographic Message Syntax". We are
- // therefore deliberately ignoring errors here.
- _ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek)
-
- return cek, nil
- case RSA_OAEP:
- // Use rand.Reader for RSA blinding
- return rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{})
- case RSA_OAEP_256:
- // Use rand.Reader for RSA blinding
- return rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{})
- }
-
- return nil, ErrUnsupportedAlgorithm
-}
-
-// Sign the given payload
-func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
- var hash crypto.Hash
-
- switch alg {
- case RS256, PS256:
- hash = crypto.SHA256
- case RS384, PS384:
- hash = crypto.SHA384
- case RS512, PS512:
- hash = crypto.SHA512
- default:
- return Signature{}, ErrUnsupportedAlgorithm
- }
-
- hasher := hash.New()
-
- // According to documentation, Write() on hash never fails
- _, _ = hasher.Write(payload)
- hashed := hasher.Sum(nil)
-
- var out []byte
- var err error
-
- switch alg {
- case RS256, RS384, RS512:
- // TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the
- // random parameter is legacy and ignored, and it can be nil.
- // https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1
- out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)
- case PS256, PS384, PS512:
- out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthEqualsHash,
- })
- }
-
- if err != nil {
- return Signature{}, err
- }
-
- return Signature{
- Signature: out,
- protected: &rawHeader{},
- }, nil
-}
-
-// Verify the given payload
-func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
- var hash crypto.Hash
-
- switch alg {
- case RS256, PS256:
- hash = crypto.SHA256
- case RS384, PS384:
- hash = crypto.SHA384
- case RS512, PS512:
- hash = crypto.SHA512
- default:
- return ErrUnsupportedAlgorithm
- }
-
- hasher := hash.New()
-
- // According to documentation, Write() on hash never fails
- _, _ = hasher.Write(payload)
- hashed := hasher.Sum(nil)
-
- switch alg {
- case RS256, RS384, RS512:
- return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature)
- case PS256, PS384, PS512:
- return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil)
- }
-
- return ErrUnsupportedAlgorithm
-}
-
-// Encrypt the given payload and update the object.
-func (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
- switch alg {
- case ECDH_ES:
- // ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key.
- return recipientInfo{
- header: &rawHeader{},
- }, nil
- case ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
- default:
- return recipientInfo{}, ErrUnsupportedAlgorithm
- }
-
- generator := ecKeyGenerator{
- algID: string(alg),
- publicKey: ctx.publicKey,
- }
-
- switch alg {
- case ECDH_ES_A128KW:
- generator.size = 16
- case ECDH_ES_A192KW:
- generator.size = 24
- case ECDH_ES_A256KW:
- generator.size = 32
- }
-
- kek, header, err := generator.genKey()
- if err != nil {
- return recipientInfo{}, err
- }
-
- block, err := aes.NewCipher(kek)
- if err != nil {
- return recipientInfo{}, err
- }
-
- jek, err := josecipher.KeyWrap(block, cek)
- if err != nil {
- return recipientInfo{}, err
- }
-
- return recipientInfo{
- encryptedKey: jek,
- header: &header,
- }, nil
-}
-
-// Get key size for EC key generator
-func (ctx ecKeyGenerator) keySize() int {
- return ctx.size
-}
-
-// Get a content encryption key for ECDH-ES
-func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {
- priv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, RandReader)
- if err != nil {
- return nil, rawHeader{}, err
- }
-
- out := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size)
-
- b, err := json.Marshal(&JSONWebKey{
- Key: &priv.PublicKey,
- })
- if err != nil {
- return nil, nil, err
- }
-
- headers := rawHeader{
- headerEPK: makeRawMessage(b),
- }
-
- return out, headers, nil
-}
-
-// Decrypt the given payload and return the content encryption key.
-func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
- epk, err := headers.getEPK()
- if err != nil {
- return nil, errors.New("go-jose/go-jose: invalid epk header")
- }
- if epk == nil {
- return nil, errors.New("go-jose/go-jose: missing epk header")
- }
-
- publicKey, ok := epk.Key.(*ecdsa.PublicKey)
- if publicKey == nil || !ok {
- return nil, errors.New("go-jose/go-jose: invalid epk header")
- }
-
- if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
- return nil, errors.New("go-jose/go-jose: invalid public key in epk header")
- }
-
- apuData, err := headers.getAPU()
- if err != nil {
- return nil, errors.New("go-jose/go-jose: invalid apu header")
- }
- apvData, err := headers.getAPV()
- if err != nil {
- return nil, errors.New("go-jose/go-jose: invalid apv header")
- }
-
- deriveKey := func(algID string, size int) []byte {
- return josecipher.DeriveECDHES(algID, apuData.bytes(), apvData.bytes(), ctx.privateKey, publicKey, size)
- }
-
- var keySize int
-
- algorithm := headers.getAlgorithm()
- switch algorithm {
- case ECDH_ES:
- // ECDH-ES uses direct key agreement, no key unwrapping necessary.
- return deriveKey(string(headers.getEncryption()), generator.keySize()), nil
- case ECDH_ES_A128KW:
- keySize = 16
- case ECDH_ES_A192KW:
- keySize = 24
- case ECDH_ES_A256KW:
- keySize = 32
- default:
- return nil, ErrUnsupportedAlgorithm
- }
-
- key := deriveKey(string(algorithm), keySize)
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, err
- }
-
- return josecipher.KeyUnwrap(block, recipient.encryptedKey)
-}
-
-func (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
- if alg != EdDSA {
- return Signature{}, ErrUnsupportedAlgorithm
- }
-
- sig, err := ctx.privateKey.Sign(RandReader, payload, crypto.Hash(0))
- if err != nil {
- return Signature{}, err
- }
-
- return Signature{
- Signature: sig,
- protected: &rawHeader{},
- }, nil
-}
-
-func (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
- if alg != EdDSA {
- return ErrUnsupportedAlgorithm
- }
- ok := ed25519.Verify(ctx.publicKey, payload, signature)
- if !ok {
- return errors.New("go-jose/go-jose: ed25519 signature failed to verify")
- }
- return nil
-}
-
-// Sign the given payload
-func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
- var expectedBitSize int
- var hash crypto.Hash
-
- switch alg {
- case ES256:
- expectedBitSize = 256
- hash = crypto.SHA256
- case ES384:
- expectedBitSize = 384
- hash = crypto.SHA384
- case ES512:
- expectedBitSize = 521
- hash = crypto.SHA512
- }
-
- curveBits := ctx.privateKey.Curve.Params().BitSize
- if expectedBitSize != curveBits {
- return Signature{}, fmt.Errorf("go-jose/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits)
- }
-
- hasher := hash.New()
-
- // According to documentation, Write() on hash never fails
- _, _ = hasher.Write(payload)
- hashed := hasher.Sum(nil)
-
- r, s, err := ecdsa.Sign(RandReader, ctx.privateKey, hashed)
- if err != nil {
- return Signature{}, err
- }
-
- keyBytes := curveBits / 8
- if curveBits%8 > 0 {
- keyBytes++
- }
-
- // We serialize the outputs (r and s) into big-endian byte arrays and pad
- // them with zeros on the left to make sure the sizes work out. Both arrays
- // must be keyBytes long, and the output must be 2*keyBytes long.
- rBytes := r.Bytes()
- rBytesPadded := make([]byte, keyBytes)
- copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
-
- sBytes := s.Bytes()
- sBytesPadded := make([]byte, keyBytes)
- copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
-
- out := append(rBytesPadded, sBytesPadded...)
-
- return Signature{
- Signature: out,
- protected: &rawHeader{},
- }, nil
-}
-
-// Verify the given payload
-func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
- var keySize int
- var hash crypto.Hash
-
- switch alg {
- case ES256:
- keySize = 32
- hash = crypto.SHA256
- case ES384:
- keySize = 48
- hash = crypto.SHA384
- case ES512:
- keySize = 66
- hash = crypto.SHA512
- default:
- return ErrUnsupportedAlgorithm
- }
-
- if len(signature) != 2*keySize {
- return fmt.Errorf("go-jose/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize)
- }
-
- hasher := hash.New()
-
- // According to documentation, Write() on hash never fails
- _, _ = hasher.Write(payload)
- hashed := hasher.Sum(nil)
-
- r := big.NewInt(0).SetBytes(signature[:keySize])
- s := big.NewInt(0).SetBytes(signature[keySize:])
-
- match := ecdsa.Verify(ctx.publicKey, hashed, r, s)
- if !match {
- return errors.New("go-jose/go-jose: ecdsa signature failed to verify")
- }
-
- return nil
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/cbc_hmac.go b/vendor/gopkg.in/go-jose/go-jose.v2/cipher/cbc_hmac.go
deleted file mode 100644
index 87065a5b96e..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/cbc_hmac.go
+++ /dev/null
@@ -1,196 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package josecipher
-
-import (
- "bytes"
- "crypto/cipher"
- "crypto/hmac"
- "crypto/sha256"
- "crypto/sha512"
- "crypto/subtle"
- "encoding/binary"
- "errors"
- "hash"
-)
-
-const (
- nonceBytes = 16
-)
-
-// NewCBCHMAC instantiates a new AEAD based on CBC+HMAC.
-func NewCBCHMAC(key []byte, newBlockCipher func([]byte) (cipher.Block, error)) (cipher.AEAD, error) {
- keySize := len(key) / 2
- integrityKey := key[:keySize]
- encryptionKey := key[keySize:]
-
- blockCipher, err := newBlockCipher(encryptionKey)
- if err != nil {
- return nil, err
- }
-
- var hash func() hash.Hash
- switch keySize {
- case 16:
- hash = sha256.New
- case 24:
- hash = sha512.New384
- case 32:
- hash = sha512.New
- }
-
- return &cbcAEAD{
- hash: hash,
- blockCipher: blockCipher,
- authtagBytes: keySize,
- integrityKey: integrityKey,
- }, nil
-}
-
-// An AEAD based on CBC+HMAC
-type cbcAEAD struct {
- hash func() hash.Hash
- authtagBytes int
- integrityKey []byte
- blockCipher cipher.Block
-}
-
-func (ctx *cbcAEAD) NonceSize() int {
- return nonceBytes
-}
-
-func (ctx *cbcAEAD) Overhead() int {
- // Maximum overhead is block size (for padding) plus auth tag length, where
- // the length of the auth tag is equivalent to the key size.
- return ctx.blockCipher.BlockSize() + ctx.authtagBytes
-}
-
-// Seal encrypts and authenticates the plaintext.
-func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
- // Output buffer -- must take care not to mangle plaintext input.
- ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)]
- copy(ciphertext, plaintext)
- ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize())
-
- cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce)
-
- cbc.CryptBlocks(ciphertext, ciphertext)
- authtag := ctx.computeAuthTag(data, nonce, ciphertext)
-
- ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag)))
- copy(out, ciphertext)
- copy(out[len(ciphertext):], authtag)
-
- return ret
-}
-
-// Open decrypts and authenticates the ciphertext.
-func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
- if len(ciphertext) < ctx.authtagBytes {
- return nil, errors.New("go-jose/go-jose: invalid ciphertext (too short)")
- }
-
- offset := len(ciphertext) - ctx.authtagBytes
- expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset])
- match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:])
- if match != 1 {
- return nil, errors.New("go-jose/go-jose: invalid ciphertext (auth tag mismatch)")
- }
-
- cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce)
-
- // Make copy of ciphertext buffer, don't want to modify in place
- buffer := append([]byte{}, []byte(ciphertext[:offset])...)
-
- if len(buffer)%ctx.blockCipher.BlockSize() > 0 {
- return nil, errors.New("go-jose/go-jose: invalid ciphertext (invalid length)")
- }
-
- cbc.CryptBlocks(buffer, buffer)
-
- // Remove padding
- plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize())
- if err != nil {
- return nil, err
- }
-
- ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext)))
- copy(out, plaintext)
-
- return ret, nil
-}
-
-// Compute an authentication tag
-func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
- buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8)
- n := 0
- n += copy(buffer, aad)
- n += copy(buffer[n:], nonce)
- n += copy(buffer[n:], ciphertext)
- binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8)
-
- // According to documentation, Write() on hash.Hash never fails.
- hmac := hmac.New(ctx.hash, ctx.integrityKey)
- _, _ = hmac.Write(buffer)
-
- return hmac.Sum(nil)[:ctx.authtagBytes]
-}
-
-// resize ensures that the given slice has a capacity of at least n bytes.
-// If the capacity of the slice is less than n, a new slice is allocated
-// and the existing data will be copied.
-func resize(in []byte, n uint64) (head, tail []byte) {
- if uint64(cap(in)) >= n {
- head = in[:n]
- } else {
- head = make([]byte, n)
- copy(head, in)
- }
-
- tail = head[len(in):]
- return
-}
-
-// Apply padding
-func padBuffer(buffer []byte, blockSize int) []byte {
- missing := blockSize - (len(buffer) % blockSize)
- ret, out := resize(buffer, uint64(len(buffer))+uint64(missing))
- padding := bytes.Repeat([]byte{byte(missing)}, missing)
- copy(out, padding)
- return ret
-}
-
-// Remove padding
-func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) {
- if len(buffer)%blockSize != 0 {
- return nil, errors.New("go-jose/go-jose: invalid padding")
- }
-
- last := buffer[len(buffer)-1]
- count := int(last)
-
- if count == 0 || count > blockSize || count > len(buffer) {
- return nil, errors.New("go-jose/go-jose: invalid padding")
- }
-
- padding := bytes.Repeat([]byte{last}, count)
- if !bytes.HasSuffix(buffer, padding) {
- return nil, errors.New("go-jose/go-jose: invalid padding")
- }
-
- return buffer[:len(buffer)-count], nil
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/concat_kdf.go b/vendor/gopkg.in/go-jose/go-jose.v2/cipher/concat_kdf.go
deleted file mode 100644
index f62c3bdba5d..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/concat_kdf.go
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package josecipher
-
-import (
- "crypto"
- "encoding/binary"
- "hash"
- "io"
-)
-
-type concatKDF struct {
- z, info []byte
- i uint32
- cache []byte
- hasher hash.Hash
-}
-
-// NewConcatKDF builds a KDF reader based on the given inputs.
-func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader {
- buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo)))
- n := 0
- n += copy(buffer, algID)
- n += copy(buffer[n:], ptyUInfo)
- n += copy(buffer[n:], ptyVInfo)
- n += copy(buffer[n:], supPubInfo)
- copy(buffer[n:], supPrivInfo)
-
- hasher := hash.New()
-
- return &concatKDF{
- z: z,
- info: buffer,
- hasher: hasher,
- cache: []byte{},
- i: 1,
- }
-}
-
-func (ctx *concatKDF) Read(out []byte) (int, error) {
- copied := copy(out, ctx.cache)
- ctx.cache = ctx.cache[copied:]
-
- for copied < len(out) {
- ctx.hasher.Reset()
-
- // Write on a hash.Hash never fails
- _ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i)
- _, _ = ctx.hasher.Write(ctx.z)
- _, _ = ctx.hasher.Write(ctx.info)
-
- hash := ctx.hasher.Sum(nil)
- chunkCopied := copy(out[copied:], hash)
- copied += chunkCopied
- ctx.cache = hash[chunkCopied:]
-
- ctx.i++
- }
-
- return copied, nil
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/ecdh_es.go b/vendor/gopkg.in/go-jose/go-jose.v2/cipher/ecdh_es.go
deleted file mode 100644
index 093c646740b..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/ecdh_es.go
+++ /dev/null
@@ -1,86 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package josecipher
-
-import (
- "bytes"
- "crypto"
- "crypto/ecdsa"
- "crypto/elliptic"
- "encoding/binary"
-)
-
-// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA.
-// It is an error to call this function with a private/public key that are not on the same
-// curve. Callers must ensure that the keys are valid before calling this function. Output
-// size may be at most 1<<16 bytes (64 KiB).
-func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte {
- if size > 1<<16 {
- panic("ECDH-ES output size too large, must be less than or equal to 1<<16")
- }
-
- // algId, partyUInfo, partyVInfo inputs must be prefixed with the length
- algID := lengthPrefixed([]byte(alg))
- ptyUInfo := lengthPrefixed(apuData)
- ptyVInfo := lengthPrefixed(apvData)
-
- // suppPubInfo is the encoded length of the output size in bits
- supPubInfo := make([]byte, 4)
- binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8)
-
- if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) {
- panic("public key not on same curve as private key")
- }
-
- z, _ := priv.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
- zBytes := z.Bytes()
-
- // Note that calling z.Bytes() on a big.Int may strip leading zero bytes from
- // the returned byte array. This can lead to a problem where zBytes will be
- // shorter than expected which breaks the key derivation. Therefore we must pad
- // to the full length of the expected coordinate here before calling the KDF.
- octSize := dSize(priv.Curve)
- if len(zBytes) != octSize {
- zBytes = append(bytes.Repeat([]byte{0}, octSize-len(zBytes)), zBytes...)
- }
-
- reader := NewConcatKDF(crypto.SHA256, zBytes, algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
- key := make([]byte, size)
-
- // Read on the KDF will never fail
- _, _ = reader.Read(key)
-
- return key
-}
-
-// dSize returns the size in octets for a coordinate on a elliptic curve.
-func dSize(curve elliptic.Curve) int {
- order := curve.Params().P
- bitLen := order.BitLen()
- size := bitLen / 8
- if bitLen%8 != 0 {
- size++
- }
- return size
-}
-
-func lengthPrefixed(data []byte) []byte {
- out := make([]byte, len(data)+4)
- binary.BigEndian.PutUint32(out, uint32(len(data)))
- copy(out[4:], data)
- return out
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/key_wrap.go b/vendor/gopkg.in/go-jose/go-jose.v2/cipher/key_wrap.go
deleted file mode 100644
index 668358f981b..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/cipher/key_wrap.go
+++ /dev/null
@@ -1,109 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package josecipher
-
-import (
- "crypto/cipher"
- "crypto/subtle"
- "encoding/binary"
- "errors"
-)
-
-var defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}
-
-// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher.
-func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {
- if len(cek)%8 != 0 {
- return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
- }
-
- n := len(cek) / 8
- r := make([][]byte, n)
-
- for i := range r {
- r[i] = make([]byte, 8)
- copy(r[i], cek[i*8:])
- }
-
- buffer := make([]byte, 16)
- tBytes := make([]byte, 8)
- copy(buffer, defaultIV)
-
- for t := 0; t < 6*n; t++ {
- copy(buffer[8:], r[t%n])
-
- block.Encrypt(buffer, buffer)
-
- binary.BigEndian.PutUint64(tBytes, uint64(t+1))
-
- for i := 0; i < 8; i++ {
- buffer[i] = buffer[i] ^ tBytes[i]
- }
- copy(r[t%n], buffer[8:])
- }
-
- out := make([]byte, (n+1)*8)
- copy(out, buffer[:8])
- for i := range r {
- copy(out[(i+1)*8:], r[i])
- }
-
- return out, nil
-}
-
-// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher.
-func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
- if len(ciphertext)%8 != 0 {
- return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
- }
-
- n := (len(ciphertext) / 8) - 1
- r := make([][]byte, n)
-
- for i := range r {
- r[i] = make([]byte, 8)
- copy(r[i], ciphertext[(i+1)*8:])
- }
-
- buffer := make([]byte, 16)
- tBytes := make([]byte, 8)
- copy(buffer[:8], ciphertext[:8])
-
- for t := 6*n - 1; t >= 0; t-- {
- binary.BigEndian.PutUint64(tBytes, uint64(t+1))
-
- for i := 0; i < 8; i++ {
- buffer[i] = buffer[i] ^ tBytes[i]
- }
- copy(buffer[8:], r[t%n])
-
- block.Decrypt(buffer, buffer)
-
- copy(r[t%n], buffer[8:])
- }
-
- if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 {
- return nil, errors.New("go-jose/go-jose: failed to unwrap key")
- }
-
- out := make([]byte, n*8)
- for i := range r {
- copy(out[i*8:], r[i])
- }
-
- return out, nil
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/crypter.go b/vendor/gopkg.in/go-jose/go-jose.v2/crypter.go
deleted file mode 100644
index 0ae2e5ebaa7..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/crypter.go
+++ /dev/null
@@ -1,548 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package jose
-
-import (
- "crypto/ecdsa"
- "crypto/rsa"
- "errors"
- "fmt"
- "reflect"
-
- "gopkg.in/go-jose/go-jose.v2/json"
-)
-
-// Encrypter represents an encrypter which produces an encrypted JWE object.
-type Encrypter interface {
- Encrypt(plaintext []byte) (*JSONWebEncryption, error)
- EncryptWithAuthData(plaintext []byte, aad []byte) (*JSONWebEncryption, error)
- Options() EncrypterOptions
-}
-
-// A generic content cipher
-type contentCipher interface {
- keySize() int
- encrypt(cek []byte, aad, plaintext []byte) (*aeadParts, error)
- decrypt(cek []byte, aad []byte, parts *aeadParts) ([]byte, error)
-}
-
-// A key generator (for generating/getting a CEK)
-type keyGenerator interface {
- keySize() int
- genKey() ([]byte, rawHeader, error)
-}
-
-// A generic key encrypter
-type keyEncrypter interface {
- encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) // Encrypt a key
-}
-
-// A generic key decrypter
-type keyDecrypter interface {
- decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) // Decrypt a key
-}
-
-// A generic encrypter based on the given key encrypter and content cipher.
-type genericEncrypter struct {
- contentAlg ContentEncryption
- compressionAlg CompressionAlgorithm
- cipher contentCipher
- recipients []recipientKeyInfo
- keyGenerator keyGenerator
- extraHeaders map[HeaderKey]interface{}
-}
-
-type recipientKeyInfo struct {
- keyID string
- keyAlg KeyAlgorithm
- keyEncrypter keyEncrypter
-}
-
-// EncrypterOptions represents options that can be set on new encrypters.
-type EncrypterOptions struct {
- Compression CompressionAlgorithm
-
- // Optional map of additional keys to be inserted into the protected header
- // of a JWS object. Some specifications which make use of JWS like to insert
- // additional values here. All values must be JSON-serializable.
- ExtraHeaders map[HeaderKey]interface{}
-}
-
-// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
-// if necessary. It returns itself and so can be used in a fluent style.
-func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions {
- if eo.ExtraHeaders == nil {
- eo.ExtraHeaders = map[HeaderKey]interface{}{}
- }
- eo.ExtraHeaders[k] = v
- return eo
-}
-
-// WithContentType adds a content type ("cty") header and returns the updated
-// EncrypterOptions.
-func (eo *EncrypterOptions) WithContentType(contentType ContentType) *EncrypterOptions {
- return eo.WithHeader(HeaderContentType, contentType)
-}
-
-// WithType adds a type ("typ") header and returns the updated EncrypterOptions.
-func (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions {
- return eo.WithHeader(HeaderType, typ)
-}
-
-// Recipient represents an algorithm/key to encrypt messages to.
-//
-// PBES2Count and PBES2Salt correspond with the "p2c" and "p2s" headers used
-// on the password-based encryption algorithms PBES2-HS256+A128KW,
-// PBES2-HS384+A192KW, and PBES2-HS512+A256KW. If they are not provided a safe
-// default of 100000 will be used for the count and a 128-bit random salt will
-// be generated.
-type Recipient struct {
- Algorithm KeyAlgorithm
- Key interface{}
- KeyID string
- PBES2Count int
- PBES2Salt []byte
-}
-
-// NewEncrypter creates an appropriate encrypter based on the key type
-func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions) (Encrypter, error) {
- encrypter := &genericEncrypter{
- contentAlg: enc,
- recipients: []recipientKeyInfo{},
- cipher: getContentCipher(enc),
- }
- if opts != nil {
- encrypter.compressionAlg = opts.Compression
- encrypter.extraHeaders = opts.ExtraHeaders
- }
-
- if encrypter.cipher == nil {
- return nil, ErrUnsupportedAlgorithm
- }
-
- var keyID string
- var rawKey interface{}
- switch encryptionKey := rcpt.Key.(type) {
- case JSONWebKey:
- keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key
- case *JSONWebKey:
- keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key
- case OpaqueKeyEncrypter:
- keyID, rawKey = encryptionKey.KeyID(), encryptionKey
- default:
- rawKey = encryptionKey
- }
-
- switch rcpt.Algorithm {
- case DIRECT:
- // Direct encryption mode must be treated differently
- if reflect.TypeOf(rawKey) != reflect.TypeOf([]byte{}) {
- return nil, ErrUnsupportedKeyType
- }
- if encrypter.cipher.keySize() != len(rawKey.([]byte)) {
- return nil, ErrInvalidKeySize
- }
- encrypter.keyGenerator = staticKeyGenerator{
- key: rawKey.([]byte),
- }
- recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, rawKey.([]byte))
- recipientInfo.keyID = keyID
- if rcpt.KeyID != "" {
- recipientInfo.keyID = rcpt.KeyID
- }
- encrypter.recipients = []recipientKeyInfo{recipientInfo}
- return encrypter, nil
- case ECDH_ES:
- // ECDH-ES (w/o key wrapping) is similar to DIRECT mode
- typeOf := reflect.TypeOf(rawKey)
- if typeOf != reflect.TypeOf(&ecdsa.PublicKey{}) {
- return nil, ErrUnsupportedKeyType
- }
- encrypter.keyGenerator = ecKeyGenerator{
- size: encrypter.cipher.keySize(),
- algID: string(enc),
- publicKey: rawKey.(*ecdsa.PublicKey),
- }
- recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, rawKey.(*ecdsa.PublicKey))
- recipientInfo.keyID = keyID
- if rcpt.KeyID != "" {
- recipientInfo.keyID = rcpt.KeyID
- }
- encrypter.recipients = []recipientKeyInfo{recipientInfo}
- return encrypter, nil
- default:
- // Can just add a standard recipient
- encrypter.keyGenerator = randomKeyGenerator{
- size: encrypter.cipher.keySize(),
- }
- err := encrypter.addRecipient(rcpt)
- return encrypter, err
- }
-}
-
-// NewMultiEncrypter creates a multi-encrypter based on the given parameters
-func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *EncrypterOptions) (Encrypter, error) {
- cipher := getContentCipher(enc)
-
- if cipher == nil {
- return nil, ErrUnsupportedAlgorithm
- }
- if rcpts == nil || len(rcpts) == 0 {
- return nil, fmt.Errorf("go-jose/go-jose: recipients is nil or empty")
- }
-
- encrypter := &genericEncrypter{
- contentAlg: enc,
- recipients: []recipientKeyInfo{},
- cipher: cipher,
- keyGenerator: randomKeyGenerator{
- size: cipher.keySize(),
- },
- }
-
- if opts != nil {
- encrypter.compressionAlg = opts.Compression
- encrypter.extraHeaders = opts.ExtraHeaders
- }
-
- for _, recipient := range rcpts {
- err := encrypter.addRecipient(recipient)
- if err != nil {
- return nil, err
- }
- }
-
- return encrypter, nil
-}
-
-func (ctx *genericEncrypter) addRecipient(recipient Recipient) (err error) {
- var recipientInfo recipientKeyInfo
-
- switch recipient.Algorithm {
- case DIRECT, ECDH_ES:
- return fmt.Errorf("go-jose/go-jose: key algorithm '%s' not supported in multi-recipient mode", recipient.Algorithm)
- }
-
- recipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key)
- if recipient.KeyID != "" {
- recipientInfo.keyID = recipient.KeyID
- }
-
- switch recipient.Algorithm {
- case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:
- if sr, ok := recipientInfo.keyEncrypter.(*symmetricKeyCipher); ok {
- sr.p2c = recipient.PBES2Count
- sr.p2s = recipient.PBES2Salt
- }
- }
-
- if err == nil {
- ctx.recipients = append(ctx.recipients, recipientInfo)
- }
- return err
-}
-
-func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKeyInfo, error) {
- switch encryptionKey := encryptionKey.(type) {
- case *rsa.PublicKey:
- return newRSARecipient(alg, encryptionKey)
- case *ecdsa.PublicKey:
- return newECDHRecipient(alg, encryptionKey)
- case []byte:
- return newSymmetricRecipient(alg, encryptionKey)
- case string:
- return newSymmetricRecipient(alg, []byte(encryptionKey))
- case *JSONWebKey:
- recipient, err := makeJWERecipient(alg, encryptionKey.Key)
- recipient.keyID = encryptionKey.KeyID
- return recipient, err
- }
- if encrypter, ok := encryptionKey.(OpaqueKeyEncrypter); ok {
- return newOpaqueKeyEncrypter(alg, encrypter)
- }
- return recipientKeyInfo{}, ErrUnsupportedKeyType
-}
-
-// newDecrypter creates an appropriate decrypter based on the key type
-func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) {
- switch decryptionKey := decryptionKey.(type) {
- case *rsa.PrivateKey:
- return &rsaDecrypterSigner{
- privateKey: decryptionKey,
- }, nil
- case *ecdsa.PrivateKey:
- return &ecDecrypterSigner{
- privateKey: decryptionKey,
- }, nil
- case []byte:
- return &symmetricKeyCipher{
- key: decryptionKey,
- }, nil
- case string:
- return &symmetricKeyCipher{
- key: []byte(decryptionKey),
- }, nil
- case JSONWebKey:
- return newDecrypter(decryptionKey.Key)
- case *JSONWebKey:
- return newDecrypter(decryptionKey.Key)
- }
- if okd, ok := decryptionKey.(OpaqueKeyDecrypter); ok {
- return &opaqueKeyDecrypter{decrypter: okd}, nil
- }
- return nil, ErrUnsupportedKeyType
-}
-
-// Implementation of encrypt method producing a JWE object.
-func (ctx *genericEncrypter) Encrypt(plaintext []byte) (*JSONWebEncryption, error) {
- return ctx.EncryptWithAuthData(plaintext, nil)
-}
-
-// Implementation of encrypt method producing a JWE object.
-func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JSONWebEncryption, error) {
- obj := &JSONWebEncryption{}
- obj.aad = aad
-
- obj.protected = &rawHeader{}
- err := obj.protected.set(headerEncryption, ctx.contentAlg)
- if err != nil {
- return nil, err
- }
-
- obj.recipients = make([]recipientInfo, len(ctx.recipients))
-
- if len(ctx.recipients) == 0 {
- return nil, fmt.Errorf("go-jose/go-jose: no recipients to encrypt to")
- }
-
- cek, headers, err := ctx.keyGenerator.genKey()
- if err != nil {
- return nil, err
- }
-
- obj.protected.merge(&headers)
-
- for i, info := range ctx.recipients {
- recipient, err := info.keyEncrypter.encryptKey(cek, info.keyAlg)
- if err != nil {
- return nil, err
- }
-
- err = recipient.header.set(headerAlgorithm, info.keyAlg)
- if err != nil {
- return nil, err
- }
-
- if info.keyID != "" {
- err = recipient.header.set(headerKeyID, info.keyID)
- if err != nil {
- return nil, err
- }
- }
- obj.recipients[i] = recipient
- }
-
- if len(ctx.recipients) == 1 {
- // Move per-recipient headers into main protected header if there's
- // only a single recipient.
- obj.protected.merge(obj.recipients[0].header)
- obj.recipients[0].header = nil
- }
-
- if ctx.compressionAlg != NONE {
- plaintext, err = compress(ctx.compressionAlg, plaintext)
- if err != nil {
- return nil, err
- }
-
- err = obj.protected.set(headerCompression, ctx.compressionAlg)
- if err != nil {
- return nil, err
- }
- }
-
- for k, v := range ctx.extraHeaders {
- b, err := json.Marshal(v)
- if err != nil {
- return nil, err
- }
- (*obj.protected)[k] = makeRawMessage(b)
- }
-
- authData := obj.computeAuthData()
- parts, err := ctx.cipher.encrypt(cek, authData, plaintext)
- if err != nil {
- return nil, err
- }
-
- obj.iv = parts.iv
- obj.ciphertext = parts.ciphertext
- obj.tag = parts.tag
-
- return obj, nil
-}
-
-func (ctx *genericEncrypter) Options() EncrypterOptions {
- return EncrypterOptions{
- Compression: ctx.compressionAlg,
- ExtraHeaders: ctx.extraHeaders,
- }
-}
-
-// Decrypt and validate the object and return the plaintext. Note that this
-// function does not support multi-recipient, if you desire multi-recipient
-// decryption use DecryptMulti instead.
-//
-// Automatically decompresses plaintext, but returns an error if the decompressed
-// data would be >250kB or >10x the size of the compressed data, whichever is larger.
-func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
- headers := obj.mergedHeaders(nil)
-
- if len(obj.recipients) > 1 {
- return nil, errors.New("go-jose/go-jose: too many recipients in payload; expecting only one")
- }
-
- critical, err := headers.getCritical()
- if err != nil {
- return nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
- }
-
- if len(critical) > 0 {
- return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
- }
-
- decrypter, err := newDecrypter(decryptionKey)
- if err != nil {
- return nil, err
- }
-
- cipher := getContentCipher(headers.getEncryption())
- if cipher == nil {
- return nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(headers.getEncryption()))
- }
-
- generator := randomKeyGenerator{
- size: cipher.keySize(),
- }
-
- parts := &aeadParts{
- iv: obj.iv,
- ciphertext: obj.ciphertext,
- tag: obj.tag,
- }
-
- authData := obj.computeAuthData()
-
- var plaintext []byte
- recipient := obj.recipients[0]
- recipientHeaders := obj.mergedHeaders(&recipient)
-
- cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
- if err == nil {
- // Found a valid CEK -- let's try to decrypt.
- plaintext, err = cipher.decrypt(cek, authData, parts)
- }
-
- if plaintext == nil {
- return nil, ErrCryptoFailure
- }
-
- // The "zip" header parameter may only be present in the protected header.
- if comp := obj.protected.getCompression(); comp != "" {
- plaintext, err = decompress(comp, plaintext)
- }
-
- return plaintext, err
-}
-
-// DecryptMulti decrypts and validates the object and returns the plaintexts,
-// with support for multiple recipients. It returns the index of the recipient
-// for which the decryption was successful, the merged headers for that recipient,
-// and the plaintext.
-//
-// Automatically decompresses plaintext, but returns an error if the decompressed
-// data would be >250kB or >3x the size of the compressed data, whichever is larger.
-func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
- globalHeaders := obj.mergedHeaders(nil)
-
- critical, err := globalHeaders.getCritical()
- if err != nil {
- return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
- }
-
- if len(critical) > 0 {
- return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
- }
-
- decrypter, err := newDecrypter(decryptionKey)
- if err != nil {
- return -1, Header{}, nil, err
- }
-
- encryption := globalHeaders.getEncryption()
- cipher := getContentCipher(encryption)
- if cipher == nil {
- return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(encryption))
- }
-
- generator := randomKeyGenerator{
- size: cipher.keySize(),
- }
-
- parts := &aeadParts{
- iv: obj.iv,
- ciphertext: obj.ciphertext,
- tag: obj.tag,
- }
-
- authData := obj.computeAuthData()
-
- index := -1
- var plaintext []byte
- var headers rawHeader
-
- for i, recipient := range obj.recipients {
- recipientHeaders := obj.mergedHeaders(&recipient)
-
- cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
- if err == nil {
- // Found a valid CEK -- let's try to decrypt.
- plaintext, err = cipher.decrypt(cek, authData, parts)
- if err == nil {
- index = i
- headers = recipientHeaders
- break
- }
- }
- }
-
- if plaintext == nil || err != nil {
- return -1, Header{}, nil, ErrCryptoFailure
- }
-
- // The "zip" header parameter may only be present in the protected header.
- if comp := obj.protected.getCompression(); comp != "" {
- plaintext, err = decompress(comp, plaintext)
- }
-
- sanitized, err := headers.sanitized()
- if err != nil {
- return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to sanitize header: %v", err)
- }
-
- return index, sanitized, plaintext, err
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/doc.go b/vendor/gopkg.in/go-jose/go-jose.v2/doc.go
deleted file mode 100644
index dd1387f3f06..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/doc.go
+++ /dev/null
@@ -1,27 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
-
-Package jose aims to provide an implementation of the Javascript Object Signing
-and Encryption set of standards. It implements encryption and signing based on
-the JSON Web Encryption and JSON Web Signature standards, with optional JSON
-Web Token support available in a sub-package. The library supports both the
-compact and full serialization formats, and has optional support for multiple
-recipients.
-
-*/
-package jose
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/encoding.go b/vendor/gopkg.in/go-jose/go-jose.v2/encoding.go
deleted file mode 100644
index 636f6c8f565..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/encoding.go
+++ /dev/null
@@ -1,198 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package jose
-
-import (
- "bytes"
- "compress/flate"
- "encoding/base64"
- "encoding/binary"
- "fmt"
- "io"
- "math/big"
- "strings"
- "unicode"
-
- "gopkg.in/go-jose/go-jose.v2/json"
-)
-
-// Helper function to serialize known-good objects.
-// Precondition: value is not a nil pointer.
-func mustSerializeJSON(value interface{}) []byte {
- out, err := json.Marshal(value)
- if err != nil {
- panic(err)
- }
- // We never want to serialize the top-level value "null," since it's not a
- // valid JOSE message. But if a caller passes in a nil pointer to this method,
- // MarshalJSON will happily serialize it as the top-level value "null". If
- // that value is then embedded in another operation, for instance by being
- // base64-encoded and fed as input to a signing algorithm
- // (https://github.com/go-jose/go-jose/issues/22), the result will be
- // incorrect. Because this method is intended for known-good objects, and a nil
- // pointer is not a known-good object, we are free to panic in this case.
- // Note: It's not possible to directly check whether the data pointed at by an
- // interface is a nil pointer, so we do this hacky workaround.
- // https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I
- if string(out) == "null" {
- panic("Tried to serialize a nil pointer.")
- }
- return out
-}
-
-// Strip all newlines and whitespace
-func stripWhitespace(data string) string {
- buf := strings.Builder{}
- buf.Grow(len(data))
- for _, r := range data {
- if !unicode.IsSpace(r) {
- buf.WriteRune(r)
- }
- }
- return buf.String()
-}
-
-// Perform compression based on algorithm
-func compress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
- switch algorithm {
- case DEFLATE:
- return deflate(input)
- default:
- return nil, ErrUnsupportedAlgorithm
- }
-}
-
-// Perform decompression based on algorithm
-func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
- switch algorithm {
- case DEFLATE:
- return inflate(input)
- default:
- return nil, ErrUnsupportedAlgorithm
- }
-}
-
-// deflate compresses the input.
-func deflate(input []byte) ([]byte, error) {
- output := new(bytes.Buffer)
-
- // Writing to byte buffer, err is always nil
- writer, _ := flate.NewWriter(output, 1)
- _, _ = io.Copy(writer, bytes.NewBuffer(input))
-
- err := writer.Close()
- return output.Bytes(), err
-}
-
-// inflate decompresses the input.
-//
-// Errors if the decompressed data would be >250kB or >10x the size of the
-// compressed data, whichever is larger.
-func inflate(input []byte) ([]byte, error) {
- output := new(bytes.Buffer)
- reader := flate.NewReader(bytes.NewBuffer(input))
-
- maxCompressedSize := 10 * int64(len(input))
- if maxCompressedSize < 250000 {
- maxCompressedSize = 250000
- }
-
- limit := maxCompressedSize + 1
- n, err := io.CopyN(output, reader, limit)
- if err != nil && err != io.EOF {
- return nil, err
- }
- if n == limit {
- return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize)
- }
-
- err = reader.Close()
- return output.Bytes(), err
-}
-
-// byteBuffer represents a slice of bytes that can be serialized to url-safe base64.
-type byteBuffer struct {
- data []byte
-}
-
-func newBuffer(data []byte) *byteBuffer {
- if data == nil {
- return nil
- }
- return &byteBuffer{
- data: data,
- }
-}
-
-func newFixedSizeBuffer(data []byte, length int) *byteBuffer {
- if len(data) > length {
- panic("go-jose/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)")
- }
- pad := make([]byte, length-len(data))
- return newBuffer(append(pad, data...))
-}
-
-func newBufferFromInt(num uint64) *byteBuffer {
- data := make([]byte, 8)
- binary.BigEndian.PutUint64(data, num)
- return newBuffer(bytes.TrimLeft(data, "\x00"))
-}
-
-func (b *byteBuffer) MarshalJSON() ([]byte, error) {
- return json.Marshal(b.base64())
-}
-
-func (b *byteBuffer) UnmarshalJSON(data []byte) error {
- var encoded string
- err := json.Unmarshal(data, &encoded)
- if err != nil {
- return err
- }
-
- if encoded == "" {
- return nil
- }
-
- decoded, err := base64.RawURLEncoding.DecodeString(encoded)
- if err != nil {
- return err
- }
-
- *b = *newBuffer(decoded)
-
- return nil
-}
-
-func (b *byteBuffer) base64() string {
- return base64.RawURLEncoding.EncodeToString(b.data)
-}
-
-func (b *byteBuffer) bytes() []byte {
- // Handling nil here allows us to transparently handle nil slices when serializing.
- if b == nil {
- return nil
- }
- return b.data
-}
-
-func (b byteBuffer) bigInt() *big.Int {
- return new(big.Int).SetBytes(b.data)
-}
-
-func (b byteBuffer) toInt() int {
- return int(b.bigInt().Int64())
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/json/LICENSE b/vendor/gopkg.in/go-jose/go-jose.v2/json/LICENSE
deleted file mode 100644
index 74487567632..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/json/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2012 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
- * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/json/README.md b/vendor/gopkg.in/go-jose/go-jose.v2/json/README.md
deleted file mode 100644
index 86de5e5581f..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/json/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Safe JSON
-
-This repository contains a fork of the `encoding/json` package from Go 1.6.
-
-The following changes were made:
-
-* Object deserialization uses case-sensitive member name matching instead of
- [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html).
- This is to avoid differences in the interpretation of JOSE messages between
- go-jose and libraries written in other languages.
-* When deserializing a JSON object, we check for duplicate keys and reject the
- input whenever we detect a duplicate. Rather than trying to work with malformed
- data, we prefer to reject it right away.
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/json/decode.go b/vendor/gopkg.in/go-jose/go-jose.v2/json/decode.go
deleted file mode 100644
index 4dbc4146cf9..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/json/decode.go
+++ /dev/null
@@ -1,1217 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Represents JSON data structure using native Go types: booleans, floats,
-// strings, arrays, and maps.
-
-package json
-
-import (
- "bytes"
- "encoding"
- "encoding/base64"
- "errors"
- "fmt"
- "math"
- "reflect"
- "runtime"
- "strconv"
- "unicode"
- "unicode/utf16"
- "unicode/utf8"
-)
-
-// Unmarshal parses the JSON-encoded data and stores the result
-// in the value pointed to by v.
-//
-// Unmarshal uses the inverse of the encodings that
-// Marshal uses, allocating maps, slices, and pointers as necessary,
-// with the following additional rules:
-//
-// To unmarshal JSON into a pointer, Unmarshal first handles the case of
-// the JSON being the JSON literal null. In that case, Unmarshal sets
-// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
-// the value pointed at by the pointer. If the pointer is nil, Unmarshal
-// allocates a new value for it to point to.
-//
-// To unmarshal JSON into a struct, Unmarshal matches incoming object
-// keys to the keys used by Marshal (either the struct field name or its tag),
-// preferring an exact match but also accepting a case-insensitive match.
-// Unmarshal will only set exported fields of the struct.
-//
-// To unmarshal JSON into an interface value,
-// Unmarshal stores one of these in the interface value:
-//
-// bool, for JSON booleans
-// float64, for JSON numbers
-// string, for JSON strings
-// []interface{}, for JSON arrays
-// map[string]interface{}, for JSON objects
-// nil for JSON null
-//
-// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
-// to zero and then appends each element to the slice.
-// As a special case, to unmarshal an empty JSON array into a slice,
-// Unmarshal replaces the slice with a new empty slice.
-//
-// To unmarshal a JSON array into a Go array, Unmarshal decodes
-// JSON array elements into corresponding Go array elements.
-// If the Go array is smaller than the JSON array,
-// the additional JSON array elements are discarded.
-// If the JSON array is smaller than the Go array,
-// the additional Go array elements are set to zero values.
-//
-// To unmarshal a JSON object into a string-keyed map, Unmarshal first
-// establishes a map to use, If the map is nil, Unmarshal allocates a new map.
-// Otherwise Unmarshal reuses the existing map, keeping existing entries.
-// Unmarshal then stores key-value pairs from the JSON object into the map.
-//
-// If a JSON value is not appropriate for a given target type,
-// or if a JSON number overflows the target type, Unmarshal
-// skips that field and completes the unmarshaling as best it can.
-// If no more serious errors are encountered, Unmarshal returns
-// an UnmarshalTypeError describing the earliest such error.
-//
-// The JSON null value unmarshals into an interface, map, pointer, or slice
-// by setting that Go value to nil. Because null is often used in JSON to mean
-// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
-// on the value and produces no error.
-//
-// When unmarshaling quoted strings, invalid UTF-8 or
-// invalid UTF-16 surrogate pairs are not treated as an error.
-// Instead, they are replaced by the Unicode replacement
-// character U+FFFD.
-//
-func Unmarshal(data []byte, v interface{}) error {
- // Check for well-formedness.
- // Avoids filling out half a data structure
- // before discovering a JSON syntax error.
- var d decodeState
- err := checkValid(data, &d.scan)
- if err != nil {
- return err
- }
-
- d.init(data)
- return d.unmarshal(v)
-}
-
-// Unmarshaler is the interface implemented by objects
-// that can unmarshal a JSON description of themselves.
-// The input can be assumed to be a valid encoding of
-// a JSON value. UnmarshalJSON must copy the JSON data
-// if it wishes to retain the data after returning.
-type Unmarshaler interface {
- UnmarshalJSON([]byte) error
-}
-
-// An UnmarshalTypeError describes a JSON value that was
-// not appropriate for a value of a specific Go type.
-type UnmarshalTypeError struct {
- Value string // description of JSON value - "bool", "array", "number -5"
- Type reflect.Type // type of Go value it could not be assigned to
- Offset int64 // error occurred after reading Offset bytes
-}
-
-func (e *UnmarshalTypeError) Error() string {
- return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
-}
-
-// An UnmarshalFieldError describes a JSON object key that
-// led to an unexported (and therefore unwritable) struct field.
-// (No longer used; kept for compatibility.)
-type UnmarshalFieldError struct {
- Key string
- Type reflect.Type
- Field reflect.StructField
-}
-
-func (e *UnmarshalFieldError) Error() string {
- return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
-}
-
-// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
-// (The argument to Unmarshal must be a non-nil pointer.)
-type InvalidUnmarshalError struct {
- Type reflect.Type
-}
-
-func (e *InvalidUnmarshalError) Error() string {
- if e.Type == nil {
- return "json: Unmarshal(nil)"
- }
-
- if e.Type.Kind() != reflect.Ptr {
- return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
- }
- return "json: Unmarshal(nil " + e.Type.String() + ")"
-}
-
-func (d *decodeState) unmarshal(v interface{}) (err error) {
- defer func() {
- if r := recover(); r != nil {
- if _, ok := r.(runtime.Error); ok {
- panic(r)
- }
- err = r.(error)
- }
- }()
-
- rv := reflect.ValueOf(v)
- if rv.Kind() != reflect.Ptr || rv.IsNil() {
- return &InvalidUnmarshalError{reflect.TypeOf(v)}
- }
-
- d.scan.reset()
- // We decode rv not rv.Elem because the Unmarshaler interface
- // test must be applied at the top level of the value.
- d.value(rv)
- return d.savedError
-}
-
-// A Number represents a JSON number literal.
-type Number string
-
-// String returns the literal text of the number.
-func (n Number) String() string { return string(n) }
-
-// Float64 returns the number as a float64.
-func (n Number) Float64() (float64, error) {
- return strconv.ParseFloat(string(n), 64)
-}
-
-// Int64 returns the number as an int64.
-func (n Number) Int64() (int64, error) {
- return strconv.ParseInt(string(n), 10, 64)
-}
-
-// isValidNumber reports whether s is a valid JSON number literal.
-func isValidNumber(s string) bool {
- // This function implements the JSON numbers grammar.
- // See https://tools.ietf.org/html/rfc7159#section-6
- // and http://json.org/number.gif
-
- if s == "" {
- return false
- }
-
- // Optional -
- if s[0] == '-' {
- s = s[1:]
- if s == "" {
- return false
- }
- }
-
- // Digits
- switch {
- default:
- return false
-
- case s[0] == '0':
- s = s[1:]
-
- case '1' <= s[0] && s[0] <= '9':
- s = s[1:]
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
- }
- }
-
- // . followed by 1 or more digits.
- if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
- s = s[2:]
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
- }
- }
-
- // e or E followed by an optional - or + and
- // 1 or more digits.
- if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
- s = s[1:]
- if s[0] == '+' || s[0] == '-' {
- s = s[1:]
- if s == "" {
- return false
- }
- }
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
- }
- }
-
- // Make sure we are at the end.
- return s == ""
-}
-
-type NumberUnmarshalType int
-
-const (
- // unmarshal a JSON number into an interface{} as a float64
- UnmarshalFloat NumberUnmarshalType = iota
- // unmarshal a JSON number into an interface{} as a `json.Number`
- UnmarshalJSONNumber
- // unmarshal a JSON number into an interface{} as a int64
- // if value is an integer otherwise float64
- UnmarshalIntOrFloat
-)
-
-// decodeState represents the state while decoding a JSON value.
-type decodeState struct {
- data []byte
- off int // read offset in data
- scan scanner
- nextscan scanner // for calls to nextValue
- savedError error
- numberType NumberUnmarshalType
-}
-
-// errPhase is used for errors that should not happen unless
-// there is a bug in the JSON decoder or something is editing
-// the data slice while the decoder executes.
-var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?")
-
-func (d *decodeState) init(data []byte) *decodeState {
- d.data = data
- d.off = 0
- d.savedError = nil
- return d
-}
-
-// error aborts the decoding by panicking with err.
-func (d *decodeState) error(err error) {
- panic(err)
-}
-
-// saveError saves the first err it is called with,
-// for reporting at the end of the unmarshal.
-func (d *decodeState) saveError(err error) {
- if d.savedError == nil {
- d.savedError = err
- }
-}
-
-// next cuts off and returns the next full JSON value in d.data[d.off:].
-// The next value is known to be an object or array, not a literal.
-func (d *decodeState) next() []byte {
- c := d.data[d.off]
- item, rest, err := nextValue(d.data[d.off:], &d.nextscan)
- if err != nil {
- d.error(err)
- }
- d.off = len(d.data) - len(rest)
-
- // Our scanner has seen the opening brace/bracket
- // and thinks we're still in the middle of the object.
- // invent a closing brace/bracket to get it out.
- if c == '{' {
- d.scan.step(&d.scan, '}')
- } else {
- d.scan.step(&d.scan, ']')
- }
-
- return item
-}
-
-// scanWhile processes bytes in d.data[d.off:] until it
-// receives a scan code not equal to op.
-// It updates d.off and returns the new scan code.
-func (d *decodeState) scanWhile(op int) int {
- var newOp int
- for {
- if d.off >= len(d.data) {
- newOp = d.scan.eof()
- d.off = len(d.data) + 1 // mark processed EOF with len+1
- } else {
- c := d.data[d.off]
- d.off++
- newOp = d.scan.step(&d.scan, c)
- }
- if newOp != op {
- break
- }
- }
- return newOp
-}
-
-// value decodes a JSON value from d.data[d.off:] into the value.
-// it updates d.off to point past the decoded value.
-func (d *decodeState) value(v reflect.Value) {
- if !v.IsValid() {
- _, rest, err := nextValue(d.data[d.off:], &d.nextscan)
- if err != nil {
- d.error(err)
- }
- d.off = len(d.data) - len(rest)
-
- // d.scan thinks we're still at the beginning of the item.
- // Feed in an empty string - the shortest, simplest value -
- // so that it knows we got to the end of the value.
- if d.scan.redo {
- // rewind.
- d.scan.redo = false
- d.scan.step = stateBeginValue
- }
- d.scan.step(&d.scan, '"')
- d.scan.step(&d.scan, '"')
-
- n := len(d.scan.parseState)
- if n > 0 && d.scan.parseState[n-1] == parseObjectKey {
- // d.scan thinks we just read an object key; finish the object
- d.scan.step(&d.scan, ':')
- d.scan.step(&d.scan, '"')
- d.scan.step(&d.scan, '"')
- d.scan.step(&d.scan, '}')
- }
-
- return
- }
-
- switch op := d.scanWhile(scanSkipSpace); op {
- default:
- d.error(errPhase)
-
- case scanBeginArray:
- d.array(v)
-
- case scanBeginObject:
- d.object(v)
-
- case scanBeginLiteral:
- d.literal(v)
- }
-}
-
-type unquotedValue struct{}
-
-// valueQuoted is like value but decodes a
-// quoted string literal or literal null into an interface value.
-// If it finds anything other than a quoted string literal or null,
-// valueQuoted returns unquotedValue{}.
-func (d *decodeState) valueQuoted() interface{} {
- switch op := d.scanWhile(scanSkipSpace); op {
- default:
- d.error(errPhase)
-
- case scanBeginArray:
- d.array(reflect.Value{})
-
- case scanBeginObject:
- d.object(reflect.Value{})
-
- case scanBeginLiteral:
- switch v := d.literalInterface().(type) {
- case nil, string:
- return v
- }
- }
- return unquotedValue{}
-}
-
-// indirect walks down v allocating pointers as needed,
-// until it gets to a non-pointer.
-// if it encounters an Unmarshaler, indirect stops and returns that.
-// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
-func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
- // If v is a named type and is addressable,
- // start with its address, so that if the type has pointer methods,
- // we find them.
- if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
- v = v.Addr()
- }
- for {
- // Load value from interface, but only if the result will be
- // usefully addressable.
- if v.Kind() == reflect.Interface && !v.IsNil() {
- e := v.Elem()
- if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
- v = e
- continue
- }
- }
-
- if v.Kind() != reflect.Ptr {
- break
- }
-
- if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
- break
- }
- if v.IsNil() {
- v.Set(reflect.New(v.Type().Elem()))
- }
- if v.Type().NumMethod() > 0 {
- if u, ok := v.Interface().(Unmarshaler); ok {
- return u, nil, reflect.Value{}
- }
- if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
- return nil, u, reflect.Value{}
- }
- }
- v = v.Elem()
- }
- return nil, nil, v
-}
-
-// array consumes an array from d.data[d.off-1:], decoding into the value v.
-// the first byte of the array ('[') has been read already.
-func (d *decodeState) array(v reflect.Value) {
- // Check for unmarshaler.
- u, ut, pv := d.indirect(v, false)
- if u != nil {
- d.off--
- err := u.UnmarshalJSON(d.next())
- if err != nil {
- d.error(err)
- }
- return
- }
- if ut != nil {
- d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)})
- d.off--
- d.next()
- return
- }
-
- v = pv
-
- // Check type of target.
- switch v.Kind() {
- case reflect.Interface:
- if v.NumMethod() == 0 {
- // Decoding into nil interface? Switch to non-reflect code.
- v.Set(reflect.ValueOf(d.arrayInterface()))
- return
- }
- // Otherwise it's invalid.
- fallthrough
- default:
- d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)})
- d.off--
- d.next()
- return
- case reflect.Array:
- case reflect.Slice:
- break
- }
-
- i := 0
- for {
- // Look ahead for ] - can only happen on first iteration.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
-
- // Back up so d.value can have the byte we just read.
- d.off--
- d.scan.undo(op)
-
- // Get element of array, growing if necessary.
- if v.Kind() == reflect.Slice {
- // Grow slice if necessary
- if i >= v.Cap() {
- newcap := v.Cap() + v.Cap()/2
- if newcap < 4 {
- newcap = 4
- }
- newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
- reflect.Copy(newv, v)
- v.Set(newv)
- }
- if i >= v.Len() {
- v.SetLen(i + 1)
- }
- }
-
- if i < v.Len() {
- // Decode into element.
- d.value(v.Index(i))
- } else {
- // Ran out of fixed array: skip.
- d.value(reflect.Value{})
- }
- i++
-
- // Next token must be , or ].
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
- if op != scanArrayValue {
- d.error(errPhase)
- }
- }
-
- if i < v.Len() {
- if v.Kind() == reflect.Array {
- // Array. Zero the rest.
- z := reflect.Zero(v.Type().Elem())
- for ; i < v.Len(); i++ {
- v.Index(i).Set(z)
- }
- } else {
- v.SetLen(i)
- }
- }
- if i == 0 && v.Kind() == reflect.Slice {
- v.Set(reflect.MakeSlice(v.Type(), 0, 0))
- }
-}
-
-var nullLiteral = []byte("null")
-
-// object consumes an object from d.data[d.off-1:], decoding into the value v.
-// the first byte ('{') of the object has been read already.
-func (d *decodeState) object(v reflect.Value) {
- // Check for unmarshaler.
- u, ut, pv := d.indirect(v, false)
- if u != nil {
- d.off--
- err := u.UnmarshalJSON(d.next())
- if err != nil {
- d.error(err)
- }
- return
- }
- if ut != nil {
- d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
- d.off--
- d.next() // skip over { } in input
- return
- }
- v = pv
-
- // Decoding into nil interface? Switch to non-reflect code.
- if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
- v.Set(reflect.ValueOf(d.objectInterface()))
- return
- }
-
- // Check type of target: struct or map[string]T
- switch v.Kind() {
- case reflect.Map:
- // map must have string kind
- t := v.Type()
- if t.Key().Kind() != reflect.String {
- d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
- d.off--
- d.next() // skip over { } in input
- return
- }
- if v.IsNil() {
- v.Set(reflect.MakeMap(t))
- }
- case reflect.Struct:
-
- default:
- d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)})
- d.off--
- d.next() // skip over { } in input
- return
- }
-
- var mapElem reflect.Value
- keys := map[string]bool{}
-
- for {
- // Read opening " of string key or closing }.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- // closing } - can only happen on first iteration.
- break
- }
- if op != scanBeginLiteral {
- d.error(errPhase)
- }
-
- // Read key.
- start := d.off - 1
- op = d.scanWhile(scanContinue)
- item := d.data[start : d.off-1]
- key, ok := unquote(item)
- if !ok {
- d.error(errPhase)
- }
-
- // Check for duplicate keys.
- _, ok = keys[key]
- if !ok {
- keys[key] = true
- } else {
- d.error(fmt.Errorf("json: duplicate key '%s' in object", key))
- }
-
- // Figure out field corresponding to key.
- var subv reflect.Value
- destring := false // whether the value is wrapped in a string to be decoded first
-
- if v.Kind() == reflect.Map {
- elemType := v.Type().Elem()
- if !mapElem.IsValid() {
- mapElem = reflect.New(elemType).Elem()
- } else {
- mapElem.Set(reflect.Zero(elemType))
- }
- subv = mapElem
- } else {
- var f *field
- fields := cachedTypeFields(v.Type())
- for i := range fields {
- ff := &fields[i]
- if bytes.Equal(ff.nameBytes, []byte(key)) {
- f = ff
- break
- }
- }
- if f != nil {
- subv = v
- destring = f.quoted
- for _, i := range f.index {
- if subv.Kind() == reflect.Ptr {
- if subv.IsNil() {
- subv.Set(reflect.New(subv.Type().Elem()))
- }
- subv = subv.Elem()
- }
- subv = subv.Field(i)
- }
- }
- }
-
- // Read : before value.
- if op == scanSkipSpace {
- op = d.scanWhile(scanSkipSpace)
- }
- if op != scanObjectKey {
- d.error(errPhase)
- }
-
- // Read value.
- if destring {
- switch qv := d.valueQuoted().(type) {
- case nil:
- d.literalStore(nullLiteral, subv, false)
- case string:
- d.literalStore([]byte(qv), subv, true)
- default:
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type()))
- }
- } else {
- d.value(subv)
- }
-
- // Write value back to map;
- // if using struct, subv points into struct already.
- if v.Kind() == reflect.Map {
- kv := reflect.ValueOf(key).Convert(v.Type().Key())
- v.SetMapIndex(kv, subv)
- }
-
- // Next token must be , or }.
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- break
- }
- if op != scanObjectValue {
- d.error(errPhase)
- }
- }
-}
-
-// literal consumes a literal from d.data[d.off-1:], decoding into the value v.
-// The first byte of the literal has been read already
-// (that's how the caller knows it's a literal).
-func (d *decodeState) literal(v reflect.Value) {
- // All bytes inside literal return scanContinue op code.
- start := d.off - 1
- op := d.scanWhile(scanContinue)
-
- // Scan read one byte too far; back up.
- d.off--
- d.scan.undo(op)
-
- d.literalStore(d.data[start:d.off], v, false)
-}
-
-// convertNumber converts the number literal s to a float64, int64 or a Number
-// depending on d.numberDecodeType.
-func (d *decodeState) convertNumber(s string) (interface{}, error) {
- switch d.numberType {
-
- case UnmarshalJSONNumber:
- return Number(s), nil
- case UnmarshalIntOrFloat:
- v, err := strconv.ParseInt(s, 10, 64)
- if err == nil {
- return v, nil
- }
-
- // tries to parse integer number in scientific notation
- f, err := strconv.ParseFloat(s, 64)
- if err != nil {
- return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)}
- }
-
- // if it has no decimal value use int64
- if fi, fd := math.Modf(f); fd == 0.0 {
- return int64(fi), nil
- }
- return f, nil
- default:
- f, err := strconv.ParseFloat(s, 64)
- if err != nil {
- return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)}
- }
- return f, nil
- }
-
-}
-
-var numberType = reflect.TypeOf(Number(""))
-
-// literalStore decodes a literal stored in item into v.
-//
-// fromQuoted indicates whether this literal came from unwrapping a
-// string from the ",string" struct tag option. this is used only to
-// produce more helpful error messages.
-func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) {
- // Check for unmarshaler.
- if len(item) == 0 {
- //Empty string given
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- return
- }
- wantptr := item[0] == 'n' // null
- u, ut, pv := d.indirect(v, wantptr)
- if u != nil {
- err := u.UnmarshalJSON(item)
- if err != nil {
- d.error(err)
- }
- return
- }
- if ut != nil {
- if item[0] != '"' {
- if fromQuoted {
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- } else {
- d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
- }
- return
- }
- s, ok := unquoteBytes(item)
- if !ok {
- if fromQuoted {
- d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- } else {
- d.error(errPhase)
- }
- }
- err := ut.UnmarshalText(s)
- if err != nil {
- d.error(err)
- }
- return
- }
-
- v = pv
-
- switch c := item[0]; c {
- case 'n': // null
- switch v.Kind() {
- case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
- v.Set(reflect.Zero(v.Type()))
- // otherwise, ignore null for primitives/string
- }
- case 't', 'f': // true, false
- value := c == 't'
- switch v.Kind() {
- default:
- if fromQuoted {
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- } else {
- d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)})
- }
- case reflect.Bool:
- v.SetBool(value)
- case reflect.Interface:
- if v.NumMethod() == 0 {
- v.Set(reflect.ValueOf(value))
- } else {
- d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)})
- }
- }
-
- case '"': // string
- s, ok := unquoteBytes(item)
- if !ok {
- if fromQuoted {
- d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- } else {
- d.error(errPhase)
- }
- }
- switch v.Kind() {
- default:
- d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
- case reflect.Slice:
- if v.Type().Elem().Kind() != reflect.Uint8 {
- d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
- break
- }
- b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
- n, err := base64.StdEncoding.Decode(b, s)
- if err != nil {
- d.saveError(err)
- break
- }
- v.SetBytes(b[:n])
- case reflect.String:
- v.SetString(string(s))
- case reflect.Interface:
- if v.NumMethod() == 0 {
- v.Set(reflect.ValueOf(string(s)))
- } else {
- d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)})
- }
- }
-
- default: // number
- if c != '-' && (c < '0' || c > '9') {
- if fromQuoted {
- d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- } else {
- d.error(errPhase)
- }
- }
- s := string(item)
- switch v.Kind() {
- default:
- if v.Kind() == reflect.String && v.Type() == numberType {
- v.SetString(s)
- if !isValidNumber(s) {
- d.error(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item))
- }
- break
- }
- if fromQuoted {
- d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- } else {
- d.error(&UnmarshalTypeError{"number", v.Type(), int64(d.off)})
- }
- case reflect.Interface:
- n, err := d.convertNumber(s)
- if err != nil {
- d.saveError(err)
- break
- }
- if v.NumMethod() != 0 {
- d.saveError(&UnmarshalTypeError{"number", v.Type(), int64(d.off)})
- break
- }
- v.Set(reflect.ValueOf(n))
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- n, err := strconv.ParseInt(s, 10, 64)
- if err != nil || v.OverflowInt(n) {
- d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
- break
- }
- v.SetInt(n)
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- n, err := strconv.ParseUint(s, 10, 64)
- if err != nil || v.OverflowUint(n) {
- d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
- break
- }
- v.SetUint(n)
-
- case reflect.Float32, reflect.Float64:
- n, err := strconv.ParseFloat(s, v.Type().Bits())
- if err != nil || v.OverflowFloat(n) {
- d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)})
- break
- }
- v.SetFloat(n)
- }
- }
-}
-
-// The xxxInterface routines build up a value to be stored
-// in an empty interface. They are not strictly necessary,
-// but they avoid the weight of reflection in this common case.
-
-// valueInterface is like value but returns interface{}
-func (d *decodeState) valueInterface() interface{} {
- switch d.scanWhile(scanSkipSpace) {
- default:
- d.error(errPhase)
- panic("unreachable")
- case scanBeginArray:
- return d.arrayInterface()
- case scanBeginObject:
- return d.objectInterface()
- case scanBeginLiteral:
- return d.literalInterface()
- }
-}
-
-// arrayInterface is like array but returns []interface{}.
-func (d *decodeState) arrayInterface() []interface{} {
- var v = make([]interface{}, 0)
- for {
- // Look ahead for ] - can only happen on first iteration.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
-
- // Back up so d.value can have the byte we just read.
- d.off--
- d.scan.undo(op)
-
- v = append(v, d.valueInterface())
-
- // Next token must be , or ].
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndArray {
- break
- }
- if op != scanArrayValue {
- d.error(errPhase)
- }
- }
- return v
-}
-
-// objectInterface is like object but returns map[string]interface{}.
-func (d *decodeState) objectInterface() map[string]interface{} {
- m := make(map[string]interface{})
- keys := map[string]bool{}
-
- for {
- // Read opening " of string key or closing }.
- op := d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- // closing } - can only happen on first iteration.
- break
- }
- if op != scanBeginLiteral {
- d.error(errPhase)
- }
-
- // Read string key.
- start := d.off - 1
- op = d.scanWhile(scanContinue)
- item := d.data[start : d.off-1]
- key, ok := unquote(item)
- if !ok {
- d.error(errPhase)
- }
-
- // Check for duplicate keys.
- _, ok = keys[key]
- if !ok {
- keys[key] = true
- } else {
- d.error(fmt.Errorf("json: duplicate key '%s' in object", key))
- }
-
- // Read : before value.
- if op == scanSkipSpace {
- op = d.scanWhile(scanSkipSpace)
- }
- if op != scanObjectKey {
- d.error(errPhase)
- }
-
- // Read value.
- m[key] = d.valueInterface()
-
- // Next token must be , or }.
- op = d.scanWhile(scanSkipSpace)
- if op == scanEndObject {
- break
- }
- if op != scanObjectValue {
- d.error(errPhase)
- }
- }
- return m
-}
-
-// literalInterface is like literal but returns an interface value.
-func (d *decodeState) literalInterface() interface{} {
- // All bytes inside literal return scanContinue op code.
- start := d.off - 1
- op := d.scanWhile(scanContinue)
-
- // Scan read one byte too far; back up.
- d.off--
- d.scan.undo(op)
- item := d.data[start:d.off]
-
- switch c := item[0]; c {
- case 'n': // null
- return nil
-
- case 't', 'f': // true, false
- return c == 't'
-
- case '"': // string
- s, ok := unquote(item)
- if !ok {
- d.error(errPhase)
- }
- return s
-
- default: // number
- if c != '-' && (c < '0' || c > '9') {
- d.error(errPhase)
- }
- n, err := d.convertNumber(string(item))
- if err != nil {
- d.saveError(err)
- }
- return n
- }
-}
-
-// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
-// or it returns -1.
-func getu4(s []byte) rune {
- if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
- return -1
- }
- r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
- if err != nil {
- return -1
- }
- return rune(r)
-}
-
-// unquote converts a quoted JSON string literal s into an actual string t.
-// The rules are different than for Go, so cannot use strconv.Unquote.
-func unquote(s []byte) (t string, ok bool) {
- s, ok = unquoteBytes(s)
- t = string(s)
- return
-}
-
-func unquoteBytes(s []byte) (t []byte, ok bool) {
- if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
- return
- }
- s = s[1 : len(s)-1]
-
- // Check for unusual characters. If there are none,
- // then no unquoting is needed, so return a slice of the
- // original bytes.
- r := 0
- for r < len(s) {
- c := s[r]
- if c == '\\' || c == '"' || c < ' ' {
- break
- }
- if c < utf8.RuneSelf {
- r++
- continue
- }
- rr, size := utf8.DecodeRune(s[r:])
- if rr == utf8.RuneError && size == 1 {
- break
- }
- r += size
- }
- if r == len(s) {
- return s, true
- }
-
- b := make([]byte, len(s)+2*utf8.UTFMax)
- w := copy(b, s[0:r])
- for r < len(s) {
- // Out of room? Can only happen if s is full of
- // malformed UTF-8 and we're replacing each
- // byte with RuneError.
- if w >= len(b)-2*utf8.UTFMax {
- nb := make([]byte, (len(b)+utf8.UTFMax)*2)
- copy(nb, b[0:w])
- b = nb
- }
- switch c := s[r]; {
- case c == '\\':
- r++
- if r >= len(s) {
- return
- }
- switch s[r] {
- default:
- return
- case '"', '\\', '/', '\'':
- b[w] = s[r]
- r++
- w++
- case 'b':
- b[w] = '\b'
- r++
- w++
- case 'f':
- b[w] = '\f'
- r++
- w++
- case 'n':
- b[w] = '\n'
- r++
- w++
- case 'r':
- b[w] = '\r'
- r++
- w++
- case 't':
- b[w] = '\t'
- r++
- w++
- case 'u':
- r--
- rr := getu4(s[r:])
- if rr < 0 {
- return
- }
- r += 6
- if utf16.IsSurrogate(rr) {
- rr1 := getu4(s[r:])
- if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
- // A valid pair; consume.
- r += 6
- w += utf8.EncodeRune(b[w:], dec)
- break
- }
- // Invalid surrogate; fall back to replacement rune.
- rr = unicode.ReplacementChar
- }
- w += utf8.EncodeRune(b[w:], rr)
- }
-
- // Quote, control characters are invalid.
- case c == '"', c < ' ':
- return
-
- // ASCII
- case c < utf8.RuneSelf:
- b[w] = c
- r++
- w++
-
- // Coerce to well-formed UTF-8.
- default:
- rr, size := utf8.DecodeRune(s[r:])
- r += size
- w += utf8.EncodeRune(b[w:], rr)
- }
- }
- return b[0:w], true
-}
diff --git a/vendor/gopkg.in/go-jose/go-jose.v2/json/encode.go b/vendor/gopkg.in/go-jose/go-jose.v2/json/encode.go
deleted file mode 100644
index 1dae8bb7cd8..00000000000
--- a/vendor/gopkg.in/go-jose/go-jose.v2/json/encode.go
+++ /dev/null
@@ -1,1197 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package json implements encoding and decoding of JSON objects as defined in
-// RFC 4627. The mapping between JSON objects and Go values is described
-// in the documentation for the Marshal and Unmarshal functions.
-//
-// See "JSON and Go" for an introduction to this package:
-// https://golang.org/doc/articles/json_and_go.html
-package json
-
-import (
- "bytes"
- "encoding"
- "encoding/base64"
- "fmt"
- "math"
- "reflect"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "unicode"
- "unicode/utf8"
-)
-
-// Marshal returns the JSON encoding of v.
-//
-// Marshal traverses the value v recursively.
-// If an encountered value implements the Marshaler interface
-// and is not a nil pointer, Marshal calls its MarshalJSON method
-// to produce JSON. If no MarshalJSON method is present but the
-// value implements encoding.TextMarshaler instead, Marshal calls
-// its MarshalText method.
-// The nil pointer exception is not strictly necessary
-// but mimics a similar, necessary exception in the behavior of
-// UnmarshalJSON.
-//
-// Otherwise, Marshal uses the following type-dependent default encodings:
-//
-// Boolean values encode as JSON booleans.
-//
-// Floating point, integer, and Number values encode as JSON numbers.
-//
-// String values encode as JSON strings coerced to valid UTF-8,
-// replacing invalid bytes with the Unicode replacement rune.
-// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
-// to keep some browsers from misinterpreting JSON output as HTML.
-// Ampersand "&" is also escaped to "\u0026" for the same reason.
-//
-// Array and slice values encode as JSON arrays, except that
-// []byte encodes as a base64-encoded string, and a nil slice
-// encodes as the null JSON object.
-//
-// Struct values encode as JSON objects. Each exported struct field
-// becomes a member of the object unless
-// - the field's tag is "-", or
-// - the field is empty and its tag specifies the "omitempty" option.
-// The empty values are false, 0, any
-// nil pointer or interface value, and any array, slice, map, or string of
-// length zero. The object's default key string is the struct field name
-// but can be specified in the struct field's tag value. The "json" key in
-// the struct field's tag value is the key name, followed by an optional comma
-// and options. Examples:
-//
-// // Field is ignored by this package.
-// Field int `json:"-"`
-//
-// // Field appears in JSON as key "myName".
-// Field int `json:"myName"`
-//
-// // Field appears in JSON as key "myName" and
-// // the field is omitted from the object if its value is empty,
-// // as defined above.
-// Field int `json:"myName,omitempty"`
-//
-// // Field appears in JSON as key "Field" (the default), but
-// // the field is skipped if empty.
-// // Note the leading comma.
-// Field int `json:",omitempty"`
-//
-// The "string" option signals that a field is stored as JSON inside a
-// JSON-encoded string. It applies only to fields of string, floating point,
-// integer, or boolean types. This extra level of encoding is sometimes used
-// when communicating with JavaScript programs:
-//
-// Int64String int64 `json:",string"`
-//
-// The key name will be used if it's a non-empty string consisting of
-// only Unicode letters, digits, dollar signs, percent signs, hyphens,
-// underscores and slashes.
-//
-// Anonymous struct fields are usually marshaled as if their inner exported fields
-// were fields in the outer struct, subject to the usual Go visibility rules amended
-// as described in the next paragraph.
-// An anonymous struct field with a name given in its JSON tag is treated as
-// having that name, rather than being anonymous.
-// An anonymous struct field of interface type is treated the same as having
-// that type as its name, rather than being anonymous.
-//
-// The Go visibility rules for struct fields are amended for JSON when
-// deciding which field to marshal or unmarshal. If there are
-// multiple fields at the same level, and that level is the least
-// nested (and would therefore be the nesting level selected by the
-// usual Go rules), the following extra rules apply:
-//
-// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
-// even if there are multiple untagged fields that would otherwise conflict.
-// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
-// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
-//
-// Handling of anonymous struct fields is new in Go 1.1.
-// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
-// an anonymous struct field in both current and earlier versions, give the field
-// a JSON tag of "-".
-//
-// Map values encode as JSON objects.
-// The map's key type must be string; the map keys are used as JSON object
-// keys, subject to the UTF-8 coercion described for string values above.
-//
-// Pointer values encode as the value pointed to.
-// A nil pointer encodes as the null JSON object.
-//
-// Interface values encode as the value contained in the interface.
-// A nil interface value encodes as the null JSON object.
-//
-// Channel, complex, and function values cannot be encoded in JSON.
-// Attempting to encode such a value causes Marshal to return
-// an UnsupportedTypeError.
-//
-// JSON cannot represent cyclic data structures and Marshal does not
-// handle them. Passing cyclic structures to Marshal will result in
-// an infinite recursion.
-//
-func Marshal(v interface{}) ([]byte, error) {
- e := &encodeState{}
- err := e.marshal(v)
- if err != nil {
- return nil, err
- }
- return e.Bytes(), nil
-}
-
-// MarshalIndent is like Marshal but applies Indent to format the output.
-func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
- b, err := Marshal(v)
- if err != nil {
- return nil, err
- }
- var buf bytes.Buffer
- err = Indent(&buf, b, prefix, indent)
- if err != nil {
- return nil, err
- }
- return buf.Bytes(), nil
-}
-
-// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
-// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
-// so that the JSON will be safe to embed inside HTML