Skip to content

Commit

Permalink
ODBC-289 Possible crash in case of array fetch
Browse files Browse the repository at this point in the history
In case of reexecuting fetch was possible when old bind is already
freed, and newly allocated bind structures have not been bound yet.
Fix of tests on windows in addition to previous commit
  • Loading branch information
lawrinn committed Oct 15, 2020
1 parent e4a8297 commit 22f1255
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 11 deletions.
2 changes: 1 addition & 1 deletion libmariadb
17 changes: 13 additions & 4 deletions ma_statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -2000,14 +2000,23 @@ SQLRETURN MADB_StmtFetch(MADB_Stmt *Stmt)
}

Stmt->LastRowFetched= 0;
Rows2Fetch= MADB_RowsToFetch(&Stmt->Cursor, Stmt->Ard->Header.ArraySize, mysql_stmt_num_rows(Stmt->stmt));

if (Stmt->result == NULL && !(Stmt->result= (MYSQL_BIND *)MADB_CALLOC(sizeof(MYSQL_BIND) * mysql_stmt_field_count(Stmt->stmt))))
if (Stmt->result == NULL)
{
MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
return Stmt->Error.ReturnValue;
if (!(Stmt->result= (MYSQL_BIND *)MADB_CALLOC(sizeof(MYSQL_BIND) * mysql_stmt_field_count(Stmt->stmt))))
{
MADB_SetError(&Stmt->Error, MADB_ERR_HY001, NULL, 0);
return Stmt->Error.ReturnValue;
}
if (Rows2Fetch > 1)
{
// We need something to be bound after executing for MoveNext function
mysql_stmt_bind_result(Stmt->stmt, Stmt->result);
}
}

Rows2Fetch= MADB_RowsToFetch(&Stmt->Cursor, Stmt->Ard->Header.ArraySize, mysql_stmt_num_rows(Stmt->stmt));

if (Rows2Fetch == 0)
{
return SQL_NO_DATA;
Expand Down
4 changes: 1 addition & 3 deletions test/basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,7 @@ ODBC_TEST(t_disconnect)
SQLRETURN rc;
int i;
SQLHSTMT hstmt;
SQLWCHAR dsn[256],
username[64],
passwd[64];

rc= SQLAllocHandle(SQL_HANDLE_DBC, Env, &hdbc1);
CHECK_ENV_RC(Env, rc);
rc= SQLConnectW(hdbc1, wdsn, SQL_NTS, wuid, SQL_NTS, wpwd, SQL_NTS);
Expand Down
35 changes: 33 additions & 2 deletions test/cursor.c
Original file line number Diff line number Diff line change
Expand Up @@ -3394,7 +3394,7 @@ ODBC_TEST(odbc289)
SQLLEN i, rowsToInsert= 3, rowsToFetch= 2;
SQLINTEGER value[2]= {0, 0};

OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS t_odbc289");
/* OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS t_odbc289");
OK_SIMPLE_STMT(Stmt, "CREATE TABLE t_odbc289 (`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT)");
for (i = 0; i < rowsToInsert; ++i)
Expand All @@ -3415,7 +3415,38 @@ ODBC_TEST(odbc289)
CHECK_STMT_RC(Stmt, SQLFetch(Stmt));
CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));
OK_SIMPLE_STMT(Stmt, "DROP TABLE t_odbc289");
OK_SIMPLE_STMT(Stmt, "DROP TABLE t_odbc289");*/
SQLCHAR value2[60];
SQLLEN length[2];

OK_SIMPLE_STMT(Stmt, "DROP TABLE IF EXISTS CUST");
OK_SIMPLE_STMT(Stmt, "CREATE TABLE CUST (`LAST_NAME` VARCHAR(29) NOT NULL)");
for (i = 0; i < rowsToInsert; ++i)
{
OK_SIMPLE_STMT(Stmt, "INSERT INTO CUST VALUES('whatever')");
}
CHECK_STMT_RC(Stmt, SQLPrepare(Stmt, "SELECT LAST_NAME FROM CUST", SQL_NTS));

CHECK_STMT_RC(Stmt, SQLSetStmtAttr(Stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)2, SQL_IS_INTEGER));

CHECK_STMT_RC(Stmt, SQLBindCol(Stmt, 1, SQL_CHAR, value2, 30, length));

CHECK_STMT_RC(Stmt, SQLExecute(Stmt));

CHECK_STMT_RC(Stmt, SQLFetch(Stmt));

printf("fetch: %s\n", value2);

printf("fetch: %s\n", value2 + 30);

CHECK_STMT_RC(Stmt, SQLFreeStmt(Stmt, SQL_CLOSE));

CHECK_STMT_RC(Stmt, SQLExecute(Stmt));

CHECK_STMT_RC(Stmt, SQLFetch(Stmt));

printf("fetch: %s\n", value2);
printf("fetch: %s\n", value2 + 30);

return OK;
}
Expand Down
2 changes: 1 addition & 1 deletion test/tap.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ size_t madbtest_convert_string(MARIADB_CHARSET_INFO *from_cs, const char *from,
*errorcode= 0;
#ifdef _WIN32
converted_len= MultiByteToWideChar(from_cs->codepage, 0, from, (int)*from_len, (wchar_t*)to, (int)*to_len);
rc= (converted_len < 1 ? -1 : 0);
rc= (converted_len < 1 ? -1 : converted_len*sizeof(SQLWCHAR));
*errorcode= GetLastError();
#else
rc= MADB_ConvertString(from, from_len, from_cs, to, to_len, to_cs, errorcode);
Expand Down

0 comments on commit 22f1255

Please sign in to comment.