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