Bug #39756 [Opn->Csd]: [PATCH] Crashes in fetching resultsets with LONG ASCII columns from MaxDB

From: Date: Sun, 20 Jun 2010 22:27:22 +0000
Subject: Bug #39756 [Opn->Csd]: [PATCH] Crashes in fetching resultsets with LONG ASCII columns from MaxDB
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-151689@lists.php.net to get a copy of this message
Edit report at http://bugs.php.net/bug.php?id=39756&edit=1

 ID:               39756
 Updated by:       felipe@php.net
 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] jani@php.net

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


Thread (21 messages)

« previous php.bugs (#151689) next »