# HG changeset patch # User nrich@ii.net # Date 1229771715 0 # Node ID a4825c3e65e93f60e667347bb97b98d374b41e80 # Parent fd78e9cdc6e9921bf8f0518c3df251c445f37acf Bugfix: memory corruption possible after reallocs. Using a static buffer instead. Will need to check for overflows on static buffer. diff -r fd78e9cdc6e9 -r a4825c3e65e9 dbd/db2/connection.c --- a/dbd/db2/connection.c Sat Dec 20 02:37:22 2008 +0000 +++ b/dbd/db2/connection.c Sat Dec 20 11:15:15 2008 +0000 @@ -223,6 +223,8 @@ * __gc */ static int connection_gc(lua_State *L) { + printf("Freeing connection\n"); + /* always close the connection */ connection_close(L); diff -r fd78e9cdc6e9 -r a4825c3e65e9 dbd/db2/statement.c --- a/dbd/db2/statement.c Sat Dec 20 02:37:22 2008 +0000 +++ b/dbd/db2/statement.c Sat Dec 20 11:15:15 2008 +0000 @@ -46,10 +46,9 @@ */ static int statement_close(lua_State *L) { statement_t *statement = (statement_t *)luaL_checkudata(L, 1, DBD_DB2_STATEMENT); - SQLRETURN rc = SQL_SUCCESS; if (statement->stmt) { - rc = SQLFreeHandle(SQL_HANDLE_STMT, statement->stmt); + SQLFreeStmt(statement->stmt, SQL_CLOSE); if (statement->resultset) free(statement->resultset); @@ -81,7 +80,8 @@ int errflag = 0; const char *errstr = NULL; SQLRETURN rc = SQL_SUCCESS; - unsigned char *buffer = NULL; + unsigned char b[1024]; + unsigned char *buffer = &b[0]; int offset = 0; resultset_t *resultset = NULL; bindparams_t *bind; /* variable to read the results */ @@ -134,7 +134,6 @@ errflag = rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO; break; case LUA_TNUMBER: - buffer = realloc(buffer, offset + sizeof(double)); num = (double *)buffer + offset; *num = lua_tonumber(L, p); offset += sizeof(double); @@ -147,7 +146,6 @@ errflag = rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO; break; case LUA_TBOOLEAN: - buffer = realloc(buffer, offset + sizeof(int)); boolean = (int *)buffer + offset; *boolean = lua_toboolean(L, p); offset += sizeof(int); @@ -168,7 +166,6 @@ } if (errflag) { - realloc(buffer, 0); lua_pushboolean(L, 0); if (errstr) { @@ -252,11 +249,6 @@ statement->bind = bind; } - /* - * free the buffer with a resize to 0 - */ - realloc(buffer, 0); - lua_pushboolean(L, 1); return 1; } @@ -268,6 +260,11 @@ int i; int d; + SQLCHAR message[SQL_MAX_MESSAGE_LENGTH + 1]; + SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1]; + SQLINTEGER sqlcode; + SQLSMALLINT length; + SQLRETURN rc = SQL_SUCCESS; if (!statement->resultset || !statement->bind) { @@ -278,15 +275,22 @@ /* fetch each row, and display */ rc = SQLFetch(statement->stmt); if (rc == SQL_NO_DATA_FOUND) { + SQLFreeStmt(statement->stmt, SQL_RESET_PARAMS); lua_pushnil(L); return 1; } + if (rc != SQL_SUCCESS) { + SQLGetDiagRec(SQL_HANDLE_STMT, statement->stmt, 1, sqlstate, &sqlcode, message, SQL_MAX_MESSAGE_LENGTH + 1, &length); + + luaL_error(L, DBI_ERR_FETCH_FAILED, message); + } + d = 1; lua_newtable(L); for (i = 0; i < statement->num_result_columns; i++) { lua_push_type_t lua_push = db2_to_lua_push(statement->resultset[i].type, statement->bind[i].len); - const char *name = strlower((char *)statement->resultset[i].name); + const char *name = strlower(statement->resultset[i].name); double val; char *value = (char *)statement->bind[i].buffer; diff -r fd78e9cdc6e9 -r a4825c3e65e9 dbd/mysql/connection.c --- a/dbd/mysql/connection.c Sat Dec 20 02:37:22 2008 +0000 +++ b/dbd/mysql/connection.c Sat Dec 20 11:15:15 2008 +0000 @@ -157,6 +157,7 @@ quoted_len = mysql_real_escape_string(conn->mysql, to, from, len); lua_pushlstring(L, to, quoted_len); + free(to); return 1; } diff -r fd78e9cdc6e9 -r a4825c3e65e9 dbd/mysql/statement.c --- a/dbd/mysql/statement.c Sat Dec 20 02:37:22 2008 +0000 +++ b/dbd/mysql/statement.c Sat Dec 20 11:15:15 2008 +0000 @@ -70,7 +70,8 @@ int num_bind_params = n - 1; int expected_params; - unsigned char *buffer = NULL; + unsigned char b[1024]; + unsigned char *buffer = &b[0]; int offset = 0; MYSQL_BIND *bind = NULL; @@ -100,6 +101,11 @@ } bind = malloc(sizeof(MYSQL_BIND) * num_bind_params); + + if (bind == NULL) { + luaL_error(L, "Could not alloc bind params\n"); + } + memset(bind, 0, sizeof(MYSQL_BIND) * num_bind_params); for (p = 2; p <= n; p++) { @@ -119,7 +125,6 @@ break; case LUA_TBOOLEAN: - buffer = realloc(buffer, offset + sizeof(int)); boolean = (int *)buffer + offset; offset += sizeof(int); *boolean = lua_toboolean(L, p); @@ -135,7 +140,6 @@ * num needs to be it's own * memory here */ - buffer = realloc(buffer, offset + sizeof(double)); num = (double *)buffer + offset; offset += sizeof(double); *num = lua_tonumber(L, p); @@ -147,7 +151,6 @@ break; case LUA_TSTRING: - buffer = realloc(buffer, offset + sizeof(size_t)); str_len = (size_t *)buffer + offset; offset += sizeof(size_t); str = lua_tolstring(L, p, str_len); @@ -183,13 +186,9 @@ } cleanup: - /* - * free the buffer with a resize to 0 - */ - realloc(buffer, 0); - - if (bind) + if (bind) { free(bind); + } if (error_message) { lua_pushboolean(L, 0); @@ -223,6 +222,7 @@ return 1; } + column_count = mysql_num_fields(statement->metadata); if (column_count > 0) {