8000 Fixed packet corruption issue when enum was not 4 bytes by daebo01 · Pull Request #1421 · mysql-net/MySqlConnector · GitHub
[go: up one dir, main page]

Skip to content

Fixed packet corruption issue when enum was not 4 bytes #1421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

daebo01
Copy link
Contributor
@daebo01 daebo01 commented Dec 17, 2023

Fixed an issue where packets were corrupted when enum was not 4 bytes

This appears to be because the column type and the actual size of data used in the SingleCommandPayloadCreator.WriteBinaryParameters function are different.

Code and screenshots to reproduce the issue are provided below

Please check

CREATE TABLE `test1` (
	`Id` INT NOT NULL AUTO_INCREMENT,
	`A` TINYINT NOT NULL,
	`B` INT NOT NULL,
	`C` INT NOT NULL,
	PRIMARY KEY (`Id`)
);
internal class TestLogic
{
    private readonly MySqlConnection _connection;

    public TestLogic(string connStr)
    {
        _connection = new MySqlConnection(connStr);
    }

    public async Task Run()
    {
        
        await _connection.OpenAsync();

        await InsertDummyRow();
        var list = await SelectAllRow();

        foreach (var row in list)
        {
            Console.WriteLine(row);
        }
    }

    private async Task InsertDummyRow()
    {
        using var cmd = _connection.CreateCommand();
        cmd.CommandText = @"
            INSERT INTO test1 (A, B, C) 
                   VALUES (@A, @B, @C)";

        cmd.Parameters.AddWithValue("@A", TestEnum1.X);
        cmd.Parameters.AddWithValue("@B", 0x40302010);
        cmd.Parameters.AddWithValue("@C", 0);

        await cmd.PrepareAsync();

        await cmd.ExecuteNonQueryAsync();
    }

    private async Task<List<TestTable1Model>> SelectAllRow()
    {
        using var cmd = _connection.CreateCommand();
        cmd.CommandText = @"
            SELECT Id, A, B, C
              FROM test1 LIMIT 1000";

        await cmd.PrepareAsync();

        var list = new List<TestTable1Model>();
        var reader = await cmd.ExecuteReaderAsync();

        while (await reader.ReadAsync())
        {
            var row = new TestTable1Model
            {
                Id = reader.GetInt32(0),
                A = (TestEnum1)reader.GetByte(1),
                B = reader.GetInt32(2),
                C = reader.GetInt32(3),
            };

            list.Add(row);
        }

        return list;
    }
}

internal class TestTable1Model
{
    public required int Id { get; set; }

    public required TestEnum1 A { get; set; }

    public required int B { get; set; }

    public required int C { get; set; }

    public override string ToString() => $"Id: {Id}, A: {A}, B: {B:X}, C: {C:X}";
}

internal enum TestEnum1 : sbyte
{
    None = 0,
    X = 1,
    Y = 2,
    Z = 3,
};

test

@daebo01 daebo01 force-pushed the enum-serialize-fix-pr branch 2 times, most recently from d5f2875 to 8ce6859 Compare December 17, 2023 11:46
Signed-off-by: Alisha Kim <pril@pril.cc>
@daebo01 daebo01 force-pushed the enum-serialize-fix-pr branch from 8ce6859 to 9352d48 Compare December 17, 2023 11:58
@bgrainger
Copy link
Member
bgrainger commented Dec 17, 2023

This appears to be because the column type and the actual size of data used in the SingleCommandPayloadCreator.WriteBinaryParameters function are different.

This is the bug. More concretely, the parameter_type value sent earlier in the COM_STMT_EXECUTE packet doesn't match the format of the data that is sent later.

This PR doesn't fix the underlying problem for the general case where the user uses an enum whose underlying type doesn't match the column definition. Thanks for bringing this to my attention; I have an idea of how this might be fixed. Edit: I thought this was a bigger issue than just enums; it's not but it can still be solved without nested type tests.

(This may also have been made worse by #1384 which caused the MySqlDbType property to be ignored.)

@bgrainger bgrainger merged commit bd53d6e into mysql-net:master Dec 18, 2023
@bgrainger
Copy link
Member

Thanks for the PR! Fixed in 2.3.2.

@daebo01
Copy link
Contributor Author
daebo01 commented Dec 19, 2023

thanks for checking

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0