Bug #84701 Overflow Exception - 64 bit enum value as parameter cast to Int32

Submitted: 28 Jan 2017 18:22 Modified: 24 Nov 2020 16:42
Reporter: Tim Wilkens Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S3 (Non-critical)
Version:6.9.9 OS:Windows
Assigned to: Assigned Account CPU Architecture:Any

[28 Jan 2017 18:22] Tim Wilkens
Description:
== What I Did ==

Pass an Enum value of underlying type ulong that is greater than 2^32 as a parameter to a query.

== What I Expected == 

Query executes returning expected data.

== What Happened ==

Connector throws an OverflowException and does not execute the query.

How to repeat:
See the following test program to observe the behavior. You will need to update the connection string to a mysql server instance you have access to. (Note: the content of the query should not matter since this throws an exception serializing the parameter and never sends it to the server)

using System;
using MySql.Data.MySqlClient;

namespace ConsoleApplication {
    class Program {
        public enum TestEnum : ulong {
            Value = ulong.MaxValue,
        }
        static void Main(string[] args) {
            string connStr = "";
            MySqlConnection conn = new MySqlConnection(connStr);
            try {
                conn.Open();
                string sql = "select * from test where id = @ID;";
                MySqlCommand command = new MySqlCommand(sql, conn);
                command.Parameters.AddWithValue("@ID", TestEnum.Value);
                MySqlDataReader rdr = command.ExecuteReader();
            } catch(Exception e) {
                Console.WriteLine(e);
            }
            conn.Close();
        }
    }
}

Building and running that should produce the following exception:

System.OverflowException: Value was either too large or too small for an Int32.
   at System.Convert.ToInt32(UInt64 value)
   at System.UInt64.System.IConvertible.ToInt32(IFormatProvider provider)
   at System.Convert.ToInt32(Object value, IFormatProvider provider)
   at System.Enum.System.IConvertible.ToInt32(IFormatProvider provider)
   at System.Convert.ToInt32(Object value)
   at MySql.Data.Types.MySqlInt32.MySql.Data.Types.IMySqlValue.WriteValue(MySqlPacket packet, Boolean binary, Object val, Int32 length)
   at MySql.Data.MySqlClient.MySqlParameter.Serialize(MySqlPacket packet, Boolean binary, MySqlConnectionStringBuilder settings)
   at MySql.Data.MySqlClient.Statement.SerializeParameter(MySqlParameterCollection parameters, MySqlPacket packet, String parmName, Int32 parameterIndex)
   at MySql.Data.MySqlClient.Statement.InternalBindParameters(String sql, MySqlParameterCollection parameters, MySqlPacket packet)
   at MySql.Data.MySqlClient.Statement.BindParameters()
   at MySql.Data.MySqlClient.PreparableStatement.Execute()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
   at ConsoleApplication.Program.Main(String[] args) in Program.cs:line 20

Suggested fix:
Respect the underlying type of Enum parameters and serialize to the appropriate type.
MySql.Data/parameter.cs seems to indicate that all Enum parameters are treated as Int32

case "Object":
          default:
#if RT
            if (t.GetTypeInfo().BaseType == typeof(Enum))
#else
            if( t.BaseType == typeof( Enum ) )
#endif
              MySqlDbType = MySqlDbType.Int32;
            else
              MySqlDbType = MySqlDbType.Blob;
            break;
[30 Jan 2017 7:34] Chiranjeevi Battula
Hello  Tim Wilkens,

Thank you for the bug report and test case.
Verified this behavior on Visual Studio 2013 (C#.Net) and Connector/NET 6.9.9 version.

Thanks,
Chiranjeevi.
[30 Jan 2017 7:35] Chiranjeevi Battula
Screenshot

Attachment: 84701.png (image/png, text), 163.28 KiB.

[24 Nov 2020 16:42] Christine Cole
Posted by developer:
 
Fixed as of the upcoming MySQL Connector/NET 8.0.23 release, and here's the proposed changelog entry from the documentation team:

Without validation, an underlying 64-bit enumeration value passed in as a
MySQL command parameter defaulted to type Int32 and produced an overflow
exception.

Thank you for the bug report.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.052 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.