| 
        php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
  [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;
 			break;
 		}
 		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:
 						break;
 					default:
 						/* take no chances, no telling how big the result would really be */
 						res_length += 20;
 						break;
 				}
 
 				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 thies@thieso.net  */
-				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 == ' ')
 					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));
 				ZVAL_FALSE(result);
 			}
 		}
 	}
Frediano Ziglio
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             
             | 
    |||||||||||||||||||||||||||||||||||||
            
                 
                Copyright © 2001-2025 The PHP GroupAll rights reserved.  | 
        Last updated: Tue Nov 04 06:00:01 2025 UTC | 
I forgot. To check the issue try: #!/home/freddy/install/bin/php -q <?php $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); ?> freddy77