-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmatch.go
118 lines (107 loc) · 3.7 KB
/
match.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// This package was originally imported from github.com/coreos/fleet/ssh.
// As such it is a derivative work under the Apache 2.0 license under which
// it was originally open-sourced. All original licensing documents have been
// included without modification. This package redistributed under:
//
// Copyright 2016 Empty Interface LLC
//
// 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.
// Copyright 2014 CoreOS, 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 knownhosts
import "strings"
// matchHost tries to match the given host name against a comma-separated
// sequence of subpatterns s (each possibly preceded by ! to indicate negation).
// It returns a boolean indicating whether or not a positive match was made.
// Any matched negations take precedence over any other possible matches in the
// pattern.
func matchHost(host, pattern string) bool {
subpatterns := strings.Split(pattern, ",")
found := false
for _, s := range subpatterns {
// If the host name matches a negated pattern, it is not
// accepted even if it matches other patterns on that line.
if strings.HasPrefix(s, "!") && match(host, s[1:]) {
return false
}
// Otherwise, check for a normal match
if match(host, s) {
found = true
}
}
// Return success if we found a positive match. If there was a negative
// match, we have already returned false and never get here.
return found
}
// match compares the input string s to the pattern p, which may contain
// single and multi-character wildcards (? and * respectively). It returns a
// boolean indicating whether the string matches the pattern.
func match(s, p string) bool {
var i, j int
for i < len(p) {
if p[i] == '*' {
// Skip the asterisk.
i++
// If at end of pattern, accept immediately.
if i == len(p) {
return true
}
// If next character in pattern is known, optimize.
if p[i] != '?' && p[i] != '*' {
// Look for instances of the next character in
// pattern, and try to match starting from those.
for ; j < len(s); j++ {
if s[j] == p[i] && match(s[j:], p[i:]) {
return true
}
}
// Failed.
return false
}
// Move ahead one character at a time and try to
// match at each position.
for ; j < len(s); j++ {
if match(s[j:], p[i:]) {
return true
}
}
// Failed.
return false
}
// There must be at least one more character in the string.
// If we are at the end, fail.
if j == len(s) {
return false
}
// Check if the next character of the string is acceptable.
if p[i] != '?' && p[i] != s[j] {
return false
}
// Move to the next character, both in string and in pattern.
i++
j++
}
// If at end of pattern, accept if also at end of string.
return j == len(s)
}