@@ -2347,9 +2347,14 @@ int DbStmt::bindColData(Napi::Env env)
23472347 sqlReturnCode = SQLBindCol (stmth, col + 1 , SQL_C_CHAR , (SQLPOINTER )bindingRowInC[col], maxColLen, &dbColumn[col].rlength );
23482348 }
23492349 break ;
2350- default : // SQL_CHAR / SQL_VARCHAR
2350+ default : // SQL_CHAR / SQL_VARCHAR / SQL_BOOLEAN and other string-representable types
23512351 {
2352+ // colPrecise * 4 + 1 accounts for multi-byte character expansion + null terminator.
2353+ // Minimum of 6 ensures types like BOOLEAN (colPrecise=1, but string representation
2354+ // "FALSE" needs 6 bytes) have a large enough buffer.
23522355 maxColLen = dbColumn[col].colPrecise * 4 + 1 ;
2356+ if (maxColLen < 6 )
2357+ maxColLen = 6 ;
23532358 bindingRowInC[col] = (SQLCHAR *)calloc (maxColLen, sizeof (SQLCHAR ));
23542359 sqlReturnCode = SQLBindCol (stmth, col + 1 , SQL_C_CHAR , (SQLPOINTER )bindingRowInC[col], maxColLen, &dbColumn[col].rlength );
23552360 }
@@ -2430,8 +2435,12 @@ int DbStmt::fetchData()
24302435 }
24312436 else
24322437 {
2438+ // rlength is the actual data length (e.g. 5 for CHAR(5) or "FALSE").
2439+ // Allocate colLen + 1 to ensure null termination, since memcpy copies
2440+ // only the data bytes without a null terminator. The extra byte is
2441+ // zero-filled by calloc.
24332442 colLen = dbColumn[col].rlength ;
2434- rowOfResultSetInC[col].data = (SQLCHAR *)calloc (colLen, sizeof (SQLCHAR ));
2443+ rowOfResultSetInC[col].data = (SQLCHAR *)calloc (colLen + 1 , sizeof (SQLCHAR ));
24352444 memcpy (rowOfResultSetInC[col].data , bindingRowInC[col], colLen * sizeof (SQLCHAR ));
24362445 rowOfResultSetInC[col].rlength = colLen;
24372446 }
@@ -2489,7 +2498,12 @@ int DbStmt::buildJsObject(Napi::Env env, Napi::Array *array)
24892498 break ;
24902499 }
24912500 default :
2492- value = Napi::String::New (env, resultSetInC[row][col].data );
2501+ // Use the known data length to bound string creation rather than relying
2502+ // on null termination, as a safeguard against buffer overreads.
2503+ if (resultSetInC[row][col].rlength == SQL_NTS )
2504+ value = Napi::String::New (env, (const char *)resultSetInC[row][col].data );
2505+ else
2506+ value = Napi::String::New (env, (const char *)resultSetInC[row][col].data , resultSetInC[row][col].rlength );
24932507 break ;
24942508 }
24952509 }
0 commit comments