mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Use compiled regex for common pack delimiter parsing (#17595)
This commit is contained in:
parent
b18604cb92
commit
aa3176f1b8
2 changed files with 72 additions and 13 deletions
|
|
@ -1958,18 +1958,45 @@ func getMostRecentResults(results []*fleet.ScheduledQueryResult) []*fleet.Schedu
|
|||
// The expected format for s is "pack<pack_delimiter>{Global|team-<team_id>}<pack_delimiter><query_name>"
|
||||
//
|
||||
// Returns "" if it failed to parse the pack_delimiter.
|
||||
|
||||
var (
|
||||
dcounter = regexp.MustCompile(`(Global)|(team-\d+)`)
|
||||
pattern = regexp.MustCompile(`^(.*)(?:(Global)|(team-\d+))`)
|
||||
)
|
||||
|
||||
func findPackDelimiterString(scheduledQueryName string) string {
|
||||
// Go's regexp doesn't support backreferences so we have to perform some manual work.
|
||||
scheduledQueryName = scheduledQueryName[4:] // always starts with "pack"
|
||||
for l := 1; l < len(scheduledQueryName); l++ {
|
||||
sep := scheduledQueryName[:l]
|
||||
rest := scheduledQueryName[l:]
|
||||
pattern := fmt.Sprintf(`^(?:(Global)|(team-\d+))%s.+`, regexp.QuoteMeta(sep))
|
||||
matched, _ := regexp.MatchString(pattern, rest)
|
||||
if matched {
|
||||
return sep
|
||||
|
||||
count := dcounter.FindAllString(scheduledQueryName, -1)
|
||||
|
||||
// If Global or team-<team_id> does not appear, then the
|
||||
// pack_delimiter is invalid.
|
||||
if len(count) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
if len(count) == 1 {
|
||||
matches := pattern.FindStringSubmatch(scheduledQueryName)
|
||||
if len(matches) > 1 {
|
||||
return matches[1]
|
||||
}
|
||||
}
|
||||
|
||||
// Handle edge cases where "Global" or "team-<team_id>"" appears multiple times in the query
|
||||
// name. Regex is not pre-compiled, so it is a less performant operation.
|
||||
// Go's regexp doesn't support backreferences so we have to perform some manual work.
|
||||
if len(count) > 1 {
|
||||
for l := 1; l < len(scheduledQueryName); l++ {
|
||||
sep := scheduledQueryName[:l]
|
||||
rest := scheduledQueryName[l:]
|
||||
pattern := fmt.Sprintf(`^(?:(Global)|(team-\d+))%s.+`, regexp.QuoteMeta(sep))
|
||||
matched, _ := regexp.MatchString(pattern, rest)
|
||||
if matched {
|
||||
return sep
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
|
@ -1995,6 +2022,10 @@ func getQueryNameAndTeamIDFromResult(path string) (*uint, string, error) {
|
|||
// For pattern: pack/Global/Name
|
||||
globalPattern := "pack" + sep + "Global" + sep
|
||||
if strings.HasPrefix(path, globalPattern) {
|
||||
name := strings.TrimPrefix(path, globalPattern)
|
||||
if name == "" {
|
||||
return nil, "", fmt.Errorf("parsing query name: %s", path)
|
||||
}
|
||||
return nil, strings.TrimPrefix(path, globalPattern), nil
|
||||
}
|
||||
|
||||
|
|
@ -2006,6 +2037,9 @@ func getQueryNameAndTeamIDFromResult(path string) (*uint, string, error) {
|
|||
if len(teamIDAndQueryNameParts) != 2 {
|
||||
return nil, "", fmt.Errorf("parsing team number part: %s", path)
|
||||
}
|
||||
if teamIDAndQueryNameParts[1] == "" {
|
||||
return nil, "", fmt.Errorf("parsing query name: %s", path)
|
||||
}
|
||||
teamNumberUint, err := strconv.ParseUint(teamIDAndQueryNameParts[0], 10, 32)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("parsing team number: %w", err)
|
||||
|
|
|
|||
|
|
@ -906,11 +906,11 @@ func TestGetQueryNameAndTeamIDFromResult(t *testing.T) {
|
|||
expectedName string
|
||||
hasErr bool
|
||||
}{
|
||||
{"pack/Global/Query Name", nil, "Query Name", false},
|
||||
{"pack/team-1/Query Name", ptr.Uint(1), "Query Name", false},
|
||||
{"pack/team-12345/Another Query", ptr.Uint(12345), "Another Query", false},
|
||||
{"pack/team-foo/Query", nil, "", true},
|
||||
{"pack/Global/QueryWith/Slash", nil, "QueryWith/Slash", false},
|
||||
{"pack/Global/Query Name", nil, "Query Name", false}, // valid global query
|
||||
{"pack/team-1/Query Name", ptr.Uint(1), "Query Name", false}, // valid team query
|
||||
{"pack/team-12345/Another Query", ptr.Uint(12345), "Another Query", false}, // valid team query
|
||||
{"pack/team-foo/Query", nil, "", true}, // missing team ID
|
||||
{"pack/Global/QueryWith/Slash", nil, "QueryWith/Slash", false}, // query name contains forward slash
|
||||
{"packGlobalGlobalGlobalGlobal", nil, "Global", false}, // pack_delimiter=Global
|
||||
{"packXGlobalGlobalXGlobalQueryWith/Slash", nil, "QueryWith/Slash", false}, // pack_delimiter=XGlobal
|
||||
{"pack//Global//QueryWith/Slash", nil, "QueryWith/Slash", false}, // pack_delimiter=//
|
||||
|
|
@ -920,6 +920,8 @@ func TestGetQueryNameAndTeamIDFromResult(t *testing.T) {
|
|||
{"pack123😁123team-1123😁123QueryWith/Slash", ptr.Uint(1), "QueryWith/Slash", false}, // pack_delimiter=123😁123
|
||||
{"pack(foo)team-1(foo)fo(o)bar", ptr.Uint(1), "fo(o)bar", false}, // pack_delimiter=(foo)
|
||||
{"packteam-1team-1team-1team-1", ptr.Uint(1), "team-1", false}, // pack_delimiter=team-1
|
||||
{"pack/Global/GlobalInQueryName", nil, "GlobalInQueryName", false}, // query name contains Global
|
||||
{"pack/team-1/team-1InQueryName", ptr.Uint(1), "team-1InQueryName", false}, // query name contains team-1
|
||||
|
||||
{"InvalidString", nil, "", true},
|
||||
{"Invalid/Query", nil, "", true},
|
||||
|
|
@ -3803,3 +3805,26 @@ func TestDetailQueriesLinuxDistros(t *testing.T) {
|
|||
require.Contains(t, m, "software_linux")
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark function
|
||||
func BenchmarkFindPackDelimiterStringCommon(b *testing.B) {
|
||||
// Input data for benchmarking
|
||||
input := "pack/Global/Foo"
|
||||
|
||||
// Run the benchmark
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
findPackDelimiterString(input)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFindPackDelimiterStringTeamPack(b *testing.B) {
|
||||
// Input data for benchmarking
|
||||
input := "packGlobalGlobalGlobalGlobal" // global pack delimiter, global team, query name global
|
||||
|
||||
// Run the benchmark
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
findPackDelimiterString(input)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue