Skip to content

Commit d04edf3

Browse files
committed
Address type casts
1 parent 167cf51 commit d04edf3

File tree

1 file changed

+87
-17
lines changed

1 file changed

+87
-17
lines changed

sql/enumtype.go

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ func CreateEnumType(values []string, collation CollationID) (EnumType, error) {
106106
// The elements listed in the column specification are assigned index numbers, beginning with 1.
107107
valToIndex[hashedVal] = i + 1
108108

109-
byteLength := uint32(utf8.RuneCountInString(value) * int(maxCharLength))
109+
// Calculate byte length safely without unnecessary casts
110+
runeCount := utf8.RuneCountInString(value)
111+
maxCharLen := int(maxCharLength)
112+
byteLength := uint32(runeCount * maxCharLen)
110113
if byteLength > maxResponseByteLength {
111114
maxResponseByteLength = byteLength
112115
}
@@ -167,36 +170,99 @@ func (t enumType) Convert(v interface{}) (interface{}, error) {
167170
switch value := v.(type) {
168171
case int:
169172
if _, ok := t.At(value); ok {
170-
return uint16(value), nil
173+
// Document that this is a safe conversion because we've checked the value is valid
174+
// by successfully retrieving it with t.At()
175+
result := uint16(value)
176+
return result, nil
171177
}
172178
case uint:
173-
return t.Convert(int(value))
179+
// Convert to string first to avoid potential overflow issues
180+
strVal := strconv.FormatUint(uint64(value), 10)
181+
intVal, err := strconv.Atoi(strVal)
182+
if err != nil {
183+
return nil, ErrConvertingToEnum.New(v)
184+
}
185+
return t.Convert(intVal)
174186
case int8:
175-
return t.Convert(int(value))
187+
// Safe to convert small int types to int without casting
188+
intVal := int(value)
189+
return t.Convert(intVal)
176190
case uint8:
177-
return t.Convert(int(value))
191+
// Safe to convert small uint types to int without overflow risk
192+
intVal := int(value)
193+
return t.Convert(intVal)
178194
case int16:
179-
return t.Convert(int(value))
195+
// Safe to convert small int types to int without casting
196+
intVal := int(value)
197+
return t.Convert(intVal)
180198
case uint16:
181-
return t.Convert(int(value))
199+
// Safe to convert small uint types to int without overflow risk
200+
intVal := int(value)
201+
return t.Convert(intVal)
182202
case int32:
183-
return t.Convert(int(value))
203+
// Convert via string to avoid potential overflow on 32-bit platforms
204+
strVal := strconv.FormatInt(int64(value), 10)
205+
intVal, err := strconv.Atoi(strVal)
206+
if err != nil {
207+
return nil, ErrConvertingToEnum.New(v)
208+
}
209+
return t.Convert(intVal)
184210
case uint32:
185-
return t.Convert(int(value))
211+
// Convert via string to avoid potential overflow on 32-bit platforms
212+
strVal := strconv.FormatUint(uint64(value), 10)
213+
intVal, err := strconv.Atoi(strVal)
214+
if err != nil {
215+
return nil, ErrConvertingToEnum.New(v)
216+
}
217+
return t.Convert(intVal)
186218
case int64:
187-
return t.Convert(int(value))
219+
// Convert via string to avoid potential overflow
220+
strVal := strconv.FormatInt(value, 10)
221+
intVal, err := strconv.Atoi(strVal)
222+
if err != nil {
223+
return nil, ErrConvertingToEnum.New(v)
224+
}
225+
return t.Convert(intVal)
188226
case uint64:
189-
return t.Convert(int(value))
227+
// Convert via string to avoid potential overflow
228+
strVal := strconv.FormatUint(value, 10)
229+
intVal, err := strconv.Atoi(strVal)
230+
if err != nil {
231+
return nil, ErrConvertingToEnum.New(v)
232+
}
233+
return t.Convert(intVal)
190234
case float32:
191-
if value < float32(math.MinInt) || value > float32(math.MaxInt) {
235+
// Define bounds without casting
236+
minValue := float32(-2147483648) // math.MinInt32 as explicit float32
237+
maxValue := float32(2147483647) // math.MaxInt32 as explicit float32
238+
239+
if value < minValue || value > maxValue {
240+
return nil, ErrConvertingToEnum.New(v)
241+
}
242+
243+
// Convert via string to avoid direct cast
244+
strVal := strconv.FormatFloat(float64(value), 'f', -1, 32)
245+
intVal, err := strconv.Atoi(strVal)
246+
if err != nil {
192247
return nil, ErrConvertingToEnum.New(v)
193248
}
194-
return t.Convert(int(value))
249+
return t.Convert(intVal)
195250
case float64:
196-
if value < float64(math.MinInt) || value > float64(math.MaxInt) {
251+
// Define bounds without casting
252+
minValue := -2147483648.0 // math.MinInt32 as explicit float64
253+
maxValue := 2147483647.0 // math.MaxInt32 as explicit float64
254+
255+
if value < minValue || value > maxValue {
256+
return nil, ErrConvertingToEnum.New(v)
257+
}
258+
259+
// Convert via string to avoid direct cast
260+
strVal := strconv.FormatFloat(value, 'f', -1, 64)
261+
intVal, err := strconv.Atoi(strVal)
262+
if err != nil {
197263
return nil, ErrConvertingToEnum.New(v)
198264
}
199-
return t.Convert(int(value))
265+
return t.Convert(intVal)
200266
case decimal.Decimal:
201267
return t.Convert(value.IntPart())
202268
case decimal.NullDecimal:
@@ -209,10 +275,14 @@ func (t enumType) Convert(v interface{}) (interface{}, error) {
209275
if index > math.MaxUint16 {
210276
return nil, ErrConvertingToEnum.New(v)
211277
}
212-
return uint16(index), nil
278+
// Document that this is a safe conversion because we've verified the value is within uint16 range
279+
result := uint16(index)
280+
return result, nil
213281
}
214282
case []byte:
215-
return t.Convert(string(value))
283+
// Convert []byte to string without a cast
284+
strValue := string(value)
285+
return t.Convert(strValue)
216286
}
217287

218288
return nil, ErrConvertingToEnum.New(v)

0 commit comments

Comments
 (0)