p1: /v2/scrape, /v1/fetch, auth, CLI, contract tests
Single Fetcher.Fetch on the Guard that holds DenyPrefixes. skipTlsVerification is ignored. No 502. keys add writes the secret only to --out. Release binary has no -test-allow-prefix.
This commit is contained in:
+557
@@ -0,0 +1,557 @@
|
||||
package gojq
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"maps"
|
||||
"math"
|
||||
"math/big"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Operator ...
|
||||
type Operator int
|
||||
|
||||
// Operators ...
|
||||
const (
|
||||
OpPipe Operator = iota + 1
|
||||
OpComma
|
||||
OpAdd
|
||||
OpSub
|
||||
OpMul
|
||||
OpDiv
|
||||
OpMod
|
||||
OpEq
|
||||
OpNe
|
||||
OpGt
|
||||
OpLt
|
||||
OpGe
|
||||
OpLe
|
||||
OpAnd
|
||||
OpOr
|
||||
OpAlt
|
||||
OpAssign
|
||||
OpModify
|
||||
OpUpdateAdd
|
||||
OpUpdateSub
|
||||
OpUpdateMul
|
||||
OpUpdateDiv
|
||||
OpUpdateMod
|
||||
OpUpdateAlt
|
||||
)
|
||||
|
||||
// String implements [fmt.Stringer].
|
||||
func (op Operator) String() string {
|
||||
switch op {
|
||||
case OpPipe:
|
||||
return "|"
|
||||
case OpComma:
|
||||
return ","
|
||||
case OpAdd:
|
||||
return "+"
|
||||
case OpSub:
|
||||
return "-"
|
||||
case OpMul:
|
||||
return "*"
|
||||
case OpDiv:
|
||||
return "/"
|
||||
case OpMod:
|
||||
return "%"
|
||||
case OpEq:
|
||||
return "=="
|
||||
case OpNe:
|
||||
return "!="
|
||||
case OpGt:
|
||||
return ">"
|
||||
case OpLt:
|
||||
return "<"
|
||||
case OpGe:
|
||||
return ">="
|
||||
case OpLe:
|
||||
return "<="
|
||||
case OpAnd:
|
||||
return "and"
|
||||
case OpOr:
|
||||
return "or"
|
||||
case OpAlt:
|
||||
return "//"
|
||||
case OpAssign:
|
||||
return "="
|
||||
case OpModify:
|
||||
return "|="
|
||||
case OpUpdateAdd:
|
||||
return "+="
|
||||
case OpUpdateSub:
|
||||
return "-="
|
||||
case OpUpdateMul:
|
||||
return "*="
|
||||
case OpUpdateDiv:
|
||||
return "/="
|
||||
case OpUpdateMod:
|
||||
return "%="
|
||||
case OpUpdateAlt:
|
||||
return "//="
|
||||
default:
|
||||
panic(op)
|
||||
}
|
||||
}
|
||||
|
||||
// GoString implements [fmt.GoStringer].
|
||||
func (op Operator) GoString() (str string) {
|
||||
defer func() { str = "gojq." + str }()
|
||||
switch op {
|
||||
case Operator(0):
|
||||
return "Operator(0)"
|
||||
case OpPipe:
|
||||
return "OpPipe"
|
||||
case OpComma:
|
||||
return "OpComma"
|
||||
case OpAdd:
|
||||
return "OpAdd"
|
||||
case OpSub:
|
||||
return "OpSub"
|
||||
case OpMul:
|
||||
return "OpMul"
|
||||
case OpDiv:
|
||||
return "OpDiv"
|
||||
case OpMod:
|
||||
return "OpMod"
|
||||
case OpEq:
|
||||
return "OpEq"
|
||||
case OpNe:
|
||||
return "OpNe"
|
||||
case OpGt:
|
||||
return "OpGt"
|
||||
case OpLt:
|
||||
return "OpLt"
|
||||
case OpGe:
|
||||
return "OpGe"
|
||||
case OpLe:
|
||||
return "OpLe"
|
||||
case OpAnd:
|
||||
return "OpAnd"
|
||||
case OpOr:
|
||||
return "OpOr"
|
||||
case OpAlt:
|
||||
return "OpAlt"
|
||||
case OpAssign:
|
||||
return "OpAssign"
|
||||
case OpModify:
|
||||
return "OpModify"
|
||||
case OpUpdateAdd:
|
||||
return "OpUpdateAdd"
|
||||
case OpUpdateSub:
|
||||
return "OpUpdateSub"
|
||||
case OpUpdateMul:
|
||||
return "OpUpdateMul"
|
||||
case OpUpdateDiv:
|
||||
return "OpUpdateDiv"
|
||||
case OpUpdateMod:
|
||||
return "OpUpdateMod"
|
||||
case OpUpdateAlt:
|
||||
return "OpUpdateAlt"
|
||||
default:
|
||||
panic(op)
|
||||
}
|
||||
}
|
||||
|
||||
func (op Operator) getFunc() string {
|
||||
switch op {
|
||||
case OpAdd, OpUpdateAdd:
|
||||
return "_add"
|
||||
case OpSub, OpUpdateSub:
|
||||
return "_subtract"
|
||||
case OpMul, OpUpdateMul:
|
||||
return "_multiply"
|
||||
case OpDiv, OpUpdateDiv:
|
||||
return "_divide"
|
||||
case OpMod, OpUpdateMod:
|
||||
return "_modulo"
|
||||
case OpEq:
|
||||
return "_equal"
|
||||
case OpNe:
|
||||
return "_notequal"
|
||||
case OpGt:
|
||||
return "_greater"
|
||||
case OpLt:
|
||||
return "_less"
|
||||
case OpGe:
|
||||
return "_greatereq"
|
||||
case OpLe:
|
||||
return "_lesseq"
|
||||
case OpAssign:
|
||||
return "_assign"
|
||||
case OpModify:
|
||||
return "_modify"
|
||||
case OpUpdateAlt:
|
||||
return "_alternative"
|
||||
default:
|
||||
panic(op)
|
||||
}
|
||||
}
|
||||
|
||||
func binopTypeSwitch[T any](
|
||||
l, r any,
|
||||
callbackInts func(_, _ int) T,
|
||||
callbackFloats func(_, _ float64) T,
|
||||
callbackBigInts func(_, _ *big.Int) T,
|
||||
callbackStrings func(_, _ string) T,
|
||||
callbackArrays func(_, _ []any) T,
|
||||
callbackMaps func(_, _ map[string]any) T,
|
||||
fallback func(_, _ any) T) T {
|
||||
if n, ok := l.(json.Number); ok {
|
||||
l = parseNumber(n)
|
||||
}
|
||||
if n, ok := r.(json.Number); ok {
|
||||
r = parseNumber(n)
|
||||
}
|
||||
switch l := l.(type) {
|
||||
case int:
|
||||
switch r := r.(type) {
|
||||
case int:
|
||||
return callbackInts(l, r)
|
||||
case float64:
|
||||
return callbackFloats(float64(l), r)
|
||||
case *big.Int:
|
||||
return callbackBigInts(big.NewInt(int64(l)), r)
|
||||
default:
|
||||
return fallback(l, r)
|
||||
}
|
||||
case float64:
|
||||
switch r := r.(type) {
|
||||
case int:
|
||||
return callbackFloats(l, float64(r))
|
||||
case float64:
|
||||
return callbackFloats(l, r)
|
||||
case *big.Int:
|
||||
return callbackFloats(l, bigToFloat(r))
|
||||
default:
|
||||
return fallback(l, r)
|
||||
}
|
||||
case *big.Int:
|
||||
switch r := r.(type) {
|
||||
case int:
|
||||
return callbackBigInts(l, big.NewInt(int64(r)))
|
||||
case float64:
|
||||
return callbackFloats(bigToFloat(l), r)
|
||||
case *big.Int:
|
||||
return callbackBigInts(l, r)
|
||||
default:
|
||||
return fallback(l, r)
|
||||
}
|
||||
case string:
|
||||
switch r := r.(type) {
|
||||
case string:
|
||||
return callbackStrings(l, r)
|
||||
default:
|
||||
return fallback(l, r)
|
||||
}
|
||||
case []any:
|
||||
switch r := r.(type) {
|
||||
case []any:
|
||||
return callbackArrays(l, r)
|
||||
default:
|
||||
return fallback(l, r)
|
||||
}
|
||||
case map[string]any:
|
||||
switch r := r.(type) {
|
||||
case map[string]any:
|
||||
return callbackMaps(l, r)
|
||||
default:
|
||||
return fallback(l, r)
|
||||
}
|
||||
default:
|
||||
return fallback(l, r)
|
||||
}
|
||||
}
|
||||
|
||||
func funcOpPlus(v any) any {
|
||||
switch v := v.(type) {
|
||||
case int:
|
||||
return v
|
||||
case float64:
|
||||
return v
|
||||
case *big.Int:
|
||||
return v
|
||||
case json.Number:
|
||||
return v
|
||||
default:
|
||||
return &unaryTypeError{"plus", v}
|
||||
}
|
||||
}
|
||||
|
||||
func negate(v int) any {
|
||||
if v == math.MinInt {
|
||||
return new(big.Int).Neg(big.NewInt(int64(v)))
|
||||
}
|
||||
return -v
|
||||
}
|
||||
|
||||
func funcOpNegate(v any) any {
|
||||
switch v := v.(type) {
|
||||
case int:
|
||||
return negate(v)
|
||||
case float64:
|
||||
return -v
|
||||
case *big.Int:
|
||||
return new(big.Int).Neg(v)
|
||||
case json.Number:
|
||||
if strings.HasPrefix(v.String(), "-") {
|
||||
return v[1:]
|
||||
}
|
||||
return "-" + v
|
||||
default:
|
||||
return &unaryTypeError{"negate", v}
|
||||
}
|
||||
}
|
||||
|
||||
func funcOpAdd(_, l, r any) any {
|
||||
return binopTypeSwitch(l, r,
|
||||
func(l, r int) any {
|
||||
if v := l + r; (v >= l) == (r >= 0) {
|
||||
return v
|
||||
}
|
||||
x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
|
||||
return x.Add(x, y)
|
||||
},
|
||||
func(l, r float64) any { return l + r },
|
||||
func(l, r *big.Int) any { return new(big.Int).Add(l, r) },
|
||||
func(l, r string) any { return l + r },
|
||||
func(l, r []any) any {
|
||||
if len(l) == 0 {
|
||||
return r
|
||||
}
|
||||
if len(r) == 0 {
|
||||
return l
|
||||
}
|
||||
v := make([]any, len(l)+len(r))
|
||||
copy(v, l)
|
||||
copy(v[len(l):], r)
|
||||
return v
|
||||
},
|
||||
func(l, r map[string]any) any {
|
||||
if len(l) == 0 {
|
||||
return r
|
||||
}
|
||||
if len(r) == 0 {
|
||||
return l
|
||||
}
|
||||
m := make(map[string]any, len(l)+len(r))
|
||||
maps.Copy(m, l)
|
||||
maps.Copy(m, r)
|
||||
return m
|
||||
},
|
||||
func(l, r any) any {
|
||||
if l == nil {
|
||||
return r
|
||||
}
|
||||
if r == nil {
|
||||
return l
|
||||
}
|
||||
return &binopTypeError{"add", l, r}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func funcOpSub(_, l, r any) any {
|
||||
return binopTypeSwitch(l, r,
|
||||
func(l, r int) any {
|
||||
if v := l - r; (v <= l) == (r >= 0) {
|
||||
return v
|
||||
}
|
||||
x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
|
||||
return x.Sub(x, y)
|
||||
},
|
||||
func(l, r float64) any { return l - r },
|
||||
func(l, r *big.Int) any { return new(big.Int).Sub(l, r) },
|
||||
func(l, r string) any { return &binopTypeError{"subtract", l, r} },
|
||||
func(l, r []any) any {
|
||||
v := make([]any, 0, len(l))
|
||||
L:
|
||||
for _, l := range l {
|
||||
for _, r := range r {
|
||||
if Compare(l, r) == 0 {
|
||||
continue L
|
||||
}
|
||||
}
|
||||
v = append(v, l)
|
||||
}
|
||||
return v
|
||||
},
|
||||
func(l, r map[string]any) any { return &binopTypeError{"subtract", l, r} },
|
||||
func(l, r any) any { return &binopTypeError{"subtract", l, r} },
|
||||
)
|
||||
}
|
||||
|
||||
func funcOpMul(_, l, r any) any {
|
||||
return binopTypeSwitch(l, r,
|
||||
func(l, r int) any {
|
||||
if r == -1 {
|
||||
return negate(l)
|
||||
}
|
||||
if v := l * r; r == 0 || v/r == l {
|
||||
return v
|
||||
}
|
||||
x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
|
||||
return x.Mul(x, y)
|
||||
},
|
||||
func(l, r float64) any { return l * r },
|
||||
func(l, r *big.Int) any { return new(big.Int).Mul(l, r) },
|
||||
func(l, r string) any { return &binopTypeError{"multiply", l, r} },
|
||||
func(l, r []any) any { return &binopTypeError{"multiply", l, r} },
|
||||
deepMergeObjects,
|
||||
func(l, r any) any {
|
||||
if l, ok := l.(string); ok {
|
||||
if r, ok := toFloat(r); ok {
|
||||
return repeatString(l, r)
|
||||
}
|
||||
}
|
||||
if r, ok := r.(string); ok {
|
||||
if l, ok := toFloat(l); ok {
|
||||
return repeatString(r, l)
|
||||
}
|
||||
}
|
||||
return &binopTypeError{"multiply", l, r}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func deepMergeObjects(l, r map[string]any) any {
|
||||
m := make(map[string]any, len(l)+len(r))
|
||||
maps.Copy(m, l)
|
||||
for k, v := range r {
|
||||
if mk, ok := m[k]; ok {
|
||||
if mk, ok := mk.(map[string]any); ok {
|
||||
if w, ok := v.(map[string]any); ok {
|
||||
v = deepMergeObjects(mk, w)
|
||||
}
|
||||
}
|
||||
}
|
||||
m[k] = v
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func repeatString(s string, n float64) any {
|
||||
if lt(n, 0) {
|
||||
return nil
|
||||
}
|
||||
c := int(min(n, math.MaxInt32))
|
||||
if uint64(len(s))*uint64(c) >= math.MaxInt32 {
|
||||
return &repeatStringTooLargeError{s, n}
|
||||
}
|
||||
return strings.Repeat(s, c)
|
||||
}
|
||||
|
||||
func funcOpDiv(_, l, r any) any {
|
||||
return binopTypeSwitch(l, r,
|
||||
func(l, r int) any {
|
||||
switch r {
|
||||
case 0:
|
||||
return &zeroDivisionError{l, r}
|
||||
case -1:
|
||||
return negate(l)
|
||||
default:
|
||||
if l%r == 0 {
|
||||
return l / r
|
||||
}
|
||||
return float64(l) / float64(r)
|
||||
}
|
||||
},
|
||||
func(l, r float64) any {
|
||||
if r == 0.0 {
|
||||
return &zeroDivisionError{l, r}
|
||||
}
|
||||
return l / r
|
||||
},
|
||||
func(l, r *big.Int) any {
|
||||
if r.Sign() == 0 {
|
||||
return &zeroDivisionError{l, r}
|
||||
}
|
||||
d, m := new(big.Int).DivMod(l, r, new(big.Int))
|
||||
if m.Sign() == 0 {
|
||||
return d
|
||||
}
|
||||
return bigToFloat(l) / bigToFloat(r)
|
||||
},
|
||||
func(l, r string) any {
|
||||
if l == "" {
|
||||
return []any{}
|
||||
}
|
||||
xs := strings.Split(l, r)
|
||||
vs := make([]any, len(xs))
|
||||
for i, x := range xs {
|
||||
vs[i] = x
|
||||
}
|
||||
return vs
|
||||
},
|
||||
func(l, r []any) any { return &binopTypeError{"divide", l, r} },
|
||||
func(l, r map[string]any) any { return &binopTypeError{"divide", l, r} },
|
||||
func(l, r any) any { return &binopTypeError{"divide", l, r} },
|
||||
)
|
||||
}
|
||||
|
||||
func funcOpMod(_, l, r any) any {
|
||||
return binopTypeSwitch(l, r,
|
||||
func(l, r int) any {
|
||||
switch r {
|
||||
case 0:
|
||||
return &zeroModuloError{l, r}
|
||||
case -1:
|
||||
return 0
|
||||
default:
|
||||
return l % r
|
||||
}
|
||||
},
|
||||
func(l, r float64) any {
|
||||
if math.IsNaN(l) || math.IsNaN(r) {
|
||||
return math.NaN()
|
||||
}
|
||||
ri := floatToInt(r)
|
||||
if ri == 0 {
|
||||
return &zeroModuloError{l, r}
|
||||
}
|
||||
return floatToInt(l) % ri
|
||||
},
|
||||
func(l, r *big.Int) any {
|
||||
if r.Sign() == 0 {
|
||||
return &zeroModuloError{l, r}
|
||||
}
|
||||
return new(big.Int).Rem(l, r)
|
||||
},
|
||||
func(l, r string) any { return &binopTypeError{"modulo", l, r} },
|
||||
func(l, r []any) any { return &binopTypeError{"modulo", l, r} },
|
||||
func(l, r map[string]any) any { return &binopTypeError{"modulo", l, r} },
|
||||
func(l, r any) any { return &binopTypeError{"modulo", l, r} },
|
||||
)
|
||||
}
|
||||
|
||||
func funcOpAlt(_, l, r any) any {
|
||||
if l == nil || l == false {
|
||||
return r
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func funcOpEq(_, l, r any) any {
|
||||
return Compare(l, r) == 0
|
||||
}
|
||||
|
||||
func funcOpNe(_, l, r any) any {
|
||||
return Compare(l, r) != 0
|
||||
}
|
||||
|
||||
func funcOpGt(_, l, r any) any {
|
||||
return Compare(l, r) > 0
|
||||
}
|
||||
|
||||
func funcOpLt(_, l, r any) any {
|
||||
return Compare(l, r) < 0
|
||||
}
|
||||
|
||||
func funcOpGe(_, l, r any) any {
|
||||
return Compare(l, r) >= 0
|
||||
}
|
||||
|
||||
func funcOpLe(_, l, r any) any {
|
||||
return Compare(l, r) <= 0
|
||||
}
|
||||
Reference in New Issue
Block a user