Bug #22114 Incorrect field length from mysql_stmt_bind_result() and mysql_fetch_fields()
Submitted: 8 Sep 2006 11:45 Modified: 8 Sep 2006 12:01
Reporter: emerson clarke Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.0 OS:Windows (Windows)
Assigned to: CPU Architecture:Any

[8 Sep 2006 11:45] emerson clarke
Description:
See bug #8550

http://bugs.mysql.com/bug.php?id=8550

Basically, when using the MYSQL_FIELD structure to determine the length and max_length of a field, the MYSQL_TIME type and any derivatives return a length of 30 bytes, but the libraries will write 36 bytes corrupting the heap.

I have confirmed that the libraries and dll's in use are the correct versions for the server.

How to repeat:
Assuming you have a MYSQL_STMT, and MYSQL object, the following code reproduces
the bug as long as there is a date, time or timestamp field in the query.

MYSQL * db = ??;
MYSQL_STMT * st = ??;

MYSQL_RES * res = mysql_stmt_result_metadata(st);
int fields = mysql_num_fields(res);

// Use any fixed length here, its not important
char bindBuffer[256];
unsigned long * bindLengths = new unsigned long[fields];

MYSQL_FIELD * field = mysql_fetch_fields(res);
for (int i=0;i<fields;++i)
{	
    int length = (field[i].max_length)?field[i].max_length:field[i].length;
    bind[i].buffer_length = length; 			
    bind[i].buffer_type = field[i].type;
    bind[i].buffer = bindBuffer;
    bind[i].length = &bindLengths[i]; 
}

mysql_stmt_bind_result(st,bind);

int state=0;
while ((state=mysql_stmt_fetch(st))==0)
{
    for (int i=0;i<fields;++i)
    {	
	assert(bindLengths[i] <= bind[i].buffer_length);
    }
}

Suggested fix:
The fix is to ignore the information from MYSQL_FIELD when using MYSQL_TIME fields and instead use sizof(MYSQL_TIME).

But the correct solution of course it to have the library report the right length.
[8 Sep 2006 12:01] Valeriy Kravchuk
Thank you for a problem report. It is a duplciate of bug #8550. Sorry for it hanging in "No feedback" state for ages, with feedback (from you) in place. I am reopening it now.