diff --git a/rules/common/base.go b/rules/common/base.go index 0baff49d..ab53753e 100644 --- a/rules/common/base.go +++ b/rules/common/base.go @@ -2,6 +2,7 @@ package common import ( "errors" + "strings" C "github.com/metacubex/mihomo/constant" @@ -33,4 +34,22 @@ func ParseParams(params []string) (isSrc bool, noResolve bool) { return } +func ParseRulePayload(ruleRaw string) (string, string, []string) { + item := strings.Split(ruleRaw, ",") + if len(item) == 1 { + return "", item[0], nil + } else if len(item) == 2 { + return item[0], item[1], nil + } else if len(item) > 2 { + // keep in sync with config/config.go [parseRules] + if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" || item[0] == "DOMAIN-REGEX" || item[0] == "PROCESS-NAME-REGEX" || item[0] == "PROCESS-PATH-REGEX" { + return item[0], strings.Join(item[1:], ","), nil + } else { + return item[0], item[1], item[2:] + } + } + + return "", "", nil +} + type ParseRuleFunc func(tp, payload, target string, params []string, subRules map[string][]C.Rule) (C.Rule, error) diff --git a/rules/logic/logic.go b/rules/logic/logic.go index 6a3be8d4..c740d8de 100644 --- a/rules/logic/logic.go +++ b/rules/logic/logic.go @@ -78,21 +78,14 @@ func (r Range) containRange(preStart, preEnd int) bool { } func (logic *Logic) payloadToRule(subPayload string, parseRule common.ParseRuleFunc) (C.Rule, error) { - splitStr := strings.SplitN(subPayload, ",", 2) - if len(splitStr) < 2 { - return nil, fmt.Errorf("[%s] format is error", subPayload) - } - - tp := splitStr[0] - payload := splitStr[1] + tp, payload, param := common.ParseRulePayload(subPayload) switch tp { case "MATCH", "SUB-RULE": return nil, fmt.Errorf("unsupported rule type [%s] on logic rule", tp) - case "NOT", "OR", "AND": - return parseRule(tp, payload, "", nil, nil) + case "": + return nil, fmt.Errorf("[%s] format is error", subPayload) } - param := strings.Split(payload, ",") - return parseRule(tp, param[0], "", param[1:], nil) + return parseRule(tp, payload, "", param, nil) } func (logic *Logic) format(payload string) ([]Range, error) { diff --git a/rules/provider/classical_strategy.go b/rules/provider/classical_strategy.go index 3b74f5cd..2505b301 100644 --- a/rules/provider/classical_strategy.go +++ b/rules/provider/classical_strategy.go @@ -2,11 +2,11 @@ package provider import ( "fmt" - "strings" C "github.com/metacubex/mihomo/constant" P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/log" + "github.com/metacubex/mihomo/rules/common" ) type classicalStrategy struct { @@ -39,7 +39,7 @@ func (c *classicalStrategy) Reset() { } func (c *classicalStrategy) Insert(rule string) { - ruleType, rule, params := ruleParse(rule) + ruleType, rule, params := common.ParseRulePayload(rule) r, err := c.parse(ruleType, rule, "", params) if err != nil { log.Warnln("parse classical rule error: %s", err.Error()) @@ -51,23 +51,6 @@ func (c *classicalStrategy) Insert(rule string) { func (c *classicalStrategy) FinishInsert() {} -func ruleParse(ruleRaw string) (string, string, []string) { - item := strings.Split(ruleRaw, ",") - if len(item) == 1 { - return "", item[0], nil - } else if len(item) == 2 { - return item[0], item[1], nil - } else if len(item) > 2 { - if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" || item[0] == "DOMAIN-REGEX" || item[0] == "PROCESS-NAME-REGEX" || item[0] == "PROCESS-PATH-REGEX" { - return item[0], strings.Join(item[1:], ","), nil - } else { - return item[0], item[1], item[2:] - } - } - - return "", "", nil -} - func NewClassicalStrategy(parse func(tp, payload, target string, params []string, subRules map[string][]C.Rule) (parsed C.Rule, parseErr error)) *classicalStrategy { return &classicalStrategy{rules: []C.Rule{}, parse: func(tp, payload, target string, params []string) (parsed C.Rule, parseErr error) { switch tp {