mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
123 lines
3.5 KiB
Go
123 lines
3.5 KiB
Go
package lib
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand" //nolint:gosec // G404: math/rand用于生成POC测试数据,非加密用途
|
|
|
|
"github.com/google/cel-go/checker/decls"
|
|
"github.com/google/cel-go/common/types"
|
|
"github.com/google/cel-go/common/types/ref"
|
|
"github.com/google/cel-go/interpreter/functions"
|
|
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
|
|
)
|
|
|
|
const maxRandomStringLength = 4096
|
|
|
|
// registerRandomDeclarations 注册随机函数的CEL声明
|
|
func registerRandomDeclarations() []*exprpb.Decl {
|
|
return []*exprpb.Decl{
|
|
decls.NewFunction("randomInt",
|
|
decls.NewOverload("randomInt_int_int",
|
|
[]*exprpb.Type{decls.Int, decls.Int},
|
|
decls.Int)),
|
|
decls.NewFunction("randomLowercase",
|
|
decls.NewOverload("randomLowercase_int",
|
|
[]*exprpb.Type{decls.Int},
|
|
decls.String)),
|
|
decls.NewFunction("randomUppercase",
|
|
decls.NewOverload("randomUppercase_int",
|
|
[]*exprpb.Type{decls.Int},
|
|
decls.String)),
|
|
decls.NewFunction("randomString",
|
|
decls.NewOverload("randomString_int",
|
|
[]*exprpb.Type{decls.Int},
|
|
decls.String)),
|
|
}
|
|
}
|
|
|
|
// registerRandomImplementations 注册随机函数的CEL实现
|
|
func registerRandomImplementations() []*functions.Overload {
|
|
return []*functions.Overload{
|
|
{
|
|
Operator: "randomInt_int_int",
|
|
Binary: func(lhs ref.Val, rhs ref.Val) ref.Val {
|
|
from, ok := lhs.(types.Int)
|
|
if !ok {
|
|
return types.ValOrErr(lhs, "unexpected type '%v' passed to randomInt", lhs.Type())
|
|
}
|
|
to, ok := rhs.(types.Int)
|
|
if !ok {
|
|
return types.ValOrErr(rhs, "unexpected type '%v' passed to randomInt", rhs.Type())
|
|
}
|
|
min, max := int64(from), int64(to)
|
|
span, err := randomIntSpan(min, max)
|
|
if err != nil {
|
|
return types.NewErr("%v", err)
|
|
}
|
|
//nolint:gosec // G404: 用于生成POC测试随机数,非加密用途
|
|
return types.Int(rand.Int63n(span) + min)
|
|
},
|
|
},
|
|
{
|
|
Operator: "randomLowercase_int",
|
|
Unary: func(value ref.Val) ref.Val {
|
|
n, ok := value.(types.Int)
|
|
if !ok {
|
|
return types.ValOrErr(value, "unexpected type '%v' passed to randomLowercase", value.Type())
|
|
}
|
|
length, err := validateRandomStringLength(n)
|
|
if err != nil {
|
|
return types.NewErr("%v", err)
|
|
}
|
|
return types.String(randomLowercase(length))
|
|
},
|
|
},
|
|
{
|
|
Operator: "randomUppercase_int",
|
|
Unary: func(value ref.Val) ref.Val {
|
|
n, ok := value.(types.Int)
|
|
if !ok {
|
|
return types.ValOrErr(value, "unexpected type '%v' passed to randomUppercase", value.Type())
|
|
}
|
|
length, err := validateRandomStringLength(n)
|
|
if err != nil {
|
|
return types.NewErr("%v", err)
|
|
}
|
|
return types.String(randomUppercase(length))
|
|
},
|
|
},
|
|
{
|
|
Operator: "randomString_int",
|
|
Unary: func(value ref.Val) ref.Val {
|
|
n, ok := value.(types.Int)
|
|
if !ok {
|
|
return types.ValOrErr(value, "unexpected type '%v' passed to randomString", value.Type())
|
|
}
|
|
length, err := validateRandomStringLength(n)
|
|
if err != nil {
|
|
return types.NewErr("%v", err)
|
|
}
|
|
return types.String(randomString(length))
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func randomIntSpan(min, max int64) (int64, error) {
|
|
if max <= min {
|
|
return 0, fmt.Errorf("randomInt: max(%d) must be greater than min(%d)", max, min)
|
|
}
|
|
const maxInt64 = int64(^uint64(0) >> 1)
|
|
if min < 0 && max > maxInt64+min {
|
|
return 0, fmt.Errorf("randomInt: range too large")
|
|
}
|
|
return max - min, nil
|
|
}
|
|
|
|
func validateRandomStringLength(n types.Int) (int, error) {
|
|
if n < 0 || n > maxRandomStringLength {
|
|
return 0, fmt.Errorf("random string length must be between 0 and %d", maxRandomStringLength)
|
|
}
|
|
return int(n), nil
|
|
}
|