mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-07-02 09:48:43 +00:00
DomainMatcher: Fix CompactDomainMatcher rule indices (#5934)
Fixes https://github.com/XTLS/Xray-core/pull/5924
This commit is contained in:
@@ -95,48 +95,43 @@ func (f *CompactDomainMatcherFactory) BuildMatcher(rules []*DomainRule) (DomainM
|
|||||||
matchers: make([]strmatcher.MatcherGroup, 0, len(rules)),
|
matchers: make([]strmatcher.MatcherGroup, 0, len(rules)),
|
||||||
values: make([]uint32, 0, len(rules)),
|
values: make([]uint32, 0, len(rules)),
|
||||||
}
|
}
|
||||||
custom := strmatcher.NewLinearValueMatcher()
|
for i, r := range rules {
|
||||||
var idx uint32
|
|
||||||
for _, r := range rules {
|
|
||||||
switch v := r.Value.(type) {
|
switch v := r.Value.(type) {
|
||||||
case *DomainRule_Custom:
|
case *DomainRule_Custom:
|
||||||
m, err := parseDomain(v.Custom)
|
m, err := parseDomain(v.Custom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
custom.Add(m, 0)
|
if compact.custom == nil {
|
||||||
|
compact.custom = strmatcher.NewLinearValueMatcher()
|
||||||
|
}
|
||||||
|
compact.custom.Add(m, uint32(i))
|
||||||
case *DomainRule_Geosite:
|
case *DomainRule_Geosite:
|
||||||
m, err := f.getOrCreateFrom(v.Geosite)
|
m, err := f.getOrCreateFrom(v.Geosite)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
compact.matchers = append(compact.matchers, m)
|
compact.matchers = append(compact.matchers, m)
|
||||||
compact.values = append(compact.values, idx)
|
compact.values = append(compact.values, uint32(i))
|
||||||
idx++
|
|
||||||
default:
|
default:
|
||||||
panic("unknown domain rule type")
|
panic("unknown domain rule type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(compact.matchers) != len(rules) {
|
|
||||||
compact.matchers = append(compact.matchers, custom)
|
|
||||||
compact.values = append(compact.values, idx+1)
|
|
||||||
}
|
|
||||||
return compact, nil
|
return compact, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type CompactDomainMatcher struct {
|
type CompactDomainMatcher struct {
|
||||||
|
custom strmatcher.ValueMatcher
|
||||||
matchers []strmatcher.MatcherGroup
|
matchers []strmatcher.MatcherGroup
|
||||||
values []uint32
|
values []uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CompactDomainMatcher) Add(matcher strmatcher.MatcherGroup, value uint32) {
|
|
||||||
c.matchers = append(c.matchers, matcher)
|
|
||||||
c.values = append(c.values, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match implements DomainMatcher.
|
// Match implements DomainMatcher.
|
||||||
func (c *CompactDomainMatcher) Match(input string) []uint32 {
|
func (c *CompactDomainMatcher) Match(input string) []uint32 {
|
||||||
result := make([]uint32, 0)
|
var result []uint32
|
||||||
|
if c.custom != nil {
|
||||||
|
result = append(result, c.custom.Match(input)...)
|
||||||
|
}
|
||||||
for i, m := range c.matchers {
|
for i, m := range c.matchers {
|
||||||
if m.MatchAny(input) {
|
if m.MatchAny(input) {
|
||||||
result = append(result, c.values[i])
|
result = append(result, c.values[i])
|
||||||
@@ -147,6 +142,9 @@ func (c *CompactDomainMatcher) Match(input string) []uint32 {
|
|||||||
|
|
||||||
// MatchAny implements DomainMatcher.
|
// MatchAny implements DomainMatcher.
|
||||||
func (c *CompactDomainMatcher) MatchAny(input string) bool {
|
func (c *CompactDomainMatcher) MatchAny(input string) bool {
|
||||||
|
if c.custom != nil && c.custom.MatchAny(input) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
for _, m := range c.matchers {
|
for _, m := range c.matchers {
|
||||||
if m.MatchAny(input) {
|
if m.MatchAny(input) {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package geodata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"slices"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/xtls/xray-core/common/geodata/strmatcher"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCompactDomainMatcher_PreservesCustomRuleIndices(t *testing.T) {
|
||||||
|
factory := &CompactDomainMatcherFactory{shared: make(map[string]strmatcher.MatcherGroup)}
|
||||||
|
matcher, err := factory.BuildMatcher([]*DomainRule{
|
||||||
|
{Value: &DomainRule_Custom{Custom: &Domain{Type: Domain_Full, Value: "example.com"}}},
|
||||||
|
{Value: &DomainRule_Custom{Custom: &Domain{Type: Domain_Domain, Value: "example.com"}}},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("BuildMatcher() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := matcher.Match("example.com")
|
||||||
|
slices.Sort(got)
|
||||||
|
|
||||||
|
want := []uint32{0, 1}
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("Match() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompactDomainMatcher_PreservesMixedRuleIndices(t *testing.T) {
|
||||||
|
t.Setenv("xray.location.asset", filepath.Join("..", "..", "resources"))
|
||||||
|
|
||||||
|
factory := &CompactDomainMatcherFactory{shared: make(map[string]strmatcher.MatcherGroup)}
|
||||||
|
matcher, err := factory.BuildMatcher([]*DomainRule{
|
||||||
|
{Value: &DomainRule_Geosite{Geosite: &GeoSiteRule{File: DefaultGeoSiteDat, Code: "CN"}}},
|
||||||
|
{Value: &DomainRule_Custom{Custom: &Domain{Type: Domain_Full, Value: "163.com"}}},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("BuildMatcher() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got := matcher.Match("163.com")
|
||||||
|
slices.Sort(got)
|
||||||
|
|
||||||
|
want := []uint32{0, 1}
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("Match() = %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user