CC_lookup_cs_new() bug
am 27.07.2006 15:52:12 von David ChappelleThis is a multi-part message in MIME format.
------_=_NextPart_001_01C6B183.DC7A43D9
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
There is a bug in the function CC_lookup_cs_new(...) in connections.c.
Here is the stack trace from the crash.
=20
#0 0x7a748947 in TL_get_fieldval () from /usr/local/lib/psqlodbc.so
#1 0x7a74dfc9 in CC_lookup_cs_new () from /usr/local/lib/psqlodbc.so
#2 0x7a74e151 in CC_lookup_characterset () from
/usr/local/lib/psqlodbc.so
#3 0x7a72be6f in CC_connect () from /usr/local/lib/psqlodbc.so
#4 0x7a734afb in PGAPI_DriverConnect () from /usr/local/lib/psqlodbc.so
#5 0x7a74ba99 in SQLDriverConnect () from /usr/local/lib/psqlodbc.so
#6 0x68b58a92 in SQLDriverConnect () from /usr/local/lib/libodbc.so.1
=20
328 static char *
329 CC_lookup_cs_new(ConnectionClass *self)
330 {
331 char *encstr =3D NULL; =20
332 QResultClass *res;
333
334 res =3D CC_send_query(self, "select pg_client_encoding()",
NULL, CLEAR_RESULT_ON_ABORT);
335 if (res)
336 {
337 char *enc =3D QR_get_value_backend_row(res, 0, 0);
338
339 if (enc)
340 encstr =3D strdup(enc);
341 QR_Destructor(res);
342 }
343 return encstr;
344 }
=20
The call to CC_send_query returns a non-null result if PGRES_FATAL_ERROR
occurs and then passes the result to TL_get_fieldval via the macro
QR_get_value_backend_row without checking the status of res. In
execute.c I noticed that the result returned from CC_send_query is
checked appropriately as follows:
=20
659 /* If manual commit and in transaction, then proceed. */
660 if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
661 {
662 mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn,
stmt_string);
663
664 res =3D CC_send_query(conn, stmt_string, NULL,
CLEAR_RESULT_ON_ABORT);
665 if (!res)
666 {
667 /* error msg will be in the connection */
668 CC_on_abort(conn, NO_TRANS);
669 CC_log_error(func, "", conn);
670 return SQL_ERROR;
671 }
672
673 ok =3D QR_command_maybe_successful(res);
674 QR_Destructor(res);
=20
So the solution would appear to be adding a
QR_command_maybe_successful(res) check in CC_lookup_cs_new. However, why
not just handle this inside send query and return NULL if the result is
bad? Especially if the flag CLEAR_RESULT_ON_ABORT leads you to believe
this is the desired behaviour.
=20
=20
=20
Questions/Comments
=20
=20
David Chappelle
Software Engineer
519.880.2400 ext.3005
Sandvine Incorporated
http://www.sandvine.com=20
=20
------_=_NextPart_001_01C6B183.DC7A43D9
Content-Type: text/html;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
xmlns=3D"http://www.w3.org/TR/REC-html40">
charset=3Dus-ascii">
style=3D'font-size:10.0pt;
font-family:Arial'>There is a bug in the function =
CC_lookup_cs_new(…) in
connections.c. Here is the stack trace from the =
crash.
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'>#0 0x7a748947 in TL_get_fieldval () from
/usr/local/lib/psqlodbc.so
style=3D'font-size:10.0pt;
font-family:Arial'>#1 0x7a74dfc9 in CC_lookup_cs_new () from
/usr/local/lib/psqlodbc.so
style=3D'font-size:10.0pt;
font-family:Arial'>#2 0x7a74e151 in CC_lookup_characterset () from
/usr/local/lib/psqlodbc.so
style=3D'font-size:10.0pt;
font-family:Arial'>#3 0x7a72be6f in CC_connect () from
/usr/local/lib/psqlodbc.so
style=3D'font-size:10.0pt;
font-family:Arial'>#4 0x7a734afb in PGAPI_DriverConnect () from
/usr/local/lib/psqlodbc.so
style=3D'font-size:10.0pt;
font-family:Arial'>#5 0x7a74ba99 in SQLDriverConnect () from
/usr/local/lib/psqlodbc.so
style=3D'font-size:10.0pt;
font-family:Arial'>#6 0x68b58a92 in SQLDriverConnect () from
/usr/local/lib/libodbc.so.1
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'> 328 static char =
*
style=3D'font-size:10.0pt;
font-family:Arial'> 329 =
CC_lookup_cs_new(ConnectionClass
*self)
style=3D'font-size:10.0pt;
font-family:Arial'> 330 {
style=3D'font-size:10.0pt;
font-family:Arial'> 331
char *encstr =3D NULL; =
style=3D'font-size:10.0pt;
font-family:Arial'> 332
QResultClass *res;
style=3D'font-size:10.0pt;
font-family:Arial'> 333
style=3D'font-size:10.0pt;
font-family:Arial'> 334 res =
=3D
CC_send_query(self, "select pg_client_encoding()", NULL,
CLEAR_RESULT_ON_ABORT);
style=3D'font-size:10.0pt;
font-family:Arial'> 335 if =
(res)
style=3D'font-size:10.0pt;
font-family:Arial'> 336 =
{
style=3D'font-size:10.0pt;
font-family:Arial'>
337 =
char *enc
=3D QR_get_value_backend_row(res, 0, 0);
style=3D'font-size:10.0pt;
font-family:Arial'> 338
style=3D'font-size:10.0pt;
font-family:Arial'>
339 if =
(enc)
style=3D'font-size:10.0pt;
font-family:Arial'>
340 &nbs=
p;
encstr =3D strdup(enc);
style=3D'font-size:10.0pt;
font-family:Arial'>
341 =
QR_Destructor(res);
style=3D'font-size:10.0pt;
font-family:Arial'> 342 =
}
style=3D'font-size:10.0pt;
font-family:Arial'> 343 return
encstr;
style=3D'font-size:10.0pt;
font-family:Arial'> 344 }
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'>The call to CC_send_query returns a non-null result =
if PGRES_FATAL_ERROR
occurs and then passes the result to TL_get_fieldval via the macro =
QR_get_value_backend_row
without checking the status of res. In execute.c I noticed that the =
result
returned from CC_send_query is checked appropriately as =
follows:
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'> 659 /* If =
manual
commit and in transaction, then proceed. */
style=3D'font-size:10.0pt;
font-family:Arial'> 660 if
(!CC_is_in_autocommit(conn) && =
CC_is_in_trans(conn))
style=3D'font-size:10.0pt;
font-family:Arial'> 661 =
{
style=3D'font-size:10.0pt;
font-family:Arial'>
662 =
mylog("PGAPI_Transact:
sending on conn %d '%s'\n", conn, =
stmt_string);
style=3D'font-size:10.0pt;
font-family:Arial'> 663
style=3D'font-size:10.0pt;
font-family:Arial'>
664 res =3D =
CC_send_query(conn,
stmt_string, NULL, CLEAR_RESULT_ON_ABORT);
style=3D'font-size:10.0pt;
font-family:Arial'>
665 if =
(!res)
style=3D'font-size:10.0pt;
font-family:Arial'>
666 =
{
style=3D'font-size:10.0pt;
font-family:Arial'>
667 &nbs=
p; /*
error msg will be in the connection */
style=3D'font-size:10.0pt;
font-family:Arial'>
668 &nbs=
p;
CC_on_abort(conn, NO_TRANS);
style=3D'font-size:10.0pt;
font-family:Arial'>
669 &nbs=
p;
CC_log_error(func, "", conn);
style=3D'font-size:10.0pt;
font-family:Arial'>
670 &nbs=
p;
return SQL_ERROR;
style=3D'font-size:10.0pt;
font-family:Arial'>
671 =
}
style=3D'font-size:10.0pt;
font-family:Arial'> 672
style=3D'font-size:10.0pt;
font-family:Arial'>
673 ok =3D
QR_command_maybe_successful(res);
style=3D'font-size:10.0pt;
font-family:Arial'>
674 =
QR_Destructor(res);
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'>So the solution would appear to be adding a =
QR_command_maybe_successful(res)
check in CC_lookup_cs_new. However, why not just handle this inside send =
query
and return NULL if the result is bad? Especially if the flag =
CLEAR_RESULT_ON_ABORT
leads you to believe this is the desired =
behaviour.
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'>Questions/Comments
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt;
font-family:Arial'>
style=3D'font-size:10.0pt'>David
Chappelle
Software Engineer
519.880.2400 ext.3005
Sandvine Incorporated
=
size=3D2>
style=3D'font-size:
12.0pt'>
------_=_NextPart_001_01C6B183.DC7A43D9--