From 07906c0aa5cea5bfbb8b7b074516902f902a3988 Mon Sep 17 00:00:00 2001 From: Skyxim Date: Sat, 9 Apr 2022 22:25:39 +0800 Subject: [PATCH] fix: parse logic rule error --- rule/logic/and.go | 8 +++++++- rule/logic/common.go | 23 ++++++++++++++--------- rule/logic/not.go | 4 ++-- rule/logic/or.go | 8 +++++++- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/rule/logic/and.go b/rule/logic/and.go index 1d4c99f78..1d650e021 100644 --- a/rule/logic/and.go +++ b/rule/logic/and.go @@ -1,6 +1,8 @@ package logic import ( + "fmt" + C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/rule/common" ) @@ -19,12 +21,16 @@ func (A *AND) ShouldFindProcess() bool { func NewAND(payload string, adapter string) (*AND, error) { and := &AND{Base: &common.Base{}, payload: payload, adapter: adapter} - rules, err := parseRuleByPayload(payload) + rules, err := parseRuleByPayload(payload, true) if err != nil { return nil, err } and.rules = rules + if len(and.rules) == 0 { + return nil, fmt.Errorf("And rule is error, may be format error or not contain least one rule") + } + for _, rule := range rules { if rule.ShouldResolveIP() { and.needIP = true diff --git a/rule/logic/common.go b/rule/logic/common.go index 657add058..2966ae7b2 100644 --- a/rule/logic/common.go +++ b/rule/logic/common.go @@ -2,19 +2,20 @@ package logic import ( "fmt" - "github.com/Dreamacro/clash/common/collections" - C "github.com/Dreamacro/clash/constant" - "github.com/Dreamacro/clash/log" - RC "github.com/Dreamacro/clash/rule/common" - "github.com/Dreamacro/clash/rule/provider" "io" "net/http" "os" "regexp" "strings" + + "github.com/Dreamacro/clash/common/collections" + C "github.com/Dreamacro/clash/constant" + "github.com/Dreamacro/clash/log" + RC "github.com/Dreamacro/clash/rule/common" + "github.com/Dreamacro/clash/rule/provider" ) -func parseRuleByPayload(payload string) ([]C.Rule, error) { +func parseRuleByPayload(payload string, skip bool) ([]C.Rule, error) { regex, err := regexp.Compile("\\(.*\\)") if err != nil { return nil, err @@ -27,7 +28,7 @@ func parseRuleByPayload(payload string) ([]C.Rule, error) { } rules := make([]C.Rule, 0, len(subAllRanges)) - subRanges := findSubRuleRange(payload, subAllRanges) + subRanges := findSubRuleRange(payload, subAllRanges, skip) for _, subRange := range subRanges { subPayload := payload[subRange.start+1 : subRange.end] @@ -51,6 +52,10 @@ func containRange(r Range, preStart, preEnd int) bool { func payloadToRule(subPayload string) (C.Rule, error) { splitStr := strings.SplitN(subPayload, ",", 2) + if len(splitStr) < 2 { + return nil, fmt.Errorf("The logic rule contain a rule of error format") + } + tp := splitStr[0] payload := splitStr[1] if tp == "NOT" || tp == "OR" || tp == "AND" { @@ -164,11 +169,11 @@ func format(payload string) ([]Range, error) { return sortResult, nil } -func findSubRuleRange(payload string, ruleRanges []Range) []Range { +func findSubRuleRange(payload string, ruleRanges []Range, skip bool) []Range { payloadLen := len(payload) subRuleRange := make([]Range, 0) for _, rr := range ruleRanges { - if rr.start == 0 && rr.end == payloadLen-1 { + if rr.start == 0 && rr.end == payloadLen-1 && skip { // 最大范围跳过 continue } diff --git a/rule/logic/not.go b/rule/logic/not.go index 81e357a58..b04d7bc70 100644 --- a/rule/logic/not.go +++ b/rule/logic/not.go @@ -19,13 +19,13 @@ func (not *NOT) ShouldFindProcess() bool { func NewNOT(payload string, adapter string) (*NOT, error) { not := &NOT{Base: &common.Base{}, payload: payload, adapter: adapter} - rule, err := parseRuleByPayload(payload) + rule, err := parseRuleByPayload(payload, false) if err != nil { return nil, err } if len(rule) < 1 { - return nil, fmt.Errorf("the parsed rule is empty") + return nil, fmt.Errorf("NOT rule have not a rule") } not.rule = rule[0] diff --git a/rule/logic/or.go b/rule/logic/or.go index 05ad6f91e..9afb73d4e 100644 --- a/rule/logic/or.go +++ b/rule/logic/or.go @@ -1,6 +1,8 @@ package logic import ( + "fmt" + C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/rule/common" ) @@ -45,12 +47,16 @@ func (or *OR) ShouldResolveIP() bool { func NewOR(payload string, adapter string) (*OR, error) { or := &OR{Base: &common.Base{}, payload: payload, adapter: adapter} - rules, err := parseRuleByPayload(payload) + rules, err := parseRuleByPayload(payload, true) if err != nil { return nil, err } or.rules = rules + if len(or.rules) == 0 { + return nil, fmt.Errorf("Or rule is error, may be format error or not contain least one rule") + } + for _, rule := range rules { if rule.ShouldResolveIP() { or.needIP = true