diff --git a/functions/functions_conversion.go b/functions/functions_conversion.go index 1243391..05642bd 100644 --- a/functions/functions_conversion.go +++ b/functions/functions_conversion.go @@ -448,19 +448,28 @@ func (f *TruncFunction) Execute(ctx *FunctionContext, args []interface{}) (inter return nil, err } - // 转换第一个参数为浮点数 - num := cast.ToFloat64(args[0]) + // 转换第一个参数为浮点数(NULL/非数值返回错误,不再静默当 0) + num, err := cast.ToFloat64E(args[0]) + if err != nil { + return nil, err + } // 转换第二个参数为整数(精度) - precision := cast.ToInt(args[1]) + precision, err := cast.ToIntE(args[1]) + if err != nil { + return nil, err + } // 精度不能为负数 if precision < 0 { return nil, fmt.Errorf("trunc precision cannot be negative") } - // 计算截断 + // 计算截断。precision 过大时 multiplier 溢出为 +Inf,截断无意义,报错。 multiplier := math.Pow(10, float64(precision)) + if math.IsInf(multiplier, 0) { + return nil, fmt.Errorf("trunc precision %d too large", precision) + } if num >= 0 { return math.Floor(num*multiplier) / multiplier, nil } else { diff --git a/functions/functions_conversion_test.go b/functions/functions_conversion_test.go index eaccfa7..f72f97f 100644 --- a/functions/functions_conversion_test.go +++ b/functions/functions_conversion_test.go @@ -182,6 +182,24 @@ func TestNewConversionFunctions(t *testing.T) { args: []interface{}{3.14159, -1}, wantErr: true, }, + { + name: "trunc nil input returns error", + funcName: "trunc", + args: []interface{}{nil, 2}, + wantErr: true, + }, + { + name: "trunc non-numeric input returns error", + funcName: "trunc", + args: []interface{}{"abc", 2}, + wantErr: true, + }, + { + name: "trunc precision too large returns error", + funcName: "trunc", + args: []interface{}{3.14, 400}, + wantErr: true, + }, } for _, tt := range tests { diff --git a/functions/functions_math.go b/functions/functions_math.go index 079ba23..ef6c351 100644 --- a/functions/functions_math.go +++ b/functions/functions_math.go @@ -353,7 +353,11 @@ func (f *ExpFunction) Execute(ctx *FunctionContext, args []interface{}) (interfa if err != nil { return nil, err } - return math.Exp(val), nil + result := math.Exp(val) + if math.IsNaN(result) || math.IsInf(result, 0) { + return nil, fmt.Errorf("exp(%v) out of range", val) + } + return result, nil } // FloorFunction 向下取整函数 @@ -723,5 +727,9 @@ func (f *PowerFunction) Execute(ctx *FunctionContext, args []interface{}) (inter if err != nil { return nil, err } - return math.Pow(x, y), nil + result := math.Pow(x, y) + if math.IsNaN(result) || math.IsInf(result, 0) { + return nil, fmt.Errorf("pow(%v, %v) out of range", x, y) + } + return result, nil } diff --git a/functions/functions_math_test.go b/functions/functions_math_test.go index b80eec4..504d4a0 100644 --- a/functions/functions_math_test.go +++ b/functions/functions_math_test.go @@ -175,6 +175,27 @@ func TestMathFunctions(t *testing.T) { expected: nil, wantErr: true, }, + { + name: "exp overflow returns error", + funcName: "exp", + args: []interface{}{1000}, + expected: nil, + wantErr: true, + }, + { + name: "pow overflow returns error", + funcName: "pow", + args: []interface{}{10, 400}, + expected: nil, + wantErr: true, + }, + { + name: "pow negative base fractional exp returns error", + funcName: "pow", + args: []interface{}{-2, 0.5}, + expected: nil, + wantErr: true, + }, { name: "log natural", funcName: "log",