|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #20467 Buffer overflow returning binary
Submitted: 2002-11-17 13:31 UTC Modified: 2002-12-11 08:35 UTC
Avg. Score:4.5 ± 0.8
Reproduced:5 of 5 (100.0%)
Same Version:4 (80.0%)
Same OS:5 (100.0%)
From: freddy77 at angelfire dot com Assigned:
Status: Closed Package: Sybase (dblib) related
PHP Version: 4.2.3 OS: Linux
Private report: No CVE-ID: None
 [2002-11-17 13:31 UTC] freddy77 at angelfire dot com
dbconvert convert binary -> char returning binary representation so 0x6789 (2 bytes) became '6789' (4 single byte characters)
When converting back to PHP (in ext/sybase/php_sybase_db.c) you pass the same size buffer leading to a buffer overflow.

Following patch fix problem. It also fix another problem (it remove last characters from conversion) and avoid future possible buffer overflows due to strange types (like UNIQUEIDs in MSSQL)

diff -r -u10 php-4.2.3/ext/sybase/php_sybase_db.c php-4.2.3mod/ext/sybase/php_sybase_db.c
--- php-4.2.3/ext/sybase/php_sybase_db.c	Wed Mar  6 16:59:42 2002
+++ php-4.2.3mod/ext/sybase/php_sybase_db.c	Sun Nov 17 20:08:31 2002
@@ -710,49 +710,51 @@
 		/*case SYBFLT8:*/
 		case SYBREAL: {
 			Z_DVAL_P(result) = (double) floatcol(offset);
 			Z_TYPE_P(result) = IS_DOUBLE;
 		default: {
 			if (dbwillconvert(coltype(offset),SYBCHAR)) {
 				char *res_buf;
 				int res_length = dbdatlen(sybase_ptr->link,offset);
+				int src_length = res_length;
 				register char *p;
 				switch (coltype(offset)) {
 					case SYBBINARY:
 					case SYBVARBINARY:
+						res_length *= 2;
+						break;
 					case SYBCHAR:
 					case SYBVARCHAR:
 					case SYBTEXT:
 					case SYBIMAGE:
 						/* take no chances, no telling how big the result would really be */
 						res_length += 20;
 				res_buf = (char *) emalloc(res_length+1);
 				memset(res_buf,' ',res_length+1);  /* XXX i'm sure there's a better way
        		  but i don't have sybase here to test
        		  991105  */
-				dbconvert(NULL,coltype(offset),dbdata(sybase_ptr->link,offset), res_length,SYBCHAR,res_buf,-1);
+				dbconvert(NULL,coltype(offset),dbdata(sybase_ptr->link,offset), src_length,SYBCHAR,res_buf,res_length);
 				/* get rid of trailing spaces */
 				p = res_buf + res_length;
-				while (*p == ' ') {
+				while (*p == ' ')
-					res_length--;
-				}
 				*(++p) = 0; /* put a trailing NULL */
+				res_length = p - res_buf;
 				Z_STRLEN_P(result) = res_length;
 				Z_STRVAL_P(result) = res_buf;
 				Z_TYPE_P(result) = IS_STRING;
 			} else {
 				php_error(E_WARNING,"Sybase:  column %d has unknown data type (%d)", offset, coltype(offset));

Frediano Ziglio


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2002-11-17 13:34 UTC] freddy77 at angelfire dot com
I forgot. To check the issue try:

#!/home/freddy/install/bin/php -q
$db_handle = sybase_connect("server","user","pass");
sybase_select_db("tempdb", $db_handle);
$db_result = sybase_query("select convert(varbinary,space(120))");
$res = sybase_fetch_row($db_result);
print "\nres=$res[0]\n";
print sybase_num_rows($db_result);
$db_result = sybase_query("select convert(numeric(18,2),1234.89)");
$res = sybase_fetch_row($db_result);
print "\nres=$res[0]\n";
print sybase_num_rows($db_result);

 [2002-11-18 13:25 UTC] freddy77 at angelfire dot com
I found also another problem.
If NULL is returned (length == 0) the loop 
"while (*p == ' ') --p;"
can lead to a buffer underflow,
"while (p >= res_buf && *p == ' ') --p;"
fix the problem

 [2002-12-07 01:29 UTC]
Someone familiar with the workings of the sybase extension should definately review the patch and make the necessary corrections before the next RC is out.
 [2002-12-09 04:11 UTC] freddy77 at angelfire dot com
You have also to decide what result you want for binary data.
If you use dbconvert for this type your results will be a hexadecimal string. If you want binary data instead you should manually copy data (use just memcpy) or do a conversion to binary, not to characters.

 [2002-12-10 09:44 UTC]
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at
In case this was a documentation problem, the fix will show up soon at

In case this was a website problem, the change will show
up on the site and on the mirror sites in short time.
Thank you for the report, and for helping us make PHP better.

 [2002-12-10 14:04 UTC] freddy77 at angelfire dot com
dbconvert is called passing res_length as source length. This can cause problems...


dbconvert(NULL,coltype(offset),dbdata(sybase_ptr->link,offset), res_length,SYBCHAR,res_buf,res_length);

should be replaced with

dbconvert(NULL,coltype(offset),dbdata(sybase_ptr->link,offset), src_length,SYBCHAR,res_buf,res_length);

 [2002-12-11 05:03 UTC] freddy77 at angelfire dot com
Perhaps is better to reopen
 [2002-12-11 08:35 UTC]
No. The typo was already fixed.
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Sat Sep 30 14:01:24 2023 UTC