Skip Menu |

This queue is for tickets about the DBD-mysql CPAN distribution.

Report information
The Basics
Id: 40278
Status: resolved
Priority: 0/
Queue: DBD-mysql

People
Owner: Nobody in particular
Requestors: cpan [...] askneil.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: core dump in DBD-mysql-4.009
Date: Wed, 22 Oct 2008 14:18:59 -0700
To: bug-DBD-mysql [...] rt.cpan.org
From: Neil Katin <cpan [...] askneil.com>
Hi there. I found a core dump problem in DBD-mysql. It happens in 4.009, as well as earlier versions. The problem is an uninitialized variable in dbdimp.c/dbd_bind_ph(). The slen variable is uninitialized, and if the SQL type is specified and translated as a MYSQL_TYPE_BLOB this uninitialized value is saved in the buffer_length bind parameter variable. I had trouble coming up with a small test case, since it depends on the stack parameters, but you can see a random length being passed into libmysqlclient (if you have debugging turned on and MYSQL_DEBUG set...) I wasn't sure if the length had to be set on integer/double parameters, so I set it anyway. The key line is this one: ! if (buffer_type == MYSQL_TYPE_STRING || buffer_type == MYSQL_TYPE_BLOB) Although, not debug printing the entire blob seemed reasonable a few lines below that one (it is already printed at the start of the routine...) Here's the patch I used to fix the problem: *** DBD-mysql-4.009/dbdimp.c 2008-10-21 20:50:22.000000000 -0400 --- DBD-mysql-4.009-fixed/dbdimp.c 2008-10-22 16:25:24.000000000 -0400 *************** *** 4278,4283 **** --- 4278,4284 ---- PerlIO_printf(DBILOGFP, "\t\tTRY TO BIND AN INT NUMBER\n"); buffer_type= MYSQL_TYPE_LONG; + buffer_length = sizeof imp_sth->fbind[idx].numeric_val.lval; imp_sth->fbind[idx].numeric_val.lval= SvIV(imp_sth->params[idx].value); buffer=(void*)&(imp_sth->fbind[idx].numeric_val.lval); if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) *************** *** 4294,4299 **** --- 4295,4301 ---- PerlIO_printf(DBILOGFP, "\t\tTRY TO BIND A FLOAT NUMBER\n"); buffer_type= MYSQL_TYPE_DOUBLE; + buffer_length = sizeof imp_sth->fbind[idx].numeric_val.dval; imp_sth->fbind[idx].numeric_val.dval= SvNV(imp_sth->params[idx].value); buffer=(char*)&(imp_sth->fbind[idx].numeric_val.dval); *************** *** 4320,4333 **** break; } ! if (buffer_type == MYSQL_TYPE_STRING) { buffer= SvPV(imp_sth->params[idx].value, slen); buffer_length= slen; if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) PerlIO_printf(DBILOGFP, ! " SCALAR type %d ->%s<- IS A STRING\n", ! sql_type, buffer); } } else --- 4322,4335 ---- break; } ! if (buffer_type == MYSQL_TYPE_STRING || buffer_type == MYSQL_TYPE_BLOB) { buffer= SvPV(imp_sth->params[idx].value, slen); buffer_length= slen; if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) PerlIO_printf(DBILOGFP, ! " SCALAR type %d ->length %d<- IS A STRING or BLOB\n", ! sql_type, buffer_length); } } else
Hi! Thank you for reporting this and sending me a patch! So, I will get this patch in and release 4.010 asap. I don't need that debug in there, so I'll just rip it out. Overkill. --Patrick On Wed Oct 22 17:19:31 2008, cpan@askneil.com wrote: Show quoted text
> > Hi there. I found a core dump problem in DBD-mysql. It happens in > 4.009, as > well as earlier versions. > > The problem is an uninitialized variable in dbdimp.c/dbd_bind_ph(). > > The slen variable is uninitialized, and if the SQL type is specified > and translated as a MYSQL_TYPE_BLOB this uninitialized value is saved > in the buffer_length bind parameter variable. > > I had trouble coming up with a small test case, since it depends on > the > stack parameters, but you can see a random length being passed into > libmysqlclient (if you have debugging turned on and MYSQL_DEBUG > set...) > > I wasn't sure if the length had to be set on integer/double > parameters, > so I set it anyway. > > The key line is this one: > ! if (buffer_type == MYSQL_TYPE_STRING || buffer_type == > MYSQL_TYPE_BLOB) > > Although, not debug printing the entire blob seemed reasonable a few > lines below > that one (it is already printed at the start of the routine...) > > > Here's the patch I used to fix the problem: > > *** DBD-mysql-4.009/dbdimp.c 2008-10-21 20:50:22.000000000 -0400 > --- DBD-mysql-4.009-fixed/dbdimp.c 2008-10-22 16:25:24.000000000 > -0400 > *************** > *** 4278,4283 **** > --- 4278,4284 ---- > PerlIO_printf(DBILOGFP, "\t\tTRY TO BIND AN INT > NUMBER\n"); > > buffer_type= MYSQL_TYPE_LONG; > + buffer_length = sizeof imp_sth->fbind[idx].numeric_val.lval; > imp_sth->fbind[idx].numeric_val.lval= SvIV(imp_sth-
> >params[idx].value);
> buffer=(void*)&(imp_sth->fbind[idx].numeric_val.lval); > if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) > *************** > *** 4294,4299 **** > --- 4295,4301 ---- > PerlIO_printf(DBILOGFP, "\t\tTRY TO BIND A FLOAT > NUMBER\n"); > > buffer_type= MYSQL_TYPE_DOUBLE; > + buffer_length = sizeof imp_sth->fbind[idx].numeric_val.dval; > imp_sth->fbind[idx].numeric_val.dval= SvNV(imp_sth-
> >params[idx].value);
> buffer=(char*)&(imp_sth->fbind[idx].numeric_val.dval); > > *************** > *** 4320,4333 **** > break; > } > > ! if (buffer_type == MYSQL_TYPE_STRING) > { > buffer= SvPV(imp_sth->params[idx].value, slen); > buffer_length= slen; > if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) > PerlIO_printf(DBILOGFP, > ! " SCALAR type %d ->%s<- IS A STRING\n", > ! sql_type, buffer); > } > } > else > --- 4322,4335 ---- > break; > } > > ! if (buffer_type == MYSQL_TYPE_STRING || buffer_type == > MYSQL_TYPE_BLOB) > { > buffer= SvPV(imp_sth->params[idx].value, slen); > buffer_length= slen; > if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) > PerlIO_printf(DBILOGFP, > ! " SCALAR type %d ->length %d<- IS A STRING > or BLOB\n", > ! sql_type, buffer_length); > } > } > else >
Fixed with your patch, slightly modified in 4.010