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
59 lines
1015 B
Go
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{}{}
|
|
}
|
|
}
|
|
}
|