Reputation: 3521
The case statement for sql_varying is causing nodejs to crash with a segmentation fault.
void FBResult::clean_sqlda(XSQLDA *sqlda)
{
int i;
XSQLVAR* var;
for(i = 0, var= sqlda->sqlvar; i < sqlda->sqld;i++,var++)
{
switch(var->sqltype & ~1)
{
case SQL_ARRAY:
case SQL_BLOB: delete (ISC_QUAD*) var->sqldata; break;
case SQL_TIMESTAMP: delete (ISC_TIMESTAMP*) var->sqldata; break;
case SQL_TYPE_TIME: delete (ISC_TIME*) var->sqldata; break;
case SQL_TYPE_DATE: delete (ISC_DATE*) var->sqldata; break;
case SQL_TEXT:
case SQL_VARYING: delete [] var->sqldata; break;
case SQL_SHORT: delete (int16_t *) var->sqldata; break;
case SQL_LONG: delete (int32_t *) var->sqldata; break;
case SQL_INT64: delete (int64_t *) var->sqldata; break;
case SQL_FLOAT: delete (float *) var->sqldata; break;
case SQL_DOUBLE: delete (double *) var->sqldata; break;
default: return;
}
if(var->sqlind != 0) delete var->sqlind;
}
}
Here is how sqldata is allocated for sql_varying:
case SQL_VARYING: var->sqldata = new char[var->sqllen + 3];
memset(var->sqldata, 0, 2);
memset(var->sqldata + 2, ' ', var->sqllen);
var->sqldata[var->sqllen + 2] = '\0';
break;
why does the line in clean_sqlda cause nodejs to crash? If I comment out the line and rebuild the extension, it doesn't crash. The line is suppose to clear the memory allocated for var->sqldata. How do I fix it?
EDIT: sql_text is allocated this way:
case SQL_TEXT: var->sqldata = new char[var->sqllen + 1];
memset(var->sqldata, ' ', var->sqllen);
//memset(var->sqldata, 0, var->sqllen);
var->sqldata[var->sqllen] = '\0';
break;
However I don't think I'm using sql_text anywhere (not sure though).
Edit #2: After further debugging, I determined that the error is caused by the line:
if(var->sqlind != 0) delete var->sqlind;
If I replace it with:
if(var->sqltype & 1) delete var->sqlind;
Somewhere in the code, sqlind is allocated like this:
if(var->sqltype & 1){
var->sqlind = new short(-1);
}
Replace the old line with the new line fixes the issue and nodejs no longer crashes. Do you think that the old line caused it to crash because sqlind is allocated to new short(-1) which is a marker for null i guess?
Upvotes: 1
Views: 252
Reputation: 3521
The bug is now fixed. var->sqldata was not initialized with 0 which caused the delete var->sqldata to always run even on a null reference causing node to crash.
Upvotes: 1
Reputation: 29896
sqltype
least significant bit is used to indicate if the value can be null.
If it is set, sqlind
is allocated and its value indicates whether or not it is null (with the values -1 for null and 0 for not null).
So the condition to test that bit when you allocate it or deallocate it, should be (var->sqltype & 1)
in both cases.
Upvotes: 0
Reputation: 43307
Your decision to allocate was (var->sqltype & 1), while your decision to free was (var->sqlind != 0). I would assume the mismatch would crash until proven otherwise if I were you.
Possible further cause: var->sqlind is not initialized in code paths that don't need to allocate.
Upvotes: 0