mirror of
https://github.com/v2fly/domain-list-community.git
synced 2026-01-01 12:35:04 +07:00
Refactor parseEntry
- add value/attribute checker(check missing space) - allow multiple spaces - sort attributes - improve readablity
This commit is contained in:
94
main.go
94
main.go
@@ -29,6 +29,12 @@ const (
|
|||||||
RuleTypeInclude string = "include"
|
RuleTypeInclude string = "include"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
TypeChecker = regexp.MustCompile(`^(domain|full|keyword|regexp|include)$`)
|
||||||
|
ValueChecker = regexp.MustCompile(`^[a-z0-9!\.-]+$`)
|
||||||
|
AttrChecker = regexp.MustCompile(`^[a-z0-9!-]+$`)
|
||||||
|
)
|
||||||
|
|
||||||
type Entry struct {
|
type Entry struct {
|
||||||
Type string
|
Type string
|
||||||
Value string
|
Value string
|
||||||
@@ -79,11 +85,6 @@ func (l *ParsedList) toProto() (*router.GeoSite, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
case RuleTypeRegexp:
|
case RuleTypeRegexp:
|
||||||
// check regexp validity to avoid runtime error
|
|
||||||
_, err := regexp.Compile(entry.Value)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid regexp in list %s: %s", l.Name, entry.Value)
|
|
||||||
}
|
|
||||||
site.Domain = append(site.Domain, &router.Domain{
|
site.Domain = append(site.Domain, &router.Domain{
|
||||||
Type: router.Domain_Regex,
|
Type: router.Domain_Regex,
|
||||||
Value: entry.Value,
|
Value: entry.Value,
|
||||||
@@ -103,9 +104,6 @@ func (l *ParsedList) toProto() (*router.GeoSite, error) {
|
|||||||
Value: entry.Value,
|
Value: entry.Value,
|
||||||
Attribute: entry.Attrs,
|
Attribute: entry.Attrs,
|
||||||
})
|
})
|
||||||
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown domain type: %s", entry.Type)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return site, nil
|
return site, nil
|
||||||
@@ -123,59 +121,55 @@ func exportPlainTextList(list []string, refName string, pl *ParsedList) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseDomain(domain string, entry *Entry) error {
|
func parseEntry(line string) (Entry, error) {
|
||||||
kv := strings.Split(domain, ":")
|
var entry Entry
|
||||||
|
parts := strings.Fields(line)
|
||||||
|
|
||||||
|
// Parse/Check type and value
|
||||||
|
rawTypeVal := parts[0]
|
||||||
|
kv := strings.Split(rawTypeVal, ":")
|
||||||
if len(kv) == 1 {
|
if len(kv) == 1 {
|
||||||
entry.Type = RuleTypeDomain
|
entry.Type = RuleTypeDomain // Default type
|
||||||
entry.Value = strings.ToLower(kv[0])
|
entry.Value = strings.ToLower(rawTypeVal)
|
||||||
return nil
|
} else if len(kv) == 2 {
|
||||||
}
|
|
||||||
|
|
||||||
if len(kv) == 2 {
|
|
||||||
entry.Type = strings.ToLower(kv[0])
|
entry.Type = strings.ToLower(kv[0])
|
||||||
|
if entry.Type == RuleTypeRegexp {
|
||||||
if strings.EqualFold(entry.Type, RuleTypeRegexp) {
|
|
||||||
entry.Value = kv[1]
|
entry.Value = kv[1]
|
||||||
} else {
|
} else {
|
||||||
entry.Value = strings.ToLower(kv[1])
|
entry.Value = strings.ToLower(kv[1])
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
return nil
|
return entry, fmt.Errorf("invalid format: %s", line)
|
||||||
|
}
|
||||||
|
if !TypeChecker.MatchString(entry.Type) {
|
||||||
|
return entry, fmt.Errorf("invalid type: %s", entry.Type)
|
||||||
|
}
|
||||||
|
if entry.Type == RuleTypeRegexp {
|
||||||
|
if _, err := regexp.Compile(entry.Value); err != nil {
|
||||||
|
return entry, fmt.Errorf("invalid regexp: %s", entry.Value)
|
||||||
|
}
|
||||||
|
} else if !ValueChecker.MatchString(entry.Value) {
|
||||||
|
return entry, fmt.Errorf("invalid value: %s", entry.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("invalid format: %s", domain)
|
// Parse/Check attributes
|
||||||
}
|
for _, part := range parts[1:] {
|
||||||
|
if !strings.HasPrefix(part, "@") {
|
||||||
func parseAttribute(attr string) (*router.Domain_Attribute, error) {
|
return entry, fmt.Errorf("invalid attribute: %s", part)
|
||||||
var attribute router.Domain_Attribute
|
|
||||||
if len(attr) == 0 || attr[0] != '@' {
|
|
||||||
return &attribute, fmt.Errorf("invalid attribute: %s", attr)
|
|
||||||
}
|
}
|
||||||
|
attrKey := strings.ToLower(part[1:]) // Trim attribute prefix `@` character
|
||||||
attribute.Key = strings.ToLower(attr[1:]) // Trim attribute prefix `@` character
|
if !AttrChecker.MatchString(attrKey) {
|
||||||
attribute.TypedValue = &router.Domain_Attribute_BoolValue{BoolValue: true}
|
return entry, fmt.Errorf("invalid attribute key: %s", attrKey)
|
||||||
return &attribute, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseEntry(line string) (Entry, error) {
|
|
||||||
parts := strings.Split(line, " ")
|
|
||||||
|
|
||||||
var entry Entry
|
|
||||||
if len(parts) == 0 {
|
|
||||||
return entry, fmt.Errorf("empty entry")
|
|
||||||
}
|
}
|
||||||
|
entry.Attrs = append(entry.Attrs, &router.Domain_Attribute{
|
||||||
if err := parseDomain(parts[0], &entry); err != nil {
|
Key: attrKey,
|
||||||
return entry, err
|
TypedValue: &router.Domain_Attribute_BoolValue{BoolValue: true},
|
||||||
}
|
})
|
||||||
|
|
||||||
for i := 1; i < len(parts); i++ {
|
|
||||||
attr, err := parseAttribute(parts[i])
|
|
||||||
if err != nil {
|
|
||||||
return entry, err
|
|
||||||
}
|
|
||||||
entry.Attrs = append(entry.Attrs, attr)
|
|
||||||
}
|
}
|
||||||
|
// Sort attributes
|
||||||
|
sort.Slice(entry.Attrs, func(i, j int) bool {
|
||||||
|
return entry.Attrs[i].Key < entry.Attrs[j].Key
|
||||||
|
})
|
||||||
|
|
||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user