mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-07 21:17:58 +02:00
116 lines
2.4 KiB
Go
116 lines
2.4 KiB
Go
package workflow
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func evalJSONPathValue(input any, path string) any {
|
|
path = strings.TrimSpace(path)
|
|
if path == "" || path == "$" || path == "." {
|
|
return input
|
|
}
|
|
if strings.HasPrefix(path, "$.") {
|
|
path = strings.TrimPrefix(path, "$.")
|
|
} else if strings.HasPrefix(path, ".") {
|
|
path = strings.TrimPrefix(path, ".")
|
|
} else if strings.HasPrefix(path, "$") {
|
|
path = strings.TrimPrefix(path, "$")
|
|
}
|
|
cur := normalizeJSONInput(input)
|
|
for _, token := range parseJSONPathTokens(path) {
|
|
if token == "" {
|
|
continue
|
|
}
|
|
switch v := cur.(type) {
|
|
case map[string]any:
|
|
cur = v[token]
|
|
case []any:
|
|
idx, err := strconv.Atoi(token)
|
|
if err != nil || idx < 0 || idx >= len(v) {
|
|
return ""
|
|
}
|
|
cur = v[idx]
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
if cur == nil {
|
|
return ""
|
|
}
|
|
return cur
|
|
}
|
|
|
|
func normalizeJSONInput(input any) any {
|
|
switch v := input.(type) {
|
|
case string:
|
|
var decoded any
|
|
if err := json.Unmarshal([]byte(v), &decoded); err == nil {
|
|
return decoded
|
|
}
|
|
return v
|
|
case []byte:
|
|
var decoded any
|
|
if err := json.Unmarshal(v, &decoded); err == nil {
|
|
return decoded
|
|
}
|
|
return string(v)
|
|
default:
|
|
return input
|
|
}
|
|
}
|
|
|
|
func parseJSONPathTokens(path string) []string {
|
|
var tokens []string
|
|
var buf strings.Builder
|
|
for i := 0; i < len(path); i++ {
|
|
ch := path[i]
|
|
switch ch {
|
|
case '.':
|
|
if buf.Len() > 0 {
|
|
tokens = append(tokens, buf.String())
|
|
buf.Reset()
|
|
}
|
|
case '[':
|
|
if buf.Len() > 0 {
|
|
tokens = append(tokens, buf.String())
|
|
buf.Reset()
|
|
}
|
|
j := i + 1
|
|
for j < len(path) && path[j] != ']' {
|
|
j++
|
|
}
|
|
if j <= len(path) {
|
|
token := strings.Trim(path[i+1:j], `"' `)
|
|
tokens = append(tokens, token)
|
|
i = j
|
|
}
|
|
default:
|
|
buf.WriteByte(ch)
|
|
}
|
|
}
|
|
if buf.Len() > 0 {
|
|
tokens = append(tokens, buf.String())
|
|
}
|
|
return tokens
|
|
}
|
|
|
|
func validateJSONPathSyntax(path string) error {
|
|
path = strings.TrimSpace(path)
|
|
if path == "" {
|
|
return fmt.Errorf("JSONPath 不能为空")
|
|
}
|
|
if !strings.HasPrefix(path, "$") && !strings.HasPrefix(path, ".") {
|
|
return fmt.Errorf("JSONPath/JQ 路径必须以 $ 或 . 开头")
|
|
}
|
|
if strings.Contains(path, "..") || strings.ContainsAny(path, "*?()|") {
|
|
return fmt.Errorf("仅支持安全路径子集,不支持通配符、递归或表达式")
|
|
}
|
|
if strings.Count(path, "[") != strings.Count(path, "]") {
|
|
return fmt.Errorf("JSONPath 方括号不匹配")
|
|
}
|
|
return nil
|
|
}
|