summaryrefslogtreecommitdiff
path: root/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go
diff options
context:
space:
mode:
authorLibravatar Terin Stock <terinjokes@gmail.com>2025-03-09 17:47:56 +0100
committerLibravatar Terin Stock <terinjokes@gmail.com>2025-03-10 01:59:49 +0100
commit3ac1ee16f377d31a0fb80c8dae28b6239ac4229e (patch)
treef61faa581feaaeaba2542b9f2b8234a590684413 /vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go
parent[chore] update URLs to forked source (diff)
downloadgotosocial-3ac1ee16f377d31a0fb80c8dae28b6239ac4229e.tar.xz
[chore] remove vendor
Diffstat (limited to 'vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go')
-rw-r--r--vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go381
1 files changed, 0 insertions, 381 deletions
diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go
deleted file mode 100644
index e54507145..000000000
--- a/vendor/github.com/grpc-ecosystem/grpc-gateway/v2/runtime/pattern.go
+++ /dev/null
@@ -1,381 +0,0 @@
-package runtime
-
-import (
- "errors"
- "fmt"
- "strconv"
- "strings"
-
- "github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
- "google.golang.org/grpc/grpclog"
-)
-
-var (
- // ErrNotMatch indicates that the given HTTP request path does not match to the pattern.
- ErrNotMatch = errors.New("not match to the path pattern")
- // ErrInvalidPattern indicates that the given definition of Pattern is not valid.
- ErrInvalidPattern = errors.New("invalid pattern")
-)
-
-type MalformedSequenceError string
-
-func (e MalformedSequenceError) Error() string {
- return "malformed path escape " + strconv.Quote(string(e))
-}
-
-type op struct {
- code utilities.OpCode
- operand int
-}
-
-// Pattern is a template pattern of http request paths defined in
-// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto
-type Pattern struct {
- // ops is a list of operations
- ops []op
- // pool is a constant pool indexed by the operands or vars.
- pool []string
- // vars is a list of variables names to be bound by this pattern
- vars []string
- // stacksize is the max depth of the stack
- stacksize int
- // tailLen is the length of the fixed-size segments after a deep wildcard
- tailLen int
- // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part.
- verb string
-}
-
-// NewPattern returns a new Pattern from the given definition values.
-// "ops" is a sequence of op codes. "pool" is a constant pool.
-// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part.
-// "version" must be 1 for now.
-// It returns an error if the given definition is invalid.
-func NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) {
- if version != 1 {
- grpclog.Errorf("unsupported version: %d", version)
- return Pattern{}, ErrInvalidPattern
- }
-
- l := len(ops)
- if l%2 != 0 {
- grpclog.Errorf("odd number of ops codes: %d", l)
- return Pattern{}, ErrInvalidPattern
- }
-
- var (
- typedOps []op
- stack, maxstack int
- tailLen int
- pushMSeen bool
- vars []string
- )
- for i := 0; i < l; i += 2 {
- op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]}
- switch op.code {
- case utilities.OpNop:
- continue
- case utilities.OpPush:
- if pushMSeen {
- tailLen++
- }
- stack++
- case utilities.OpPushM:
- if pushMSeen {
- grpclog.Error("pushM appears twice")
- return Pattern{}, ErrInvalidPattern
- }
- pushMSeen = true
- stack++
- case utilities.OpLitPush:
- if op.operand < 0 || len(pool) <= op.operand {
- grpclog.Errorf("negative literal index: %d", op.operand)
- return Pattern{}, ErrInvalidPattern
- }
- if pushMSeen {
- tailLen++
- }
- stack++
- case utilities.OpConcatN:
- if op.operand <= 0 {
- grpclog.Errorf("negative concat size: %d", op.operand)
- return Pattern{}, ErrInvalidPattern
- }
- stack -= op.operand
- if stack < 0 {
- grpclog.Error("stack underflow")
- return Pattern{}, ErrInvalidPattern
- }
- stack++
- case utilities.OpCapture:
- if op.operand < 0 || len(pool) <= op.operand {
- grpclog.Errorf("variable name index out of bound: %d", op.operand)
- return Pattern{}, ErrInvalidPattern
- }
- v := pool[op.operand]
- op.operand = len(vars)
- vars = append(vars, v)
- stack--
- if stack < 0 {
- grpclog.Error("stack underflow")
- return Pattern{}, ErrInvalidPattern
- }
- default:
- grpclog.Errorf("invalid opcode: %d", op.code)
- return Pattern{}, ErrInvalidPattern
- }
-
- if maxstack < stack {
- maxstack = stack
- }
- typedOps = append(typedOps, op)
- }
- return Pattern{
- ops: typedOps,
- pool: pool,
- vars: vars,
- stacksize: maxstack,
- tailLen: tailLen,
- verb: verb,
- }, nil
-}
-
-// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization.
-func MustPattern(p Pattern, err error) Pattern {
- if err != nil {
- grpclog.Fatalf("Pattern initialization failed: %v", err)
- }
- return p
-}
-
-// MatchAndEscape examines components to determine if they match to a Pattern.
-// MatchAndEscape will return an error if no Patterns matched or if a pattern
-// matched but contained malformed escape sequences. If successful, the function
-// returns a mapping from field paths to their captured values.
-func (p Pattern) MatchAndEscape(components []string, verb string, unescapingMode UnescapingMode) (map[string]string, error) {
- if p.verb != verb {
- if p.verb != "" {
- return nil, ErrNotMatch
- }
- if len(components) == 0 {
- components = []string{":" + verb}
- } else {
- components = append([]string{}, components...)
- components[len(components)-1] += ":" + verb
- }
- }
-
- var pos int
- stack := make([]string, 0, p.stacksize)
- captured := make([]string, len(p.vars))
- l := len(components)
- for _, op := range p.ops {
- var err error
-
- switch op.code {
- case utilities.OpNop:
- continue
- case utilities.OpPush, utilities.OpLitPush:
- if pos >= l {
- return nil, ErrNotMatch
- }
- c := components[pos]
- if op.code == utilities.OpLitPush {
- if lit := p.pool[op.operand]; c != lit {
- return nil, ErrNotMatch
- }
- } else if op.code == utilities.OpPush {
- if c, err = unescape(c, unescapingMode, false); err != nil {
- return nil, err
- }
- }
- stack = append(stack, c)
- pos++
- case utilities.OpPushM:
- end := len(components)
- if end < pos+p.tailLen {
- return nil, ErrNotMatch
- }
- end -= p.tailLen
- c := strings.Join(components[pos:end], "/")
- if c, err = unescape(c, unescapingMode, true); err != nil {
- return nil, err
- }
- stack = append(stack, c)
- pos = end
- case utilities.OpConcatN:
- n := op.operand
- l := len(stack) - n
- stack = append(stack[:l], strings.Join(stack[l:], "/"))
- case utilities.OpCapture:
- n := len(stack) - 1
- captured[op.operand] = stack[n]
- stack = stack[:n]
- }
- }
- if pos < l {
- return nil, ErrNotMatch
- }
- bindings := make(map[string]string)
- for i, val := range captured {
- bindings[p.vars[i]] = val
- }
- return bindings, nil
-}
-
-// MatchAndEscape examines components to determine if they match to a Pattern.
-// It will never perform per-component unescaping (see: UnescapingModeLegacy).
-// MatchAndEscape will return an error if no Patterns matched. If successful,
-// the function returns a mapping from field paths to their captured values.
-//
-// Deprecated: Use MatchAndEscape.
-func (p Pattern) Match(components []string, verb string) (map[string]string, error) {
- return p.MatchAndEscape(components, verb, UnescapingModeDefault)
-}
-
-// Verb returns the verb part of the Pattern.
-func (p Pattern) Verb() string { return p.verb }
-
-func (p Pattern) String() string {
- var stack []string
- for _, op := range p.ops {
- switch op.code {
- case utilities.OpNop:
- continue
- case utilities.OpPush:
- stack = append(stack, "*")
- case utilities.OpLitPush:
- stack = append(stack, p.pool[op.operand])
- case utilities.OpPushM:
- stack = append(stack, "**")
- case utilities.OpConcatN:
- n := op.operand
- l := len(stack) - n
- stack = append(stack[:l], strings.Join(stack[l:], "/"))
- case utilities.OpCapture:
- n := len(stack) - 1
- stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n])
- }
- }
- segs := strings.Join(stack, "/")
- if p.verb != "" {
- return fmt.Sprintf("/%s:%s", segs, p.verb)
- }
- return "/" + segs
-}
-
-/*
- * The following code is adopted and modified from Go's standard library
- * and carries the attached license.
- *
- * Copyright 2009 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.
- */
-
-// ishex returns whether or not the given byte is a valid hex character
-func ishex(c byte) bool {
- switch {
- case '0' <= c && c <= '9':
- return true
- case 'a' <= c && c <= 'f':
- return true
- case 'A' <= c && c <= 'F':
- return true
- }
- return false
-}
-
-func isRFC6570Reserved(c byte) bool {
- switch c {
- case '!', '#', '$', '&', '\'', '(', ')', '*',
- '+', ',', '/', ':', ';', '=', '?', '@', '[', ']':
- return true
- default:
- return false
- }
-}
-
-// unhex converts a hex point to the bit representation
-func unhex(c byte) byte {
- switch {
- case '0' <= c && c <= '9':
- return c - '0'
- case 'a' <= c && c <= 'f':
- return c - 'a' + 10
- case 'A' <= c && c <= 'F':
- return c - 'A' + 10
- }
- return 0
-}
-
-// shouldUnescapeWithMode returns true if the character is escapable with the
-// given mode
-func shouldUnescapeWithMode(c byte, mode UnescapingMode) bool {
- switch mode {
- case UnescapingModeAllExceptReserved:
- if isRFC6570Reserved(c) {
- return false
- }
- case UnescapingModeAllExceptSlash:
- if c == '/' {
- return false
- }
- case UnescapingModeAllCharacters:
- return true
- }
- return true
-}
-
-// unescape unescapes a path string using the provided mode
-func unescape(s string, mode UnescapingMode, multisegment bool) (string, error) {
- // TODO(v3): remove UnescapingModeLegacy
- if mode == UnescapingModeLegacy {
- return s, nil
- }
-
- if !multisegment {
- mode = UnescapingModeAllCharacters
- }
-
- // Count %, check that they're well-formed.
- n := 0
- for i := 0; i < len(s); {
- if s[i] == '%' {
- n++
- if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
- s = s[i:]
- if len(s) > 3 {
- s = s[:3]
- }
-
- return "", MalformedSequenceError(s)
- }
- i += 3
- } else {
- i++
- }
- }
-
- if n == 0 {
- return s, nil
- }
-
- var t strings.Builder
- t.Grow(len(s))
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '%':
- c := unhex(s[i+1])<<4 | unhex(s[i+2])
- if shouldUnescapeWithMode(c, mode) {
- t.WriteByte(c)
- i += 2
- continue
- }
- fallthrough
- default:
- t.WriteByte(s[i])
- }
- }
-
- return t.String(), nil
-}