From cd0ede7e1c63a7f1dd640d538d1598ed8d346a93 Mon Sep 17 00:00:00 2001 From: M09Ic Date: Mon, 21 Nov 2022 20:44:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E--filter=E4=B8=8E--match?= =?UTF-8?q?=E5=8F=82=E6=95=B0,=20=E5=8F=AF=E4=BB=A5=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E8=BF=87=E6=BB=A4=E4=B8=8E=E5=8C=B9=E9=85=8D=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 3 +- go.sum | 20 +++++++++ internal/checkpool.go | 2 +- internal/option.go | 32 ++++++++++---- internal/pool.go | 98 +++++++++++++++++++++++++++++++------------ internal/runner.go | 5 +++ internal/types.go | 6 +++ pkg/baseline.go | 10 ++--- pkg/config.go | 8 +++- 9 files changed, 142 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index 35e4710..c48fbe1 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,14 @@ require ( github.com/chainreactors/files v0.2.4 github.com/chainreactors/go-metrics v0.0.0-20220926021830-24787b7a10f8 github.com/chainreactors/gogo/v2 v2.9.5-0.20221110124606-bb8c89742d4d + github.com/chainreactors/ipcs v0.0.13 github.com/chainreactors/logs v0.6.2 github.com/chainreactors/parsers v0.2.7 github.com/chainreactors/words v0.1.1 ) require ( - github.com/chainreactors/ipcs v0.0.13 + github.com/antonmedv/expr v1.9.0 github.com/go-dedup/simhash v0.0.0-20170904020510-9ecaca7b509c github.com/gosuri/uiprogress v0.0.1 github.com/jessevdk/go-flags v1.5.0 diff --git a/go.sum b/go.sum index 7fda4f4..a920101 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,9 @@ +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/M09ic/go-ntlmssp v1.2.9/go.mod h1:yMNEF6ulbFipt3CakMhcmcNVACshPRG4Ap4l00V+mMs= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/antonmedv/expr v1.9.0 h1:j4HI3NHEdgDnN9p6oI6Ndr0G5QryMY0FNxT4ONrFDGU= +github.com/antonmedv/expr v1.9.0/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8= github.com/chainreactors/files v0.2.0/go.mod h1:/Xa9YXhjBlaC33JTD6ZTJFig6pcplak2IDcovf42/6A= github.com/chainreactors/files v0.2.3/go.mod h1:/Xa9YXhjBlaC33JTD6ZTJFig6pcplak2IDcovf42/6A= github.com/chainreactors/files v0.2.4 h1:R0iCqjWLcwwLoSi87FpgUlpxZAd+W4ZLQF3lkoLWZi0= @@ -20,9 +23,12 @@ github.com/chainreactors/parsers v0.2.7 h1:3iEuluL7gSDrElZWyf1KEiTgddgcoZC0IaIHb github.com/chainreactors/parsers v0.2.7/go.mod h1:Z9weht+lnFCk7UcwqFu6lXpS7u5vttiy0AJYOAyCCLA= github.com/chainreactors/words v0.1.1 h1:Zw4HKFtYcIH5SfuCV0X6kj/A5sN99jrQD2ChUonLOV8= github.com/chainreactors/words v0.1.1/go.mod h1:jRcFgafTKqdkd1+StzPCTJG1ESrZHluXEO2eERdHBMQ= +github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= +github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5 h1:4U+x+EB1P66zwYgTjxWXSOT8vF+651Ksr1lojiCZnT8= github.com/go-dedup/megophone v0.0.0-20170830025436-f01be21026f5/go.mod h1:poR/Cp00iqtqu9ltFwl6C00sKC0HY13u/Gh05ZBmP54= github.com/go-dedup/simhash v0.0.0-20170904020510-9ecaca7b509c h1:mucYYQn+sMGNSxidhleonzAdwL203RxhjJGnxQU4NWU= @@ -38,14 +44,24 @@ github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= +github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE= github.com/panjf2000/ants/v2 v2.6.0 h1:xOSpw42m+BMiJ2I33we7h6fYzG4DAlpE1xyI7VS2gxU= github.com/panjf2000/ants/v2 v2.6.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE= +github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/tview v0.0.0-20200219210816-cd38d7432498/go.mod h1:6lkG1x+13OShEf0EaOCaTQYyB7d5nSbb181KtjlS+84= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/sanity-io/litter v1.2.0/go.mod h1:JF6pZUFgu2Q0sBZ+HSV35P8TVPI1TTzEwyu9FXAw2W4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg= @@ -64,6 +80,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -77,10 +95,12 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/checkpool.go b/internal/checkpool.go index 5c502f3..a1ced30 100644 --- a/internal/checkpool.go +++ b/internal/checkpool.go @@ -51,7 +51,7 @@ func NewCheckPool(ctx context.Context, config *pkg.Config) (*CheckPool, error) { if reqerr != nil && reqerr != fasthttp.ErrBodyTooLarge { pool.failedCount++ - bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, Err: reqerr.Error(), Reason: ErrRequestFailed.Error()} + bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, ErrString: reqerr.Error(), Reason: ErrRequestFailed.Error()} } else { bl = pkg.NewBaseline(req.URI(), req.Host(), resp) bl.Collect() diff --git a/internal/option.go b/internal/option.go index 23bb935..382ba88 100644 --- a/internal/option.go +++ b/internal/option.go @@ -2,6 +2,7 @@ package internal import ( "fmt" + "github.com/antonmedv/expr" "github.com/chainreactors/logs" "github.com/chainreactors/spray/pkg" "github.com/chainreactors/words/mask" @@ -38,13 +39,13 @@ type InputOptions struct { } type OutputOptions struct { - Matches map[string]string `long:"match" description:"String, "` - Filters map[string]string `long:"filter" description:"String, "` - Extracts []string `long:"extract" description:"String, "` - OutputFile string `short:"f" description:"String, output filename"` - FuzzyFile string `long:"fuzzy-file" description:"String, fuzzy output filename"` - Fuzzy bool `long:"fuzzy" description:"String, open fuzzy output"` - OutputProbe string `long:"probe" description:"String, output format"` + Match string `long:"match" description:"String, "` + Filter string `long:"filter" description:"String, "` + Extracts []string `long:"extract" description:"String, "` + OutputFile string `short:"f" description:"String, output filename"` + FuzzyFile string `long:"fuzzy-file" description:"String, fuzzy output filename"` + Fuzzy bool `long:"fuzzy" description:"String, open fuzzy output"` + OutputProbe string `long:"probe" description:"String, output format"` } type RequestOptions struct { @@ -261,6 +262,23 @@ func (opt *Option) PrepareRunner() (*Runner, error) { }) } logs.Log.Importantf("Loaded %d dictionaries and %d decorators", len(opt.Dictionaries), len(r.Fns)) + + if opt.Match != "" { + exp, err := expr.Compile(opt.Match) + if err != nil { + return nil, err + } + r.MatchExpr = exp + } + + if opt.Filter != "" { + exp, err := expr.Compile(opt.Filter) + if err != nil { + return nil, err + } + r.FilterExpr = exp + } + // prepare header for _, h := range opt.Headers { i := strings.Index(h, ":") diff --git a/internal/pool.go b/internal/pool.go index f1d634d..f5e2d15 100644 --- a/internal/pool.go +++ b/internal/pool.go @@ -3,12 +3,15 @@ package internal import ( "context" "fmt" + "github.com/antonmedv/expr" + "github.com/antonmedv/expr/vm" "github.com/chainreactors/logs" "github.com/chainreactors/spray/pkg" "github.com/chainreactors/spray/pkg/ihttp" "github.com/chainreactors/words" "github.com/panjf2000/ants/v2" "github.com/valyala/fasthttp" + "strconv" "sync" "time" ) @@ -81,15 +84,22 @@ func NewPool(ctx context.Context, config *pkg.Config) (*Pool, error) { if reqerr != nil && reqerr != fasthttp.ErrBodyTooLarge { pool.failedCount++ - bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, Err: reqerr.Error(), Reason: ErrRequestFailed.Error()} + bl = &pkg.Baseline{Url: pool.BaseURL + unit.path, IsValid: false, ErrString: reqerr.Error(), Reason: ErrRequestFailed.Error()} pool.failedBaselines = append(pool.failedBaselines, bl) } else { - if err = pool.PreCompare(resp); unit.source != WordSource || err == nil { - // 通过预对比跳过一些无用数据, 减少性能消耗 + if unit.source != WordSource { bl = pkg.NewBaseline(req.URI(), req.Host(), resp) - pool.addFuzzyBaseline(bl) } else { - bl = pkg.NewInvalidBaseline(req.URI(), req.Host(), resp, err.Error()) + if unit.source != WordSource || pool.MatchExpr != nil { + // 如果非wordsource, 或自定义了match函数, 则所有数据送入tempch中 + bl = pkg.NewBaseline(req.URI(), req.Host(), resp) + } else if err = pool.PreCompare(resp); err == nil { + // 通过预对比跳过一些无用数据, 减少性能消耗 + bl = pkg.NewBaseline(req.URI(), req.Host(), resp) + pool.addFuzzyBaseline(bl) + } else { + bl = pkg.NewInvalidBaseline(req.URI(), req.Host(), resp, err.Error()) + } } } @@ -104,8 +114,8 @@ func NewPool(ctx context.Context, config *pkg.Config) (*Pool, error) { pool.initwg.Done() return case CheckSource: - if bl.Err != "" { - logs.Log.Warnf("[check.error] maybe ip had banned by waf, break (%d/%d), error: %s", pool.failedCount, pool.BreakThreshold, bl.Err) + if bl.ErrString != "" { + logs.Log.Warnf("[check.error] maybe ip had banned by waf, break (%d/%d), error: %s", pool.failedCount, pool.BreakThreshold, bl.ErrString) pool.failedBaselines = append(pool.failedBaselines, bl) } else if i := pool.base.Compare(bl); i < 1 { if i == 0 { @@ -139,14 +149,27 @@ func NewPool(ctx context.Context, config *pkg.Config) (*Pool, error) { pool.pool = p go func() { for bl := range pool.tempCh { - if pool.customCompare != nil { - if pool.customCompare(bl) { - pool.OutputCh <- bl + var status bool + if pool.MatchExpr != nil { + if pool.CompareWithExpr(pool.MatchExpr, bl) { + status = true } } else { - pool.BaseCompare(bl) - pool.wg.Done() + if pool.BaseCompare(bl) { + status = true + } } + + if status { + if pool.FilterExpr != nil && pool.CompareWithExpr(pool.FilterExpr, bl) { + bl.Reason = ErrCustomFilter.Error() + bl.IsValid = false + } + } else { + bl.IsValid = false + } + pool.OutputCh <- bl + pool.wg.Done() } pool.analyzeDone = true @@ -171,7 +194,6 @@ type Pool struct { analyzeDone bool genReq func(s string) (*ihttp.Request, error) check func() - customCompare func(*pkg.Baseline) bool worder *words.Worder wg sync.WaitGroup initwg sync.WaitGroup // 初始化用, 之后改成锁 @@ -185,11 +207,11 @@ func (p *Pool) Init() error { // todo 分析baseline // 检测基本访问能力 - if p.base.Err != "" { + if p.base.ErrString != "" { return fmt.Errorf(p.base.String()) } - if p.index.Err != "" { + if p.index.ErrString != "" { return fmt.Errorf(p.index.String()) } @@ -275,11 +297,11 @@ func (p *Pool) PreCompare(resp *ihttp.Response) error { return nil } -func (p *Pool) BaseCompare(bl *pkg.Baseline) { +func (p *Pool) BaseCompare(bl *pkg.Baseline) bool { if !bl.IsValid { // precompare 确认无效数据直接送入管道 p.OutputCh <- bl - return + return false } var status = -1 base, ok := p.baselines[bl.Status] // 挑选对应状态码的baseline进行compare @@ -293,31 +315,56 @@ func (p *Pool) BaseCompare(bl *pkg.Baseline) { ok = true base = p.index } - } if ok { if status = base.Compare(bl); status == 1 { - p.PutToInvalid(bl, ErrCompareFailed.Error()) - return + bl.Reason = ErrCompareFailed.Error() + return false } } bl.Collect() for _, f := range bl.Frameworks { if f.Tag == "waf/cdn" { - p.PutToInvalid(bl, ErrWaf.Error()) - return + bl.Reason = ErrWaf.Error() + return false } } if ok && status == 0 && base.FuzzyCompare(bl) { - p.PutToInvalid(bl, ErrFuzzyCompareFailed.Error()) + bl.Reason = ErrFuzzyCompareFailed.Error() p.PutToFuzzy(bl) - return + return false } - p.OutputCh <- bl + return true +} + +func (p *Pool) CompareWithExpr(exp *vm.Program, other *pkg.Baseline) bool { + params := map[string]interface{}{ + "index": p.index, + "base": p.base, + "current": other, + } + for _, status := range FuzzyStatus { + if bl, ok := p.baselines[status]; ok { + params["bl"+strconv.Itoa(status)] = bl + } else { + params["bl"+strconv.Itoa(status)] = &pkg.Baseline{} + } + } + + res, err := expr.Run(exp, params) + if err != nil { + logs.Log.Warn(err.Error()) + } + + if res == true { + return true + } else { + return false + } } func (p *Pool) addFuzzyBaseline(bl *pkg.Baseline) { @@ -330,7 +377,6 @@ func (p *Pool) addFuzzyBaseline(bl *pkg.Baseline) { func (p *Pool) PutToInvalid(bl *pkg.Baseline, reason string) { bl.IsValid = false - bl.Reason = reason p.OutputCh <- bl } diff --git a/internal/runner.go b/internal/runner.go index a6baaa8..e57f6a1 100644 --- a/internal/runner.go +++ b/internal/runner.go @@ -3,6 +3,7 @@ package internal import ( "context" "fmt" + "github.com/antonmedv/expr/vm" "github.com/chainreactors/files" "github.com/chainreactors/logs" "github.com/chainreactors/spray/pkg" @@ -32,6 +33,8 @@ type Runner struct { Wordlist []string Headers http.Header Fns []func(string) string + FilterExpr *vm.Program + MatchExpr *vm.Program Threads int PoolSize int Pools *ants.PoolWithFunc @@ -66,6 +69,8 @@ func (r *Runner) PrepareConfig() *pkg.Config { CheckPeriod: r.CheckPeriod, ErrPeriod: r.ErrPeriod, BreakThreshold: r.BreakThreshold, + MatchExpr: r.MatchExpr, + FilterExpr: r.FilterExpr, } if config.Mod == pkg.PathSpray { config.ClientType = ihttp.FAST diff --git a/internal/types.go b/internal/types.go index 9e0b58e..ebf838b 100644 --- a/internal/types.go +++ b/internal/types.go @@ -10,6 +10,8 @@ const ( ErrRedirect ErrCompareFailed ErrFuzzyCompareFailed + ErrCustomCompareFailed + ErrCustomFilter ) func (e ErrorType) Error() string { @@ -28,6 +30,10 @@ func (e ErrorType) Error() string { return "compare failed" case ErrFuzzyCompareFailed: return "fuzzy compare failed" + case ErrCustomCompareFailed: + return "custom compare failed" + case ErrCustomFilter: + return "custom filtered" default: return "unknown error" } diff --git a/pkg/baseline.go b/pkg/baseline.go index 8376387..b86eba1 100644 --- a/pkg/baseline.go +++ b/pkg/baseline.go @@ -72,7 +72,7 @@ type Baseline struct { Title string `json:"title"` Frameworks Frameworks `json:"frameworks"` Extracteds Extracteds `json:"extracts"` - Err string `json:"error"` + ErrString string `json:"error"` Reason string `json:"reason"` IsValid bool `json:"valid"` IsFuzzy bool `json:"fuzzy"` @@ -189,9 +189,9 @@ func (bl *Baseline) Format(probes []string) string { line.WriteString(" ,") line.WriteString(bl.Reason) } - if bl.Err != "" { + if bl.ErrString != "" { line.WriteString(" ,err: ") - line.WriteString(bl.Err) + line.WriteString(bl.ErrString) return line.String() } @@ -216,9 +216,9 @@ func (bl *Baseline) String() string { line.WriteString(bl.Reason) line.WriteString("]") } - if bl.Err != "" { + if bl.ErrString != "" { line.WriteString(" [err: ") - line.WriteString(bl.Err) + line.WriteString(bl.ErrString) line.WriteString("]") return line.String() } diff --git a/pkg/config.go b/pkg/config.go index 8785bd3..d3c7aeb 100644 --- a/pkg/config.go +++ b/pkg/config.go @@ -1,6 +1,7 @@ package pkg import ( + "github.com/antonmedv/expr/vm" "net/http" ) @@ -31,6 +32,9 @@ type Config struct { Headers http.Header ClientType int Fns []func(string) string - OutputCh chan *Baseline - FuzzyCh chan *Baseline + MatchExpr *vm.Program + FilterExpr *vm.Program + + OutputCh chan *Baseline + FuzzyCh chan *Baseline }