Skip to content
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

Don't confuse length encoded int with EOF #179

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions contrib/ruby/test/client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1122,4 +1122,21 @@ def test_error_classes_exclusively_match_subclasses
assert_operator SystemCallError, :===, klass.new
assert_operator Trilogy::ConnectionError, :===, klass.new
end

def test_reads_row_not_eof
# We're going to write a big packet, so ensure we are allowed to send it
set_max_allowed_packet(32 * 1024 * 1024)
client = new_tcp_client
create_test_table(client)

# Write a value whose length will require an 8-byte length-encoded int
value = "x" * 2 ** 24
client.query("INSERT INTO `trilogy_test` (`long_text_test`) VALUES (\"#{value}\")")

# Ensure we read the row and don't confuse it with an EOF packet
result = client.query("SELECT `long_text_test` FROM `trilogy_test` LIMIT 1")
assert_equal value.length, result.rows[0][0].length
ensure
ensure_closed client
end
end
47 changes: 25 additions & 22 deletions src/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static int read_err_packet(trilogy_conn_t *conn)
return TRILOGY_ERR;
}

static int read_eof_packet(trilogy_conn_t *conn)
static int read_deprecated_eof_packet(trilogy_conn_t *conn)
{
trilogy_eof_packet_t eof_packet;

Expand All @@ -236,6 +236,21 @@ static int read_eof_packet(trilogy_conn_t *conn)
return TRILOGY_EOF;
}

static int read_eof_packet(trilogy_conn_t *conn)
{
int rc;

if (conn->capabilities & TRILOGY_CAPABILITIES_DEPRECATE_EOF) {
return read_ok_packet(conn);
} else {
if ((rc = read_deprecated_eof_packet(conn)) != TRILOGY_EOF) {
return rc;
}

return TRILOGY_OK;
}
}

static int read_auth_switch_packet(trilogy_conn_t *conn, trilogy_handshake_t *handshake)
{
trilogy_auth_switch_request_packet_t auth_switch_packet;
Expand Down Expand Up @@ -647,15 +662,7 @@ static int read_eof(trilogy_conn_t *conn)
return rc;
}

if (conn->capabilities & TRILOGY_CAPABILITIES_DEPRECATE_EOF) {
return read_ok_packet(conn);
} else {
if ((rc = read_eof_packet(conn)) != TRILOGY_EOF) {
return rc;
}

return TRILOGY_OK;
}
return read_eof_packet(conn);
}

int trilogy_read_row(trilogy_conn_t *conn, trilogy_value_t *values_out)
Expand All @@ -680,14 +687,12 @@ int trilogy_read_row(trilogy_conn_t *conn, trilogy_value_t *values_out)
return rc;
}

if (conn->capabilities & TRILOGY_CAPABILITIES_DEPRECATE_EOF && current_packet_type(conn) == TRILOGY_PACKET_EOF) {
if ((rc = read_ok_packet(conn)) != TRILOGY_OK) {
if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
if ((rc = read_eof_packet(conn)) != TRILOGY_OK) {
return rc;
}

return TRILOGY_EOF;
} else if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
return read_eof_packet(conn);
} else if (current_packet_type(conn) == TRILOGY_PACKET_ERR) {
return read_err_packet(conn);
} else {
Expand Down Expand Up @@ -941,20 +946,18 @@ int trilogy_stmt_bind_data_send(trilogy_conn_t *conn, trilogy_stmt_t *stmt, uint
int trilogy_stmt_read_row(trilogy_conn_t *conn, trilogy_stmt_t *stmt, trilogy_column_packet_t *columns,
trilogy_binary_value_t *values_out)
{
int err = read_packet(conn);
int rc = read_packet(conn);

if (err < 0) {
return err;
if (rc < 0) {
return rc;
}

if (conn->capabilities & TRILOGY_CAPABILITIES_DEPRECATE_EOF && current_packet_type(conn) == TRILOGY_PACKET_EOF) {
if ((err = read_ok_packet(conn)) != TRILOGY_OK) {
return err;
if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
if ((rc = read_eof_packet(conn)) != TRILOGY_OK) {
return rc;
}

return TRILOGY_EOF;
} else if (current_packet_type(conn) == TRILOGY_PACKET_EOF && conn->packet_buffer.len < 9) {
return read_eof_packet(conn);
} else if (current_packet_type(conn) == TRILOGY_PACKET_ERR) {
return read_err_packet(conn);
} else {
Expand Down
Loading