[erlang-patches] [PATCH] ODBC server segfaults on 64-bit platform

willi <>
Sat May 3 20:53:48 CEST 2008


Hi,

Please, consider this patch for inclusion. I've replaced SQLINTEGER with SQLLEN where it is mandated by ODBC specification.
Without this modifications, ODBC driver segfaults on functions with SQLLEN type parameters on 64bit platforms.
Tested on linux (both AMD64 and 32-bit).

---
 lib/odbc/c_src/odbcserver.c |   60 ++++++++++--------------------------------
 lib/odbc/c_src/odbcserver.h |    6 ++--
 2 files changed, 18 insertions(+), 48 deletions(-)

diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c
index a5d10ab..168f09f 100644
--- a/lib/odbc/c_src/odbcserver.c
+++ b/lib/odbc/c_src/odbcserver.c
@@ -154,8 +154,6 @@ static db_result_msg encode_value_list_scroll(SQLSMALLINT num_of_columns,
 					      db_state *state);
 static db_result_msg encode_row_count(SQLINTEGER num_of_rows,
 				      db_state *state);
-static int encode_column(byte *buffer, int index, db_column column,
-			 int column_nr, db_state *state);  
 static void encode_column_dyn(db_column column, int column_nr,
 			      db_state *state);
 static void encode_data_type(SQLINTEGER sql_type, SQLINTEGER size,
@@ -590,7 +588,7 @@ static db_result_msg db_query(byte *sql, db_state *state)
 static db_result_msg db_select_count(byte *sql, db_state *state)
 {
     SQLSMALLINT num_of_columns, intresult;
-    SQLINTEGER num_of_rows;
+    SQLLEN num_of_rows;
     SQLRETURN result;
     diagnos diagnos;
     db_result_msg msg;
@@ -760,6 +758,7 @@ static db_result_msg db_param_query(byte *buffer, db_state *state)
 		switch (param_status.param_status_array[i]) {
 		case SQL_PARAM_SUCCESS:
 		case SQL_PARAM_SUCCESS_WITH_INFO:
+		case SQL_PARAM_DIAG_UNAVAILABLE:
 		break;
 		default:
 		    diagnos =
@@ -812,7 +811,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state)
     SQLSMALLINT num_of_columns;
     SQLCHAR name[MAX_NAME];
     SQLSMALLINT name_len, sql_type, dec_digits, nullable;
-    SQLINTEGER size;
+    SQLLEN size;
     diagnos diagnos;
     int i;
     
@@ -851,7 +850,7 @@ static db_result_msg db_describe_table(byte *sql, db_state *state)
     for (i = 0; i < num_of_columns; ++i) {
 	
 	if(!sql_success(SQLDescribeCol(statement_handle(state),
-				       (SQLSMALLINT)(i+1),
+				       (SQLUSMALLINT)(i+1),
 				       name, sizeof(name), &name_len,
 				       &sql_type, &size, &dec_digits,
 				       &nullable)))
@@ -938,7 +937,8 @@ static db_result_msg encode_atom_message(char* atom)
 static db_result_msg encode_result(db_state *state)
 {
     SQLSMALLINT num_of_columns = 0;
-    SQLINTEGER RowCountPtr = 0, paramBatch = 0;
+    SQLLEN RowCountPtr = 0;
+    SQLINTEGER paramBatch = 0;
     db_result_msg msg;
     int elements, update, num_of_rows = 0;
     char *atom;
@@ -1039,7 +1039,7 @@ static db_result_msg encode_column_name_list(SQLSMALLINT num_of_columns,
     db_result_msg msg;
     SQLCHAR name[MAX_NAME];
     SQLSMALLINT name_len, sql_type, dec_digits, nullable;
-    SQLUINTEGER size; 
+    SQLLEN size; 
     SQLRETURN result;
 
     msg = encode_empty_message();
@@ -1224,48 +1224,11 @@ static db_result_msg encode_row_count(SQLINTEGER num_of_rows,
     return msg;
 }
  
-/* Description: Encodes a column value into the buffer <buffer>.*/
-static int encode_column(byte *buffer, int index, db_column column,
-			 int column_nr, db_state *state)
-{
-    if(column.type.len == 0 ||
-       column.type.strlen_or_indptr == SQL_NULL_DATA)
-	ei_encode_atom((char *)buffer, &index, "null");
-    else {
-	switch(column.type.c) {
-	case SQL_C_CHAR:
-	    ei_encode_string((char *)buffer, &index, column.buffer);
-	    break;
-	case SQL_C_DOUBLE:
-	    ei_encode_double((char *)buffer, &index, *(double *)column.buffer);
-	    break;
-	case SQL_C_SLONG:
-	    ei_encode_long((char *)buffer, &index, *(long *)column.buffer);
-	    break;
-	case SQL_C_BIT:
-	    ei_encode_atom((char *)buffer, &index,
-			   column.buffer[0]?"true":"false");
-	    break;
-	case SQL_C_BINARY:
-	    if (buffer == NULL) {  
-		column = retrive_binary_data(column, column_nr, state);
-	    }
-	    ei_encode_string((char *)buffer, &index, (void *)column.buffer);
-	    break;
-	default:
-	    ei_encode_atom((char *)buffer, &index, "error");
-	    break;
-	} 
-    } 
-    return index;
-}
-
 /* Description: Encodes the a column value into the "ei_x" - dynamic_buffer
    held by the state variable */
 static void encode_column_dyn(db_column column, int column_nr,
 			      db_state *state)
 {
-  
     if (column.type.len == 0 ||
 	column.type.strlen_or_indptr == SQL_NULL_DATA) {
 	ei_x_encode_atom(&dynamic_buffer(state), "null");
@@ -1930,7 +1893,7 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
 	 params->type.c = SQL_C_CHAR;
 	 params->type.col_size = (SQLUINTEGER)length;
 	 params->type.strlen_or_indptr_array =
-	     (SQLUINTEGER*)safe_malloc(num_param_values
+	     (SQLLEN*)safe_malloc(num_param_values
 				       * sizeof(SQL_NTS));
 	 params->values.string =
 	    (byte *)safe_malloc((num_param_values + 1) *
@@ -1977,8 +1940,15 @@ static void init_param_column(param_array *params, byte *buffer, int *index,
 static void init_param_statement(int cols, int num_param_values, 
 				 db_state *state, param_status *status)
 {
+    int i;
+
     status -> param_status_array =
 	(SQLUSMALLINT *)safe_malloc(num_param_values * sizeof(SQLUSMALLINT));
+
+    for(i=0; i<num_param_values; i++) {
+    	status -> param_status_array[i] = SQL_PARAM_PROCEED;
+    }
+
     status -> params_processed = 0;
     
     if(!sql_success(SQLAllocHandle(SQL_HANDLE_STMT,
diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h
index 2e6146a..fb74bf8 100644
--- a/lib/odbc/c_src/odbcserver.h
+++ b/lib/odbc/c_src/odbcserver.h
@@ -118,9 +118,9 @@ typedef struct {
     SQLSMALLINT sql;
     SQLUINTEGER col_size;
     SQLSMALLINT decimal_digits;
-    SQLUINTEGER len;
-    SQLINTEGER  strlen_or_indptr;
-    SQLINTEGER *strlen_or_indptr_array; 
+    SQLLEN len;
+    SQLLEN  strlen_or_indptr;
+    SQLLEN *strlen_or_indptr_array; 
 } col_type;
 
 typedef struct {
-- 
1.5.4.3




More information about the erlang-patches mailing list