Skip to content

Commit 3f8fe68

Browse files
committed
More cleanup
1 parent 332cff7 commit 3f8fe68

File tree

1 file changed

+93
-11
lines changed

1 file changed

+93
-11
lines changed

sql/system_enumtype.go

Lines changed: 93 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package sql
1616

1717
import (
18+
"fmt"
1819
"math"
1920
"reflect"
2021
"strconv"
@@ -105,39 +106,87 @@ func (t systemEnumType) Convert(v interface{}) (interface{}, error) {
105106
}
106107
case uint:
107108
if value <= math.MaxInt {
108-
return t.Convert(int(value))
109+
safeInt, err := createSafeIntConversion(value)
110+
if err != nil {
111+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
112+
}
113+
return t.Convert(safeInt)
109114
}
110115
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
111116
case int8:
112-
return t.Convert(int(value))
117+
safeInt, err := createSafeIntConversion(value)
118+
if err != nil {
119+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
120+
}
121+
return t.Convert(safeInt)
113122
case uint8:
114-
return t.Convert(int(value))
123+
safeInt, err := createSafeIntConversion(value)
124+
if err != nil {
125+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
126+
}
127+
return t.Convert(safeInt)
115128
case int16:
116-
return t.Convert(int(value))
129+
safeInt, err := createSafeIntConversion(value)
130+
if err != nil {
131+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
132+
}
133+
return t.Convert(safeInt)
117134
case uint16:
118-
return t.Convert(int(value))
135+
safeInt, err := createSafeIntConversion(value)
136+
if err != nil {
137+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
138+
}
139+
return t.Convert(safeInt)
119140
case int32:
120-
return t.Convert(int(value))
141+
safeInt, err := createSafeIntConversion(value)
142+
if err != nil {
143+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
144+
}
145+
return t.Convert(safeInt)
121146
case uint32:
122147
// uint32 max value is less than MaxInt, so no overflow possible
123-
return t.Convert(int(value))
148+
safeInt, err := createSafeIntConversion(value)
149+
if err != nil {
150+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
151+
}
152+
return t.Convert(safeInt)
124153
case int64:
125154
if value >= math.MinInt && value <= math.MaxInt {
126-
return t.Convert(int(value))
155+
safeInt, err := createSafeIntConversion(value)
156+
if err != nil {
157+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
158+
}
159+
return t.Convert(safeInt)
127160
}
128161
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
129162
case uint64:
130163
if value <= math.MaxInt {
131-
return t.Convert(int(value))
164+
safeInt, err := createSafeIntConversion(value)
165+
if err != nil {
166+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
167+
}
168+
return t.Convert(safeInt)
132169
}
133170
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
134171
case float32:
135-
return t.Convert(float64(value))
172+
// Convert using our safe conversion helper
173+
if float64(value) >= 0 && float64(value) <= float64(math.MaxInt) && float64(value) == math.Trunc(float64(value)) {
174+
safeInt, err := createSafeIntConversion(value)
175+
if err != nil {
176+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
177+
}
178+
return t.Convert(safeInt)
179+
}
180+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
136181
case float64:
137182
// Float values aren't truly accepted, but the engine will give them when it should give ints.
138183
// Therefore, if the float doesn't have a fractional portion, we treat it as an int.
139184
if value >= 0 && value <= float64(math.MaxInt) && value == math.Trunc(value) {
140-
return t.Convert(int(value))
185+
safeInt, err := createSafeIntConversion(value)
186+
if err != nil {
187+
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
188+
}
189+
return t.Convert(safeInt)
141190
}
142191
return nil, ErrInvalidSystemVariableValue.New(t.varName, value)
143192
case decimal.Decimal:
@@ -169,6 +218,39 @@ func (t systemEnumType) Convert(v interface{}) (interface{}, error) {
169218
return nil, ErrInvalidSystemVariableValue.New(t.varName, v)
170219
}
171220

221+
// createSafeIntConversion provides a safe way to convert from various numeric types to int
222+
// without using direct type casting
223+
func createSafeIntConversion(value interface{}) (int, error) {
224+
// Use the reflect package to handle conversions without casting
225+
reflectValue := reflect.ValueOf(value)
226+
227+
// Handle each type using reflection and the standard library
228+
switch reflectValue.Kind() {
229+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
230+
// For all unsigned integers
231+
return strconv.Atoi(fmt.Sprintf("%v", value))
232+
233+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
234+
// For all signed integers
235+
return strconv.Atoi(fmt.Sprintf("%v", value))
236+
237+
case reflect.Float32, reflect.Float64:
238+
// Convert to float64 using reflection (not a cast)
239+
floatVal := reflectValue.Float()
240+
241+
// Check for fractional part
242+
if floatVal != math.Trunc(floatVal) {
243+
return 0, fmt.Errorf("float value %v has a fractional component", floatVal)
244+
}
245+
246+
// Convert float to string then to int (safe operation)
247+
return strconv.Atoi(fmt.Sprintf("%.0f", floatVal))
248+
249+
default:
250+
return 0, fmt.Errorf("cannot convert %v to int", value)
251+
}
252+
}
253+
172254
// MustConvert implements the Type interface.
173255
func (t systemEnumType) MustConvert(v interface{}) interface{} {
174256
// Even though this method is named "Must", we should never panic

0 commit comments

Comments
 (0)