Edit report at http://bugs.php.net/bug.php?id=39756&edit=1

 ID:               39756
 Updated by:       [email protected]
 Reported by:      tobias dot barth at web-arts dot com
 Summary:          [PATCH] Crashes in fetching resultsets with LONG ASCII
                   columns from MaxDB
-Status:           Open
+Status:           Closed
 Type:             Bug
 Package:          ODBC related
 Operating System: SuSE Linux 10.1
-PHP Version:      6CVS-2007-04-28 (snap)
+PHP Version:      5.2
-Assigned To:      
+Assigned To:      felipe



Previous Comments:
------------------------------------------------------------------------
[2009-08-18 12:02:21] tobias dot barth at web-arts dot com

works for me with php 5.2.10.

------------------------------------------------------------------------
[2009-05-05 01:00:01] php-bugs at lists dot php dot net

No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".

------------------------------------------------------------------------
[2009-04-27 16:00:09] [email protected]

Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/



------------------------------------------------------------------------
[2007-04-28 19:56:47] tobias dot barth at web-arts dot com

I know a bit more about it now. Trying to do select queries on MaxDB
tables with the unixODBC-Tool "isql" only returned the first column of
the first row full with data, the rest was empty. I contacted the author
of unixODBC, Nick Gorham, and was told to get the latest snapshot of
unixODBC. With that snapshot, isql works. The reason: In 64 Bit systems,
length parameters and pointers are 64-Bit. There is a new symbol
"SQLLEN" in the header files of unixODBC now. But the problem persists
in php. I got the latest php6 snapshot and got many compilation warnings
in php_odbc.c because of incompatible pointer types. php_odbc.c uses
SDWORD as length attributes and int variables as numeric representation
of pointers - e.g. for creating connection names. I tried to fix that
and put SQLLEN in each data structure where 4 byte datatypes where used
and produces a compiler warning - now the warnings are gone. But I still
get glibc errors, when doing select queries in MaxDB:



*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x00005555560c3e90 ***

*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x00005555560609c0 ***

*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x000055555605e660 ***

*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x0000555556052700 ***

*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x0000555556064400 ***

*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid
pointer: 0x00005555560cad60 ***



Perhaps I did something wrong with those SQLLEN things or just did not
enough - would you please take a look at it?

The diff between the snapshot and my modified version is:



lxdevel:/usr/src/php6.0-200704281030/ext/odbc # diff -u php_odbc.c
/tmp/php6.0-200704281030/ext/odbc/php_odbc.c

--- php_odbc.c  2007-04-28 15:23:07.000000000 +0200

+++ /tmp/php6.0-200704281030/ext/odbc/php_odbc.c        2007-03-13
02:30:20.000000000 +0100

@@ -642,7 +642,7 @@

        RETCODE rc;

        int i;

        SWORD       colnamelen; /* Not used */

-       SQLLEN      displaysize;

+       SDWORD      displaysize;



        result->values = (odbc_result_value *)
safe_emalloc(sizeof(odbc_result_value), result->numcols, 0);



@@ -736,7 +736,7 @@

         */

        SDWORD len;

 #else

-       SQLLEN len;

+       SQLINTEGER len;

 #endif

        zval **pv_res, **pv_num;



@@ -932,15 +932,15 @@

 {

        zval **pv_res, **pv_param_arr, **tmp;

        typedef struct params_t {

-               SQLLEN vallen;

-               SQLLEN fp;

+               SDWORD vallen;

+               int fp;

        } params_t;

        params_t *params = NULL;

        char *filename;

        unsigned char otype;

        SWORD sqltype, ctype, scale;

        SWORD nullable;

-       SQLLEN precision;

+       UDWORD precision;

        odbc_result   *result;

        int numArgs, i, ne;

        RETCODE rc;

@@ -1154,7 +1154,7 @@

                                                result->stmt, state,
&error, errormsg,

                                                sizeof(errormsg)-1,
&errormsgsize);

                        if (!strncmp(state,"S1015",5)) {

-                               snprintf(cursorname, max_len+1,
"php_curs_%d", (SQLLEN)result->stmt);

+                               snprintf(cursorname, max_len+1,
"php_curs_%d", (int)result->stmt);

                                if
(SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) {

                                        odbc_sql_error(result->conn_ptr,
result->stmt, "SQLSetCursorName");

                                        RETVAL_FALSE;

@@ -1726,7 +1726,7 @@

        odbc_result *result;

        int i = 0;

        RETCODE rc;

-       SQLLEN  fieldsize;

+       SDWORD  fieldsize;

        zval **pv_res, **pv_field;

 #ifdef HAVE_SQL_EXTENDED_FETCH

        UDWORD crow;

@@ -2334,13 +2334,12 @@



                if (zend_hash_find(&EG(regular_list), hashed_details,
hashed_len + 1,

                                        (void **) &index_ptr) ==
SUCCESS) {

-                       int type;

-                       SQLLEN conn_id;

+                       int type, conn_id;

                        void *ptr;

                        if (Z_TYPE_P(index_ptr) != le_index_ptr) {

                                RETURN_FALSE;

                        }

-                       conn_id = (SQLLEN)index_ptr->ptr;

+                       conn_id = (int)index_ptr->ptr;

                        ptr = zend_list_find(conn_id, &type);   /* check
if the connection is still there */

                        if (ptr && (type == le_conn || type ==
le_pconn)) {

                                zend_list_addref(conn_id);

@@ -2426,7 +2425,7 @@

 PHP_FUNCTION(odbc_num_rows)

 {

        odbc_result *result;

-       SQLROWCOUNT rows;

+       SDWORD rows;

        zval **pv_res;



        if (zend_get_parameters_ex(1, &pv_res) == FAILURE) {

lxdevel:/usr/src/php6.0-200704281030/ext/odbc # diff -u
/tmp/php6.0-200704281030/ext/odbc/php_odbc.c php_oodbc.c

diff: php_oodbc.c: Datei oder Verzeichnis nicht gefunden

lxdevel:/usr/src/php6.0-200704281030/ext/odbc # diff -u
/tmp/php6.0-200704281030/ext/odbc/php_odbc.c php_odbc.c

--- /tmp/php6.0-200704281030/ext/odbc/php_odbc.c        2007-03-13
02:30:20.000000000 +0100

+++ php_odbc.c  2007-04-28 15:23:07.000000000 +0200

@@ -642,7 +642,7 @@

        RETCODE rc;

        int i;

        SWORD       colnamelen; /* Not used */

-       SDWORD      displaysize;

+       SQLLEN      displaysize;



        result->values = (odbc_result_value *)
safe_emalloc(sizeof(odbc_result_value), result->numcols, 0);



@@ -736,7 +736,7 @@

         */

        SDWORD len;

 #else

-       SQLINTEGER len;

+       SQLLEN len;

 #endif

        zval **pv_res, **pv_num;



@@ -932,15 +932,15 @@

 {

        zval **pv_res, **pv_param_arr, **tmp;

        typedef struct params_t {

-               SDWORD vallen;

-               int fp;

+               SQLLEN vallen;

+               SQLLEN fp;

        } params_t;

        params_t *params = NULL;

        char *filename;

        unsigned char otype;

        SWORD sqltype, ctype, scale;

        SWORD nullable;

-       UDWORD precision;

+       SQLLEN precision;

        odbc_result   *result;

        int numArgs, i, ne;

        RETCODE rc;

@@ -1154,7 +1154,7 @@

                                                result->stmt, state,
&error, errormsg,

                                                sizeof(errormsg)-1,
&errormsgsize);

                        if (!strncmp(state,"S1015",5)) {

-                               snprintf(cursorname, max_len+1,
"php_curs_%d", (int)result->stmt);

+                               snprintf(cursorname, max_len+1,
"php_curs_%d", (SQLLEN)result->stmt);

                                if
(SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) {

                                        odbc_sql_error(result->conn_ptr,
result->stmt, "SQLSetCursorName");

                                        RETVAL_FALSE;

@@ -1726,7 +1726,7 @@

        odbc_result *result;

        int i = 0;

        RETCODE rc;

-       SDWORD  fieldsize;

+       SQLLEN  fieldsize;

        zval **pv_res, **pv_field;

 #ifdef HAVE_SQL_EXTENDED_FETCH

        UDWORD crow;

@@ -2334,12 +2334,13 @@



                if (zend_hash_find(&EG(regular_list), hashed_details,
hashed_len + 1,

                                        (void **) &index_ptr) ==
SUCCESS) {

-                       int type, conn_id;

+                       int type;

+                       SQLLEN conn_id;

                        void *ptr;

                        if (Z_TYPE_P(index_ptr) != le_index_ptr) {

                                RETURN_FALSE;

                        }

-                       conn_id = (int)index_ptr->ptr;

+                       conn_id = (SQLLEN)index_ptr->ptr;

                        ptr = zend_list_find(conn_id, &type);   /* check
if the connection is still there */

                        if (ptr && (type == le_conn || type ==
le_pconn)) {

                                zend_list_addref(conn_id);

@@ -2425,7 +2426,7 @@

 PHP_FUNCTION(odbc_num_rows)

 {

        odbc_result *result;

-       SDWORD rows;

+       SQLROWCOUNT rows;

        zval **pv_res;



        if (zend_get_parameters_ex(1, &pv_res) == FAILURE) {

lxdevel:/usr/src/php6.0-200704281030/ext/odbc #

------------------------------------------------------------------------
[2006-12-09 02:44:47] tobias dot barth at web-arts dot com

I reviewed the compiler output when compiling php_odbc.c today, and I
saw the following warnings:



/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c: In function
'zif_odbc_execute':

/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:1042: warning:
cast to pointer from integer of different size

/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c: In function
'zif_odbc_cursor':

/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:1157: warning:
cast from pointer to integer of different size

/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c: In function
'odbc_do_connect':

/usr/src/php4-STABLE-200612061330/ext/odbc/php_odbc.c:2302: warning:
cast from pointer to integer of different size



In line 1042, you use the field "fp" as if it was a pointer:

rc = SQLBindParameter(result->stmt, (UWORD)i, SQL_PARAM_INPUT,

                                                                          
ctype, sqltype, precision, scale,

                                                                          (void 
*)params[i-1].fp, 0,

                                                                          
&params[i-1].vallen);



on 32 Bit-Machines that may work, on 64 Bit machines, where the field
"fp" is declared as "int" (which is 32 Bit on SuSE Linux 10.1), and a
void* is a 64 Bit-Pointer, that will not work. 





In line 2302, you do it the other way:

                        conn_id = (int)index_ptr->ptr;



Here, a pointer ("ptr") is treated as if it was an int value - cutting
off the high 32 bits.



In line 1157, there is:

                                sprintf(cursorname,"php_curs_%d", 
(int)result->stmt);



maybe "stmt" is chopped off here, too - maybe that is harmful, too.



I think those "treat int as if a pointer would fit into it" things could
be the reason why I get those crashes after having used "odbc_exec" or
other php_odbc functions - do you agree?



Greetings,



Tobias Barth

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=39756


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=39756&edit=1

Reply via email to