ID:               30280
 Updated by:       [EMAIL PROTECTED]
 Reported By:      freddyz77 at tin dot it
-Status:           Assigned
+Status:           Closed
 Bug Type:         MSSQL related
 Operating System: Any
 PHP Version:      4.3.9
 Assigned To:      fmk
 New Comment:

This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Most of this patch makes good sence and have been added to CVS.
Thanks for the input.


Previous Comments:
------------------------------------------------------------------------

[2004-09-30 12:24:44] andreyra at chtivo dot ru

How to get the compiled version of this dll for Windows?

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

[2004-09-29 20:39:37] freddyz77 at tin dot it

Description:
------------
Well, I wrote this patch just looking at the code, I hope someone find
some useful info. Mainly it contains some memory leak fix connecting
and some others minor issues and notes.

--- php_mssql.c.orig    2004-09-29 19:52:42.000000000 +0200
+++ php_mssql.c 2004-09-29 20:29:10.000000000 +0200
@@ -197,20 +197,23 @@
                result->data = NULL;
                result->blocks_initialized = 0;
        }
        
        if (free_fields && result->fields) {
                for (i=0; i<result->num_fields; i++) {
                        STR_FREE(result->fields[i].name);
                        STR_FREE(result->fields[i].column_source);
                }
                efree(result->fields);
+               result->fields = NULL;
+               result->num_fields = 0;
+               result->cur_field = 0;
        }
 }
 
 static void _free_mssql_statement(mssql_statement *statement)
 {
        if (statement->binds) {
                zend_hash_destroy(statement->binds);
                efree(statement->binds);
        }
        
@@ -263,28 +266,25 @@
        mssql_bind *bind= (mssql_bind *) data;
 
        zval_ptr_dtor(&(bind->zval));
 }
 
 static void php_mssql_init_globals(zend_mssql_globals *mssql_globals)
 {
        long compatability_mode;
 
        mssql_globals->num_persistent = 0;
+       mssql_globals->get_column_content =
php_mssql_get_column_content_with_type;
        if (cfg_get_long("mssql.compatability_mode", &compatability_mode) ==
SUCCESS) {
                if (compatability_mode) {
                        mssql_globals->get_column_content =
php_mssql_get_column_content_without_type;      
-               } else {
-                       mssql_globals->get_column_content =
php_mssql_get_column_content_with_type;
                }
-       } else {
-               mssql_globals->get_column_content =
php_mssql_get_column_content_with_type;
        }
 }
 
 PHP_MINIT_FUNCTION(mssql)
 {
        ZEND_INIT_MODULE_GLOBALS(mssql, php_mssql_init_globals, NULL);
 
        REGISTER_INI_ENTRIES();
 
        le_statement = register_list_destructors(_free_mssql_statement,
NULL);
@@ -508,61 +508,68 @@
                        if (DBSETOPT(mssql.link, DBBUFFER, "2")==FAIL) {
                                efree(hashed_details);
                                dbfreelogin(mssql.login);
                                dbclose(mssql.link);
                                RETURN_FALSE;
                        }
 
                        if (MS_SQL_G(textlimit) != -1) {
                                sprintf(buffer, "%li", MS_SQL_G(textlimit));
                                if (DBSETOPT(mssql.link, DBTEXTLIMIT, 
buffer)==FAIL) {
+                                       dbclose(mssql.link);
                                        efree(hashed_details);
                                        dbfreelogin(mssql.login);
                                        RETURN_FALSE;
                                }
                        }
                        if (MS_SQL_G(textsize) != -1) {
                                sprintf(buffer, "SET TEXTSIZE %li", 
MS_SQL_G(textsize));
                                dbcmd(mssql.link, buffer);
                                dbsqlexec(mssql.link);
                                dbresults(mssql.link);
                        }
 
                        /* hash it up */
                        mssql_ptr = (mssql_link *) malloc(sizeof(mssql_link));
                        memcpy(mssql_ptr, &mssql, sizeof(mssql_link));
                        Z_TYPE(new_le) = le_plink;
                        new_le.ptr = mssql_ptr;
                        if (zend_hash_update(&EG(persistent_list), 
hashed_details,
hashed_details_length + 1, &new_le, sizeof(list_entry), NULL)==FAILURE)
{
                                free(mssql_ptr);
+                               dbclose(mssql.link);
                                efree(hashed_details);
                                dbfreelogin(mssql.login);
                                RETURN_FALSE;
                        }
                        MS_SQL_G(num_persistent)++;
                        MS_SQL_G(num_links)++;
                } else {  /* we do */
+                       dbfreelogin(mssql.login);
+
                        if (Z_TYPE_P(le) != le_plink) {
+                               efree(hashed_details);
 #if BROKEN_MSSQL_PCONNECTS
                                log_error("PHP/MS SQL:  Hashed persistent link 
is not a MS SQL
link!",php_rqst->server);
 #endif
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Hashed persistent
link is not a MS SQL link!");
                                RETURN_FALSE;
                        }
                        
                        mssql_ptr = (mssql_link *) le->ptr;
                        /* test that the link hasn't died */
                        if (DBDEAD(mssql_ptr->link) == TRUE) {
+                               /* free previous connection */
+                               dbclose(mssql_ptr->link);
 #if BROKEN_MSSQL_PCONNECTS
                                log_error("PHP/MS SQL:  Persistent link died, 
trying to
reconnect...",php_rqst->server);
 #endif
-                               if 
((mssql_ptr->link=dbopen(mssql_ptr->login,host))==FAIL) {
+                               if 
((mssql_ptr->link=dbopen(mssql_ptr->login,host))==NULL) {
 #if BROKEN_MSSQL_PCONNECTS
                                        log_error("PHP/MS SQL:  Unable to 
reconnect!",php_rqst->server);
 #endif
                                        php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "Link to server lost,
unable to reconnect");
                                        zend_hash_del(&EG(persistent_list), 
hashed_details,
hashed_details_length+1);
                                        efree(hashed_details);
                                        RETURN_FALSE;
                                }
 #if BROKEN_MSSQL_PCONNECTS
                                log_error("PHP/MS SQL:  Reconnect 
successful!",php_rqst->server);
@@ -584,57 +591,63 @@
                /* first we check the hash for the hashed_details key.  if it
exists,
                 * it should point us to the right offset where the actual mssql
link sits.
                 * if it doesn't, open a new mssql link, add it to the resource
list,
                 * and add a pointer to it with hashed_details as the key.
                 */
                if (zend_hash_find(&EG(regular_list), hashed_details,
hashed_details_length + 1,(void **) &index_ptr)==SUCCESS) {
                        int type,link;
                        void *ptr;
 
                        if (Z_TYPE_P(index_ptr) != le_index_ptr) {
+                               efree(hashed_details);
+                               dbfreelogin(mssql.login);
                                RETURN_FALSE;
                        }
                        link = (int) index_ptr->ptr;
                        ptr = zend_list_find(link,&type);   /* check if the 
link is still
there */
                        if (ptr && (type==le_link || type==le_plink)) {
                                zend_list_addref(link);
                                Z_LVAL_P(return_value) = link;
                                php_mssql_set_default_link(link TSRMLS_CC);
                                Z_TYPE_P(return_value) = IS_RESOURCE;
                                efree(hashed_details);
+                               dbfreelogin(mssql.login);
                                return;
                        } else {
                                zend_hash_del(&EG(regular_list), hashed_details,
hashed_details_length + 1);
                        }
                }
                if (MS_SQL_G(max_links) != -1 && MS_SQL_G(num_links) >=
MS_SQL_G(max_links)) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many 
open links
(%ld)", MS_SQL_G(num_links));
                        efree(hashed_details);
+                       dbfreelogin(mssql.login);
                        RETURN_FALSE;
                }
                
                if ((mssql.link=dbopen(mssql.login, host))==NULL) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to 
connect to
server:  %s", host);
                        efree(hashed_details);
+                       dbfreelogin(mssql.login);
                        RETURN_FALSE;
                }
 
                if (DBSETOPT(mssql.link, DBBUFFER,"2")==FAIL) {
                        efree(hashed_details);
                        dbfreelogin(mssql.login);
                        dbclose(mssql.link);
                        RETURN_FALSE;
                }
 
                if (MS_SQL_G(textlimit) != -1) {
                        sprintf(buffer, "%li", MS_SQL_G(textlimit));
                        if (DBSETOPT(mssql.link, DBTEXTLIMIT, buffer)==FAIL) {
+                               dbclose(mssql.link);
                                efree(hashed_details);
                                dbfreelogin(mssql.login);
                                RETURN_FALSE;
                        }
                }
                if (MS_SQL_G(textsize) != -1) {
                        sprintf(buffer, "SET TEXTSIZE %li", MS_SQL_G(textsize));
                        dbcmd(mssql.link, buffer);
                        dbsqlexec(mssql.link);
                        dbresults(mssql.link);
@@ -980,40 +993,42 @@
                        type = dbrettype(mssql_ptr->link, i);
                                                
                        if (statement->binds != NULL) { /*      Maybe a 
non-parameter sp        */
                                if (zend_hash_find(statement->binds, parameter, 
strlen(parameter),
(void**)&bind)==SUCCESS) {
                                        switch (type) {
                                                case SQLBIT:
                                                case SQLINT1:
                                                case SQLINT2:
                                                case SQLINT4:
                                                        
convert_to_long_ex(&bind->zval);
+                                                       /* FIXME this works 
only on little endian machine !!! */
                                                        Z_LVAL_P(bind->zval) = 
*((int
*)(dbretdata(mssql_ptr->link,i)));
                                                        break;
                        
                                                case SQLFLT4:
                                                case SQLFLT8:
                                                case SQLFLTN:
                                                case SQLMONEY4:
                                                case SQLMONEY:
                                                case SQLMONEYN:
                                                        
convert_to_double_ex(&bind->zval);
                                                        Z_DVAL_P(bind->zval) = 
*((double
*)(dbretdata(mssql_ptr->link,i)));
                                                        break;
 
                                                case SQLCHAR:
                                                case SQLVARCHAR:
                                                case SQLTEXT:
                                                        
convert_to_string_ex(&bind->zval);
                                                        Z_STRLEN_P(bind->zval) 
= dbretlen(mssql_ptr->link,i);
                                                        Z_STRVAL_P(bind->zval) =
estrndup(dbretdata(mssql_ptr->link,i),Z_STRLEN_P(bind->zval));
                                                        break;
+                                               /* TODO binary */
                                        }
                                }
                                else {
                                        php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "An output parameter
variable was not provided");
                                }
                        }
                }
        }
        if (statement->binds != NULL) { /*      Maybe a non-parameter sp        
*/
                if (zend_hash_find(statement->binds, "RETVAL", 6,
(void**)&bind)==SUCCESS) {
@@ -1187,40 +1202,44 @@
        }
        if (dbsqlexec(mssql_ptr->link)==FAIL || (retvalue =
dbresults(mssql_ptr->link))==FAIL) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed");
                RETURN_FALSE;
        }
        
        /* Skip results not returning any columns */
        while ((num_fields = dbnumcols(mssql_ptr->link)) <= 0 && retvalue ==
SUCCEED) {
                retvalue = dbresults(mssql_ptr->link);
        }
+       if (retvalue != SUCCEED) {
+               RETURN_FALSE;
+       }
        if ((num_fields = dbnumcols(mssql_ptr->link)) <= 0) {
                RETURN_TRUE;
        }
 
        retvalue=dbnextrow(mssql_ptr->link);    
        if (retvalue==FAIL) {
                RETURN_FALSE;
        }
 
        result = (mssql_result *) emalloc(sizeof(mssql_result));
        result->statement = NULL;
        result->num_fields = num_fields;
        result->blocks_initialized = 1;
        
        result->batchsize = batchsize;
        result->data = NULL;
        result->blocks_initialized = 0;
        result->mssql_ptr = mssql_ptr;
        result->cur_field=result->cur_row=result->num_rows=0;
 
+       /* TODO here this condition it's always true */
        if (num_fields > 0) {
                result->fields = (mssql_field *)
emalloc(sizeof(mssql_field)*result->num_fields);
                result->num_rows = _mssql_fetch_batch(mssql_ptr, result, 
retvalue
TSRMLS_CC);
        }
        else
                result->fields = NULL;
        
        ZEND_REGISTER_RESOURCE(return_value, result, le_result);
 }
 /* }}} */
@@ -1267,20 +1286,21 @@
 
        zend_list_delete(Z_RESVAL_PP(mssql_result_index));
        RETURN_TRUE;
 }
 /* }}} */
 
 /* {{{ proto string mssql_get_last_message(void)
    Gets the last message from the MS-SQL server */
 PHP_FUNCTION(mssql_get_last_message)
 {
+       /* TODO add link parameter */
        if (MS_SQL_G(server_message)) {
                RETURN_STRING(MS_SQL_G(server_message),1);
        }
        else {
                RETURN_STRING(empty_string,1);
        }
 }
 
 /* }}} */
 
@@ -2236,27 +2256,29 @@
                        convert_to_string_ex(binary);
                        convert_to_long_ex(short_format);
                        sf = Z_LVAL_PP(short_format);
                        break;
 
                default:
                        WRONG_PARAM_COUNT;
                        break;
        }
 
+       /* FIXME this code can cause a buffer reading overflow if binary it's
less than 16 bytes */
        dbconvert(NULL, SQLBINARY, (BYTE*)Z_STRVAL_PP(binary), 16, SQLCHAR,
buffer, -1);
 
        if (sf) {
                php_strtoupper(buffer, 32);
                RETURN_STRING(buffer, 1);
        }
        else {
+               /* FIXME this works only on little endian machine */
                int i;
                for (i=0; i<4; i++) {
                        buffer2[2*i] = buffer[6-2*i];
                        buffer2[2*i+1] = buffer[7-2*i];
                }
                buffer2[8] = '-';
                for (i=0; i<2; i++) {
                        buffer2[9+2*i] = buffer[10-2*i];
                        buffer2[10+2*i] = buffer[11-2*i];
                }




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


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

Reply via email to