View Single Post
  #1  
Old 07-28-2003, 06:25 AM
Deawin
Fire Beetle
 
Join Date: Jun 2003
Location: Vienna, Austria
Posts: 11
Default Fix crash in Database::GetSharedBank

Code:
void Database::GetSharedBank(int32 account_id,Shared_Bank_Struct* sharedbank){
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	unsigned long* lengths;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT sharedbank from account WHERE id=%i", account_id), errbuf, &result)) {
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1) {	
			row = mysql_fetch_row(result);
			lengths = mysql_fetch_lengths(result);
			if (lengths[0] == sizeof(Shared_Bank_Struct)) {
				memcpy(sharedbank, row[0], sizeof(Shared_Bank_Struct));
				mysql_free_result(result);
				return;
			}
			else{
				cerr << "Length error in GetSharedBank.  Expected: " << sizeof(Shared_Bank_Struct) << ", Got: " << lengths[0] << endl;
				mysql_free_result(result);
				return;
			}


		}
	}
	else
	{
		cerr << "Err in Database::GetSharedBank(int32 account_id): " << errbuf << endl;
		mysql_free_result(result);   // <- HERE
	}
}

At the very end of this function, mysql_free_result(result) should not be called if RunQuery() returned false.
This crashed on my machine because my DB layout was a little wrong but could crash on other occasions as well.

Maybe DBcore::RunQuery should set *result to NULL at the beginning of the function so that you can check if it needs to be freed in the code elsewhere (like above):
Code:
if(result) mysql_free_result(result);
or build a macro around it, or whatever.

Hope that helps and please to ignore if I am totally wrong :P
Markus
Reply With Quote