Integer underflow while processing packets

Bug #1613217 reported by Oxygen
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Drizzle Client & Protocol Library
New
Undecided
Unassigned

Bug Description

When I was trying to buffer results for prepared statements using "drizzle_stmt_buffer", it returns DRIZZLE_RETURN_BAD_PACKET_NUMBER : drizzle_state_packet_read:bad packet number:54:0

Debug log:
.....
DEBUG: drizzle_state_packet_read
DEBUG: buffer_size= 130, packet_size= 62, packet_number= 51
DEBUG: drizzle_state_row_read
DEBUG: drizzle_state_packet_read
DEBUG: buffer_size= 64, packet_size= 32, packet_number= 52
DEBUG: drizzle_state_row_read
DEBUG: drizzle_state_packet_read
DEBUG: buffer_size= 28, packet_size= 62, packet_number= 53
DEBUG: drizzle_state_row_read
DEBUG: drizzle_state_packet_read
** FATAL : [9] drizzle_state_packet_read:bad packet number:54:0

I did some modifications to print out "con->buffer_size", and I got:
.....
DEBUG: buffer_size= 64, packet_size= 32, packet_number= 52
DEBUG: drizzle_state_row_read
DEBUG: drizzle_state_packet_read, con->buffer_size = 28
DEBUG: buffer_size= 28, packet_size= 62, packet_number= 53
DEBUG: drizzle_state_row_read
DEBUG: drizzle_state_packet_read, con->buffer_size = 18446744073709551585 <-- there it is !
** FATAL : [9] drizzle_state_packet_read:bad packet number:54:0

Here we can see "con->buffer_size" was underflowed.
This happens every time when the SQL gives a large set of rows, and we can see the "buffer_size" field is smaller than "packet_size". So I guess the response packet was not complete that causes the integer underflow.

I did some possible fix in "state.cc", the attachment is the diff file.

Test code:
static void fatal(drizzle_return_t ret, drizzle_st *con)
{
    fprintf(stderr, "** FATAL : [%d] %s\n", (int)ret, drizzle_error(con));
    exit(ret);
}

int main()
{
    drizzle_st *con = drizzle_create("1.1.1.1", 3306, "user", "passwd", "testdb", NULL);
    con->verbose = DRIZZLE_VERBOSE_MAX;

    drizzle_return_t ret;
    if ((ret = drizzle_connect(con)) != DRIZZLE_RETURN_OK)
        fatal(ret, con);

    const char *query= "SELECT id, state, result, timestamp FROM some_table WHERE state = ?";
    drizzle_stmt_st *stmt = drizzle_stmt_prepare(con, query, strlen(query), &ret);

    printf("params: %" PRIu16 "\n", drizzle_stmt_param_count(stmt));
    if ((ret = drizzle_stmt_set_int(stmt, 0, 1, false)) != DRIZZLE_RETURN_OK)
        fatal(ret, con);

    printf("execute\n");
    if ((ret = drizzle_stmt_execute(stmt)) != DRIZZLE_RETURN_OK)
        fatal(ret, con);

    printf("buffer\n");
    if ((ret = drizzle_stmt_buffer(stmt)) != DRIZZLE_RETURN_OK)
        fatal(ret, con);

    while ((ret = drizzle_stmt_fetch(stmt)) != DRIZZLE_RETURN_ROW_END)
    {
        size_t size;
        drizzle_return_t retv = DRIZZLE_RETURN_OK;
        const char *id = drizzle_stmt_get_string(stmt, 0, &size, &retv);
        const char *state = drizzle_stmt_get_string(stmt, 1, &size, &retv);
        const char *result = drizzle_stmt_get_string(stmt, 2, &size, &retv);
        const char *timestamp = drizzle_stmt_get_string(stmt, 3, &size, &retv);
        fprintf(stderr, "id: %s, state: %s, result: %s, timestamp: %s\n", id, state, result, timestamp);
    }

    printf("rows found: %" PRIu64 "\n", drizzle_stmt_row_count(stmt));
    drizzle_stmt_close(stmt);

    printf("quit\n");
    drizzle_quit(con);
    return 0;
}

Revision history for this message
Oxygen (chenzhuoyu1992) wrote :
Revision history for this message
Marenz (marenz) wrote :

seeing the low activity in this project, I doubt your bug will be looked at here. You could however report it to https://github.com/sociomantic-tsunami/libdrizzle-redux

Revision history for this message
Oxygen (chenzhuoyu1992) wrote :

OK, I'll create a pull request on that GitHub repository.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.