[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Segfault in Ruby/ODBC

Nathaniel Talbott

11/10/2003 6:55:00 PM

Nathaniel Talbott [mailto:nathaniel@NOSPAMtalbott.ws] wrote:

> I'll dig in to do_fetch and
> see if I can find the memory problem.

OK, I'm pretty sure I've fixed the problem... for anyone who's interested,
I've included a patch with all of my changes to odbc.c.

Turns out the problem lay in one of the underlying library functions
(SQLColAttributes) claiming to return a zero-length string when the
requested value (SQL_COLUMN_TABLE_NAME) didn't exist, but instead not
returning anything, leaving the buffer the value was supposed to be put in
to in a hosed state. I've fixed it for the time being by making sure the
buffer always starts with a NULL value, so that it will always be
interpreted as an empty string if the function doesn't do anything to it. I
don't know if this will work if the extension is built with unicode support,
but since I don't have to deal with that environment, I don't really care at
this point. If there's a better solution, I'm all ears.

Thanks for all your help,


Nathaniel

<:((><


--- ../odbc.c.old Thu Aug 21 14:44:37 2003
+++ odbc.c Mon Nov 10 12:51:05 2003
@@ -1021,7 +1021,7 @@
*/

static VALUE
-env_new(self)
+env_new(VALUE self)
{
ENV *e;
SQLHENV henv = SQL_NULL_HENV;
@@ -1904,6 +1904,7 @@
char name[SQL_MAX_MESSAGE_LENGTH];
#endif

+ name[0] = 0;
if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
SQLColAttributes(hstmt, ic, SQL_COLUMN_LABEL, name,
(SQLSMALLINT) sizeof (name),
@@ -1940,6 +1941,7 @@
rb_iv_set(obj, "@name", rb_tainted_str_new2(upcase_if(name, upc)));
#endif
v = Qnil;
+ name[0] = 0;
if (succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
SQLColAttributes(hstmt, ic, SQL_COLUMN_TABLE_NAME, name,
(SQLSMALLINT) sizeof (name),
@@ -3713,6 +3715,7 @@
#endif

for (i = 0; i < q->ncols; i++) {
+ name[0] = 0;
if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
SQLColAttributes(q->hstmt,
(SQLUSMALLINT) (i + 1),
@@ -3730,6 +3733,7 @@
#else
need += 2 * (strlen(name) + 1);
#endif
+ name[0] = 0;
if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
SQLColAttributes(q->hstmt,
(SQLUSMALLINT) (i + 1),
@@ -3757,6 +3761,7 @@
for (i = 0; i < q->ncols; i++) {
char *p0;

+ name[0] = 0;
tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
SQLColAttributes(q->hstmt, (SQLUSMALLINT) (i + 1),
SQL_COLUMN_TABLE_NAME, name,
@@ -3771,6 +3776,7 @@
strcat(p, ".");
p += strlen(p);
p0 = p;
+ name[0] = 0;
tracesql(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
SQLColAttributes(q->hstmt, (SQLUSMALLINT) (i + 1),
SQL_COLUMN_LABEL, name,
@@ -5426,8 +5432,11 @@
rb_define_method(Cproc, "initialize", stmt_proc_init, -1);
rb_define_method(Cproc, "call", stmt_proc_call, -1);
rb_define_method(Cproc, "[]", stmt_proc_call, -1);
+
+#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
rb_enable_super(Cproc, "call");
rb_enable_super(Cproc, "[]");
+#endif

/* constants */
for (i = 0; o_const[i].name != NULL; i++) {