chore: simplified logic rule parsing
Some checks failed
Test / test (1.20, macos-15-intel) (push) Has been cancelled
Test / test (1.20, macos-latest) (push) Has been cancelled
Test / test (1.20, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.20, ubuntu-latest) (push) Has been cancelled
Test / test (1.20, windows-latest) (push) Has been cancelled
Test / test (1.21, macos-15-intel) (push) Has been cancelled
Test / test (1.21, macos-latest) (push) Has been cancelled
Test / test (1.21, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.21, ubuntu-latest) (push) Has been cancelled
Test / test (1.21, windows-latest) (push) Has been cancelled
Test / test (1.22, macos-15-intel) (push) Has been cancelled
Test / test (1.22, macos-latest) (push) Has been cancelled
Test / test (1.22, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.22, ubuntu-latest) (push) Has been cancelled
Test / test (1.22, windows-latest) (push) Has been cancelled
Test / test (1.23, macos-15-intel) (push) Has been cancelled
Test / test (1.23, macos-latest) (push) Has been cancelled
Test / test (1.23, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.23, ubuntu-latest) (push) Has been cancelled
Test / test (1.23, windows-latest) (push) Has been cancelled
Test / test (1.24, macos-15-intel) (push) Has been cancelled
Test / test (1.24, macos-latest) (push) Has been cancelled
Test / test (1.24, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.24, ubuntu-latest) (push) Has been cancelled
Test / test (1.24, windows-latest) (push) Has been cancelled
Test / test (1.25, macos-15-intel) (push) Has been cancelled
Test / test (1.25, macos-latest) (push) Has been cancelled
Test / test (1.25, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.25, ubuntu-latest) (push) Has been cancelled
Test / test (1.25, windows-latest) (push) Has been cancelled
Test / test (1.26.0-rc.1, macos-15-intel) (push) Has been cancelled
Test / test (1.26.0-rc.1, macos-latest) (push) Has been cancelled
Test / test (1.26.0-rc.1, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.26.0-rc.1, ubuntu-latest) (push) Has been cancelled
Test / test (1.26.0-rc.1, windows-latest) (push) Has been cancelled
Trigger CMFA Update / trigger-CMFA-update (push) Has been cancelled

This commit is contained in:
wwqgtxx 2026-01-08 23:42:01 +08:00
parent 0f2baca2de
commit 94c8d60f72
2 changed files with 41 additions and 45 deletions

View File

@ -2,14 +2,12 @@ package logic
import (
"fmt"
"regexp"
"sort"
"strings"
"sync"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/rules/common"
list "github.com/bahlo/generic-list-go"
)
type Logic struct {
@ -70,7 +68,6 @@ func NewAND(payload string, adapter string, parseRule common.ParseRuleFunc) (*Lo
type Range struct {
start int
end int
index int
}
func (r Range) containRange(preStart, preEnd int) bool {
@ -89,40 +86,35 @@ func (logic *Logic) payloadToRule(subPayload string, parseRule common.ParseRuleF
}
func (logic *Logic) format(payload string) ([]Range, error) {
stack := list.New[Range]()
num := 0
stack := make([]int, 0)
subRanges := make([]Range, 0)
for i, c := range payload {
if c == '(' {
sr := Range{
start: i,
index: num,
}
num++
stack.PushBack(sr)
stack = append(stack, i) // push
} else if c == ')' {
if stack.Len() == 0 {
if len(stack) == 0 {
return nil, fmt.Errorf("missing '('")
}
sr := stack.Back()
stack.Remove(sr)
sr.Value.end = i
subRanges = append(subRanges, sr.Value)
back := len(stack) - 1
start := stack[back] // back
stack = stack[:back] // pop
subRanges = append(subRanges, Range{
start: start,
end: i,
})
}
}
if stack.Len() != 0 {
if len(stack) != 0 {
return nil, fmt.Errorf("format error is missing )")
}
sortResult := make([]Range, len(subRanges))
for _, sr := range subRanges {
sortResult[sr.index] = sr
}
sort.Slice(subRanges, func(i, j int) bool {
return subRanges[i].start < subRanges[j].start
})
return sortResult, nil
return subRanges, nil
}
func (logic *Logic) findSubRuleRange(payload string, ruleRanges []Range) []Range {
@ -152,36 +144,32 @@ func (logic *Logic) findSubRuleRange(payload string, ruleRanges []Range) []Range
}
func (logic *Logic) parsePayload(payload string, parseRule common.ParseRuleFunc) error {
regex, err := regexp.Compile("\\(.*\\)")
if !strings.HasPrefix(payload, "(") || !strings.HasSuffix(payload, ")") { // the payload must be "(xxx)" format
return fmt.Errorf("payload format error")
}
subAllRanges, err := logic.format(payload)
if err != nil {
return err
}
if regex.MatchString(payload) {
subAllRanges, err := logic.format(payload)
rules := make([]C.Rule, 0, len(subAllRanges))
subRanges := logic.findSubRuleRange(payload, subAllRanges)
for _, subRange := range subRanges {
subPayload := payload[subRange.start+1 : subRange.end]
rule, err := logic.payloadToRule(subPayload, parseRule)
if err != nil {
return err
}
rules := make([]C.Rule, 0, len(subAllRanges))
subRanges := logic.findSubRuleRange(payload, subAllRanges)
for _, subRange := range subRanges {
subPayload := payload[subRange.start+1 : subRange.end]
rule, err := logic.payloadToRule(subPayload, parseRule)
if err != nil {
return err
}
rules = append(rules, rule)
}
logic.rules = rules
return nil
rules = append(rules, rule)
}
return fmt.Errorf("payload format error")
logic.rules = rules
return nil
}
func (logic *Logic) RuleType() C.RuleType {

View File

@ -1,13 +1,15 @@
package logic_test
import (
"testing"
// https://github.com/golang/go/wiki/CodeReviewComments#import-dot
. "github.com/metacubex/mihomo/rules/logic"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/rules"
"github.com/stretchr/testify/assert"
"testing"
)
var ParseRule = rules.ParseRule
@ -38,6 +40,12 @@ func TestNOT(t *testing.T) {
}, C.RuleMatchHelper{})
assert.Equal(t, false, m)
_, err = NewNOT("(DST-PORT,5600-6666)", "DIRECT", ParseRule)
assert.NotEqual(t, nil, err)
_, err = NewNOT("DST-PORT,5600-6666", "DIRECT", ParseRule)
assert.NotEqual(t, nil, err)
_, err = NewNOT("((DST-PORT,5600-6666),(DOMAIN,baidu.com))", "DIRECT", ParseRule)
assert.NotEqual(t, nil, err)