Files
wehub-resource-sync bf9395e022
CI / license-header (push) Has been skipped
CI / e2e-dry-run (push) Has been skipped
CI / fast-gate (push) Failing after 0s
Test PR Label Logic / test-pr-labels (push) Failing after 1s
Skill Format Check / check-format (push) Failing after 2s
CI / security (push) Failing after 5s
CI / unit-test (push) Has been skipped
CI / lint (push) Has been skipped
CI / script-test (push) Has been skipped
CI / deterministic-gate (push) Has been skipped
CI / coverage (push) Has been skipped
CI / results (push) Has been cancelled
CI / deadcode (push) Has been cancelled
CI / e2e-live (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:54 +08:00

59 lines
1015 B
Go

// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package contentsafety
import (
"context"
"regexp"
)
const (
maxStringBytes = 1 << 17 // 128 KiB per string
maxDepth = 64
)
type rule struct {
ID string
Pattern *regexp.Regexp
}
type scanner struct {
rules []rule
}
func (s *scanner) walk(ctx context.Context, v any, hits map[string]struct{}, depth int) {
if depth > maxDepth {
return
}
if ctx.Err() != nil {
return
}
switch t := v.(type) {
case string:
s.scanString(t, hits)
case map[string]any:
for _, child := range t {
s.walk(ctx, child, hits, depth+1)
}
case []any:
for _, child := range t {
s.walk(ctx, child, hits, depth+1)
}
}
}
func (s *scanner) scanString(text string, hits map[string]struct{}) {
if len(text) > maxStringBytes {
text = text[:maxStringBytes]
}
for _, r := range s.rules {
if _, already := hits[r.ID]; already {
continue
}
if r.Pattern.MatchString(text) {
hits[r.ID] = struct{}{}
}
}
}