feat: TextRule line num

This commit is contained in:
Toby
2023-08-14 13:24:23 -07:00
parent cd2524c767
commit 6fa958815b
3 changed files with 17 additions and 15 deletions

View File

@@ -84,12 +84,12 @@ func (s *compiledRuleSetImpl[O]) Match(host HostInfo, proto protocol, port uint1
} }
type CompilationError struct { type CompilationError struct {
Index int LineNum int
Message string Message string
} }
func (e *CompilationError) Error() string { func (e *CompilationError) Error() string {
return fmt.Sprintf("error at index %d: %s", e.Index, e.Message) return fmt.Sprintf("error at line %d: %s", e.LineNum, e.Message)
} }
func Compile[O Outbound](rules []TextRule, outbounds map[string]O, func Compile[O Outbound](rules []TextRule, outbounds map[string]O,
@@ -99,21 +99,21 @@ func Compile[O Outbound](rules []TextRule, outbounds map[string]O,
for i, rule := range rules { for i, rule := range rules {
outbound, ok := outbounds[rule.Outbound] outbound, ok := outbounds[rule.Outbound]
if !ok { if !ok {
return nil, &CompilationError{i, fmt.Sprintf("outbound %s not found", rule.Outbound)} return nil, &CompilationError{rule.LineNum, fmt.Sprintf("outbound %s not found", rule.Outbound)}
} }
hm, errStr := compileHostMatcher(rule.Address, geoipFunc) hm, errStr := compileHostMatcher(rule.Address, geoipFunc)
if errStr != "" { if errStr != "" {
return nil, &CompilationError{i, errStr} return nil, &CompilationError{rule.LineNum, errStr}
} }
proto, port, ok := parseProtoPort(rule.ProtoPort) proto, port, ok := parseProtoPort(rule.ProtoPort)
if !ok { if !ok {
return nil, &CompilationError{i, fmt.Sprintf("invalid protocol/port: %s", rule.ProtoPort)} return nil, &CompilationError{rule.LineNum, fmt.Sprintf("invalid protocol/port: %s", rule.ProtoPort)}
} }
var hijackAddress net.IP var hijackAddress net.IP
if rule.HijackAddress != "" { if rule.HijackAddress != "" {
hijackAddress = net.ParseIP(rule.HijackAddress) hijackAddress = net.ParseIP(rule.HijackAddress)
if hijackAddress == nil { if hijackAddress == nil {
return nil, &CompilationError{i, fmt.Sprintf("invalid hijack address (must be an IP address): %s", rule.HijackAddress)} return nil, &CompilationError{rule.LineNum, fmt.Sprintf("invalid hijack address (must be an IP address): %s", rule.HijackAddress)}
} }
} }
compiledRules[i] = compiledRule[O]{outbound, hm, proto, port, hijackAddress} compiledRules[i] = compiledRule[O]{outbound, hm, proto, port, hijackAddress}

View File

@@ -31,9 +31,10 @@ type TextRule struct {
Address string Address string
ProtoPort string ProtoPort string
HijackAddress string HijackAddress string
LineNum int
} }
func parseLine(line string) *TextRule { func parseLine(line string, num int) *TextRule {
matches := linePattern.FindStringSubmatch(line) matches := linePattern.FindStringSubmatch(line)
if matches == nil { if matches == nil {
return nil return nil
@@ -43,6 +44,7 @@ func parseLine(line string) *TextRule {
Address: strings.TrimSpace(matches[2]), Address: strings.TrimSpace(matches[2]),
ProtoPort: strings.TrimSpace(matches[3]), ProtoPort: strings.TrimSpace(matches[3]),
HijackAddress: strings.TrimSpace(matches[4]), HijackAddress: strings.TrimSpace(matches[4]),
LineNum: num,
} }
} }
@@ -61,7 +63,7 @@ func ParseTextRules(text string) ([]TextRule, error) {
continue continue
} }
// Parse line // Parse line
rule := parseLine(line) rule := parseLine(line, lineNum)
if rule == nil { if rule == nil {
return nil, &InvalidSyntaxError{line, lineNum} return nil, &InvalidSyntaxError{line, lineNum}
} }

View File

@@ -32,13 +32,13 @@ my_custom_outbound1(9.9.9.9,*, 8.8.8.8) # bebop
my_custom_outbound2(all) my_custom_outbound2(all)
`, `,
want: []TextRule{ want: []TextRule{
{Outbound: "direct", Address: "1.1.1.1"}, {Outbound: "direct", Address: "1.1.1.1", LineNum: 4},
{Outbound: "direct", Address: "8.8.8.0/24"}, {Outbound: "direct", Address: "8.8.8.0/24", LineNum: 5},
{Outbound: "reject", Address: "all", ProtoPort: "udp/443"}, {Outbound: "reject", Address: "all", ProtoPort: "udp/443", LineNum: 6},
{Outbound: "reject", Address: "geoip:cn"}, {Outbound: "reject", Address: "geoip:cn", LineNum: 7},
{Outbound: "reject", Address: "*.v2ex.com"}, {Outbound: "reject", Address: "*.v2ex.com", LineNum: 8},
{Outbound: "my_custom_outbound1", Address: "9.9.9.9", ProtoPort: "*", HijackAddress: "8.8.8.8"}, {Outbound: "my_custom_outbound1", Address: "9.9.9.9", ProtoPort: "*", HijackAddress: "8.8.8.8", LineNum: 9},
{Outbound: "my_custom_outbound2", Address: "all"}, {Outbound: "my_custom_outbound2", Address: "all", LineNum: 10},
}, },
wantErr: false, wantErr: false,
}, },