mirror of
https://github.com/bettercap/bettercap
synced 2025-07-16 10:03:39 -07:00
new: supporting wildcard expressions in dns.spoof module (closes #215)
This commit is contained in:
parent
e80e73879f
commit
b5596d54d2
66 changed files with 6281 additions and 10 deletions
122
vendor/github.com/gobwas/glob/syntax/ast/ast.go
generated
vendored
Normal file
122
vendor/github.com/gobwas/glob/syntax/ast/ast.go
generated
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
Parent *Node
|
||||
Children []*Node
|
||||
Value interface{}
|
||||
Kind Kind
|
||||
}
|
||||
|
||||
func NewNode(k Kind, v interface{}, ch ...*Node) *Node {
|
||||
n := &Node{
|
||||
Kind: k,
|
||||
Value: v,
|
||||
}
|
||||
for _, c := range ch {
|
||||
Insert(n, c)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (a *Node) Equal(b *Node) bool {
|
||||
if a.Kind != b.Kind {
|
||||
return false
|
||||
}
|
||||
if a.Value != b.Value {
|
||||
return false
|
||||
}
|
||||
if len(a.Children) != len(b.Children) {
|
||||
return false
|
||||
}
|
||||
for i, c := range a.Children {
|
||||
if !c.Equal(b.Children[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *Node) String() string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(a.Kind.String())
|
||||
if a.Value != nil {
|
||||
buf.WriteString(" =")
|
||||
buf.WriteString(fmt.Sprintf("%v", a.Value))
|
||||
}
|
||||
if len(a.Children) > 0 {
|
||||
buf.WriteString(" [")
|
||||
for i, c := range a.Children {
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
buf.WriteString(c.String())
|
||||
}
|
||||
buf.WriteString("]")
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func Insert(parent *Node, children ...*Node) {
|
||||
parent.Children = append(parent.Children, children...)
|
||||
for _, ch := range children {
|
||||
ch.Parent = parent
|
||||
}
|
||||
}
|
||||
|
||||
type List struct {
|
||||
Not bool
|
||||
Chars string
|
||||
}
|
||||
|
||||
type Range struct {
|
||||
Not bool
|
||||
Lo, Hi rune
|
||||
}
|
||||
|
||||
type Text struct {
|
||||
Text string
|
||||
}
|
||||
|
||||
type Kind int
|
||||
|
||||
const (
|
||||
KindNothing Kind = iota
|
||||
KindPattern
|
||||
KindList
|
||||
KindRange
|
||||
KindText
|
||||
KindAny
|
||||
KindSuper
|
||||
KindSingle
|
||||
KindAnyOf
|
||||
)
|
||||
|
||||
func (k Kind) String() string {
|
||||
switch k {
|
||||
case KindNothing:
|
||||
return "Nothing"
|
||||
case KindPattern:
|
||||
return "Pattern"
|
||||
case KindList:
|
||||
return "List"
|
||||
case KindRange:
|
||||
return "Range"
|
||||
case KindText:
|
||||
return "Text"
|
||||
case KindAny:
|
||||
return "Any"
|
||||
case KindSuper:
|
||||
return "Super"
|
||||
case KindSingle:
|
||||
return "Single"
|
||||
case KindAnyOf:
|
||||
return "AnyOf"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
157
vendor/github.com/gobwas/glob/syntax/ast/parser.go
generated
vendored
Normal file
157
vendor/github.com/gobwas/glob/syntax/ast/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gobwas/glob/syntax/lexer"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type Lexer interface {
|
||||
Next() lexer.Token
|
||||
}
|
||||
|
||||
type parseFn func(*Node, Lexer) (parseFn, *Node, error)
|
||||
|
||||
func Parse(lexer Lexer) (*Node, error) {
|
||||
var parser parseFn
|
||||
|
||||
root := NewNode(KindPattern, nil)
|
||||
|
||||
var (
|
||||
tree *Node
|
||||
err error
|
||||
)
|
||||
for parser, tree = parserMain, root; parser != nil; {
|
||||
parser, tree, err = parser(tree, lexer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return root, nil
|
||||
}
|
||||
|
||||
func parserMain(tree *Node, lex Lexer) (parseFn, *Node, error) {
|
||||
for {
|
||||
token := lex.Next()
|
||||
switch token.Type {
|
||||
case lexer.EOF:
|
||||
return nil, tree, nil
|
||||
|
||||
case lexer.Error:
|
||||
return nil, tree, errors.New(token.Raw)
|
||||
|
||||
case lexer.Text:
|
||||
Insert(tree, NewNode(KindText, Text{token.Raw}))
|
||||
return parserMain, tree, nil
|
||||
|
||||
case lexer.Any:
|
||||
Insert(tree, NewNode(KindAny, nil))
|
||||
return parserMain, tree, nil
|
||||
|
||||
case lexer.Super:
|
||||
Insert(tree, NewNode(KindSuper, nil))
|
||||
return parserMain, tree, nil
|
||||
|
||||
case lexer.Single:
|
||||
Insert(tree, NewNode(KindSingle, nil))
|
||||
return parserMain, tree, nil
|
||||
|
||||
case lexer.RangeOpen:
|
||||
return parserRange, tree, nil
|
||||
|
||||
case lexer.TermsOpen:
|
||||
a := NewNode(KindAnyOf, nil)
|
||||
Insert(tree, a)
|
||||
|
||||
p := NewNode(KindPattern, nil)
|
||||
Insert(a, p)
|
||||
|
||||
return parserMain, p, nil
|
||||
|
||||
case lexer.Separator:
|
||||
p := NewNode(KindPattern, nil)
|
||||
Insert(tree.Parent, p)
|
||||
|
||||
return parserMain, p, nil
|
||||
|
||||
case lexer.TermsClose:
|
||||
return parserMain, tree.Parent.Parent, nil
|
||||
|
||||
default:
|
||||
return nil, tree, fmt.Errorf("unexpected token: %s", token)
|
||||
}
|
||||
}
|
||||
return nil, tree, fmt.Errorf("unknown error")
|
||||
}
|
||||
|
||||
func parserRange(tree *Node, lex Lexer) (parseFn, *Node, error) {
|
||||
var (
|
||||
not bool
|
||||
lo rune
|
||||
hi rune
|
||||
chars string
|
||||
)
|
||||
for {
|
||||
token := lex.Next()
|
||||
switch token.Type {
|
||||
case lexer.EOF:
|
||||
return nil, tree, errors.New("unexpected end")
|
||||
|
||||
case lexer.Error:
|
||||
return nil, tree, errors.New(token.Raw)
|
||||
|
||||
case lexer.Not:
|
||||
not = true
|
||||
|
||||
case lexer.RangeLo:
|
||||
r, w := utf8.DecodeRuneInString(token.Raw)
|
||||
if len(token.Raw) > w {
|
||||
return nil, tree, fmt.Errorf("unexpected length of lo character")
|
||||
}
|
||||
lo = r
|
||||
|
||||
case lexer.RangeBetween:
|
||||
//
|
||||
|
||||
case lexer.RangeHi:
|
||||
r, w := utf8.DecodeRuneInString(token.Raw)
|
||||
if len(token.Raw) > w {
|
||||
return nil, tree, fmt.Errorf("unexpected length of lo character")
|
||||
}
|
||||
|
||||
hi = r
|
||||
|
||||
if hi < lo {
|
||||
return nil, tree, fmt.Errorf("hi character '%s' should be greater than lo '%s'", string(hi), string(lo))
|
||||
}
|
||||
|
||||
case lexer.Text:
|
||||
chars = token.Raw
|
||||
|
||||
case lexer.RangeClose:
|
||||
isRange := lo != 0 && hi != 0
|
||||
isChars := chars != ""
|
||||
|
||||
if isChars == isRange {
|
||||
return nil, tree, fmt.Errorf("could not parse range")
|
||||
}
|
||||
|
||||
if isRange {
|
||||
Insert(tree, NewNode(KindRange, Range{
|
||||
Lo: lo,
|
||||
Hi: hi,
|
||||
Not: not,
|
||||
}))
|
||||
} else {
|
||||
Insert(tree, NewNode(KindList, List{
|
||||
Chars: chars,
|
||||
Not: not,
|
||||
}))
|
||||
}
|
||||
|
||||
return parserMain, tree, nil
|
||||
}
|
||||
}
|
||||
}
|
218
vendor/github.com/gobwas/glob/syntax/ast/parser_test.go
generated
vendored
Normal file
218
vendor/github.com/gobwas/glob/syntax/ast/parser_test.go
generated
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
package ast
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/gobwas/glob/syntax/lexer"
|
||||
)
|
||||
|
||||
type stubLexer struct {
|
||||
tokens []lexer.Token
|
||||
pos int
|
||||
}
|
||||
|
||||
func (s *stubLexer) Next() (ret lexer.Token) {
|
||||
if s.pos == len(s.tokens) {
|
||||
return lexer.Token{lexer.EOF, ""}
|
||||
}
|
||||
ret = s.tokens[s.pos]
|
||||
s.pos++
|
||||
return
|
||||
}
|
||||
|
||||
func TestParseString(t *testing.T) {
|
||||
for id, test := range []struct {
|
||||
tokens []lexer.Token
|
||||
tree *Node
|
||||
}{
|
||||
{
|
||||
//pattern: "abc",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.Text, "abc"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "abc"}),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "a*c",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.Text, "a"},
|
||||
{lexer.Any, "*"},
|
||||
{lexer.Text, "c"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "a"}),
|
||||
NewNode(KindAny, nil),
|
||||
NewNode(KindText, Text{Text: "c"}),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "a**c",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.Text, "a"},
|
||||
{lexer.Super, "**"},
|
||||
{lexer.Text, "c"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "a"}),
|
||||
NewNode(KindSuper, nil),
|
||||
NewNode(KindText, Text{Text: "c"}),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "a?c",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.Text, "a"},
|
||||
{lexer.Single, "?"},
|
||||
{lexer.Text, "c"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "a"}),
|
||||
NewNode(KindSingle, nil),
|
||||
NewNode(KindText, Text{Text: "c"}),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "[!a-z]",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.RangeOpen, "["},
|
||||
{lexer.Not, "!"},
|
||||
{lexer.RangeLo, "a"},
|
||||
{lexer.RangeBetween, "-"},
|
||||
{lexer.RangeHi, "z"},
|
||||
{lexer.RangeClose, "]"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindRange, Range{Lo: 'a', Hi: 'z', Not: true}),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "[az]",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.RangeOpen, "["},
|
||||
{lexer.Text, "az"},
|
||||
{lexer.RangeClose, "]"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindList, List{Chars: "az"}),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "{a,z}",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.TermsOpen, "{"},
|
||||
{lexer.Text, "a"},
|
||||
{lexer.Separator, ","},
|
||||
{lexer.Text, "z"},
|
||||
{lexer.TermsClose, "}"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindAnyOf, nil,
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "a"}),
|
||||
),
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "z"}),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "/{z,ab}*",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.Text, "/"},
|
||||
{lexer.TermsOpen, "{"},
|
||||
{lexer.Text, "z"},
|
||||
{lexer.Separator, ","},
|
||||
{lexer.Text, "ab"},
|
||||
{lexer.TermsClose, "}"},
|
||||
{lexer.Any, "*"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "/"}),
|
||||
NewNode(KindAnyOf, nil,
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "z"}),
|
||||
),
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "ab"}),
|
||||
),
|
||||
),
|
||||
NewNode(KindAny, nil),
|
||||
),
|
||||
},
|
||||
{
|
||||
//pattern: "{a,{x,y},?,[a-z],[!qwe]}",
|
||||
tokens: []lexer.Token{
|
||||
{lexer.TermsOpen, "{"},
|
||||
{lexer.Text, "a"},
|
||||
{lexer.Separator, ","},
|
||||
{lexer.TermsOpen, "{"},
|
||||
{lexer.Text, "x"},
|
||||
{lexer.Separator, ","},
|
||||
{lexer.Text, "y"},
|
||||
{lexer.TermsClose, "}"},
|
||||
{lexer.Separator, ","},
|
||||
{lexer.Single, "?"},
|
||||
{lexer.Separator, ","},
|
||||
{lexer.RangeOpen, "["},
|
||||
{lexer.RangeLo, "a"},
|
||||
{lexer.RangeBetween, "-"},
|
||||
{lexer.RangeHi, "z"},
|
||||
{lexer.RangeClose, "]"},
|
||||
{lexer.Separator, ","},
|
||||
{lexer.RangeOpen, "["},
|
||||
{lexer.Not, "!"},
|
||||
{lexer.Text, "qwe"},
|
||||
{lexer.RangeClose, "]"},
|
||||
{lexer.TermsClose, "}"},
|
||||
{lexer.EOF, ""},
|
||||
},
|
||||
tree: NewNode(KindPattern, nil,
|
||||
NewNode(KindAnyOf, nil,
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "a"}),
|
||||
),
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindAnyOf, nil,
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "x"}),
|
||||
),
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindText, Text{Text: "y"}),
|
||||
),
|
||||
),
|
||||
),
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindSingle, nil),
|
||||
),
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindRange, Range{Lo: 'a', Hi: 'z', Not: false}),
|
||||
),
|
||||
NewNode(KindPattern, nil,
|
||||
NewNode(KindList, List{Chars: "qwe", Not: true}),
|
||||
),
|
||||
),
|
||||
),
|
||||
},
|
||||
} {
|
||||
lexer := &stubLexer{tokens: test.tokens}
|
||||
result, err := Parse(lexer)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] unexpected error: %s", id, err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.tree, result) {
|
||||
t.Errorf("[%d] Parse():\nact:\t%s\nexp:\t%s\n", id, result, test.tree)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue