php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #33153 segfaults when calling mssql_next_result
Submitted: 2005-05-26 18:16 UTC Modified: 2005-11-18 20:15 UTC
From: erudd at netfor dot com Assigned: fmk
Status: Closed Package: MSSQL related
PHP Version: 4.3.11 OS: FC3/FC4/MDK 10.2 x86 & x86_64
Private report: No CVE-ID:
 [2005-05-26 18:16 UTC] erudd at netfor dot com
Description:
------------
Using the mssql extension from PHP 4.3.11 on an x86_64 system. (core PHP is latest FC3 RPMS, php-mssql is custom compiled RPM using freetds 0.63).  Everything works fine except for calling the mssql_next_result function (via PEAR::DB 1.7.6) apache and the command line client will segfault.  This works fine on a MDK 10.1 32bit system w/ PHP 4.3.8. 

I havn't yet tried on a FC3 x86 system

Also the freetds commandline 'tsql" command runs the query without any issues and returns all the result fields.

Reproduce code:
---------------
require_once("DB.php");
$db =& DB::connect("mssql://user:pass@server/Database");
$sql = <<<EOSQL
DECLARE Search CURSOR LOCAL SCROLL READ_ONLY FOR
   SELECT * FROM MyTable
DECLARE @limit INT, @offset INT
SET @limit = 20
SET @offset = 5
OPEN Search
FETCH ABSOLUTE @offset FROM Search
WHILE @@FETCH_STATUS =0 AND @limit > 1
BEGIN
  FETCH NEXT FROM Search
  SET @limit = @limit -1
END
CLOSE Search
DEALLOCATE Search
EOSQL;
$res =& $db->query($sql);
$row =& $res->fetchRow(DB_FETCHMODE_ASSOC);
do {
  $return[] =& $row;
  $row =& $res->fetchRow(DB_FETCHMODE_ASSOC);
  if (is_null($row)) {
    if ($res->nextResult()) {
       $row =& $res->fetchRow(DB_FETCHMODE_ASSOC);
    }
  }
} while ($row);

Expected result:
----------------
Not to segfault and return 20 records from the table starting at record 5


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-05-26 18:23 UTC] eddie at omegaware dot com
Backtrace of the crash.

#0  dblastrow (dbproc=0x8c9530) at dblib.c:5909
#1  0x0000002a9a7f54bf in zif_mssql_next_result (ht=9213232, return_value=0x7bde58, 
    this_ptr=0x9034a0, return_value_used=9454256)
    at /home/erudd/RPMBUILD/BUILD/php-4.3.11/ext/mssql/php_mssql.c:1865
#2  0x000000000051c405 in execute (op_array=0x8004b8)
    at /usr/src/debug/php-4.3.11/Zend/zend_execute.c:1654
#3  0x000000000051891b in execute (op_array=0x7f3128)
    at /usr/src/debug/php-4.3.11/Zend/zend_execute.c:1698
#4  0x000000000051891b in execute (op_array=0x7af1b8)
    at /usr/src/debug/php-4.3.11/Zend/zend_execute.c:1698
#5  0x000000000050869d in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /usr/src/debug/php-4.3.11/Zend/zend.c:926
#6  0x00000000004dc14a in php_execute_script (primary_file=0x7fbffff550)
    at /usr/src/debug/php-4.3.11/main/main.c:1745
#7  0x000000000052384a in main (argc=3, argv=0x7fbffff688)
    at /usr/src/debug/php-4.3.11/sapi/cgi/cgi_main.c:1601
 [2005-05-26 18:49 UTC] eddie at omegaware dot com
segfault occurs because of a null res_info in the dbproc that is passed to the dblastrow function in freetds' dblib.

FreeTDS bug report on the issue

http://sourceforge.net/tracker/index.php?func=detail&aid=1209286&group_id=33106&atid=407806

Not sure if this is a freetds issue, or if php-mssql isn't doing something correct.
 [2005-05-26 19:37 UTC] sniper@php.net
Please try using this CVS snapshot:

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


 [2005-05-30 10:31 UTC] freddyz77 at tin dot it
dblastrow should not fail, this is certainly a FreeTDS bug. Fixed in CVS, expect a new 0.63.1 release.
However I don't understand why PHP calls dblastrow (related to dblib buffering).

freddy77
(FreeTDS developer)
 [2005-06-28 18:54 UTC] erudd at netfor dot com
I have tried the latest CVS code for the php-mssql extension and the same results occur.. I updated to the lastest on the 0.63 branch of freetds and apache/php no longer segfault, but PHP never advances to the next result set.
 [2005-08-03 18:56 UTC] erudd at netfor dot com
Any updates on this issue? 

(Mandrake Bug #)
http://qa.mandriva.com/show_bug.cgi?id=17272
 [2005-08-09 16:17 UTC] freddyz77 at tin dot it
Problem here is that in mssql_next_result PHP do not ignore recordset without columns

in mssql_query

/* Skip results not returning any columns */
while ((num_fields = dbnumcols(mssql_ptr->link)) <= 0 && retvalue == SUCCEED) { 
  retvalue = dbresults(mssql_ptr->link);
}

in mssql_execute

/* Skip results not returning any columns */
while ((num_fields = dbnumcols(mssql_ptr->link)) <= 0 && retval_results == SUCCEED) {
  retval_results = dbresults(mssql_ptr->link);
}

but there is no such loop in mssql_next_result

freddy77
 [2005-10-17 21:56 UTC] erudd at netfor dot com
Patch based on PHP_5_0 head branch
applies to php 5.0.4 and php 4.3.10.
tested and works with every I could throw at it (32 bit and 64 bit)

Index: php_mssql.c
===================================================================
RCS file: /repository/php-src/ext/mssql/php_mssql.c,v
retrieving revision 1.137.2.9
diff -u -r1.137.2.9 php_mssql.c
--- php_mssql.c 12 Apr 2005 17:46:06 -0000      1.137.2.9
+++ php_mssql.c 14 Oct 2005 23:02:42 -0000
@@ -1829,10 +1829,15 @@
                WRONG_PARAM_COUNT;
        }

        ZEND_FETCH_RESOURCE(result, mssql_result *, mssql_result_index, -1, "MS SQL-result", le_result);

        mssql_ptr = result->mssql_ptr;
        retvalue = dbresults(mssql_ptr->link);
+
+       while (dbnumcols(mssql_ptr->link) <= 0 && retvalue == SUCCEED) {
+               retvalue = dbresults(mssql_ptr->link);
+       }
+
        if (retvalue == FAIL) {
                RETURN_FALSE;
        }
 [2005-11-18 20:15 UTC] fmk@php.net
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.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 24 20:02:09 2014 UTC