@@ -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