#23142 [Fbk->Opn]: datalen parameter is not correctly set when calling stored procedures
| From: | arnarb at oddi dot is | Date: | Wed, 23 Apr 2003 13:59:47 +0000 |
| Subject: | #23142 [Fbk->Opn]: datalen parameter is not correctly set when calling stored procedures | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-38212@lists.php.net to get a copy of this message | ||
ID: 23142
User updated by: arnarb at oddi dot is
Reported By: arnarb at oddi dot is
-Status: Feedback
+Status: Open
Bug Type: MSSQL related
Operating System: Linux 2.4.18
PHP Version: 4.3.1
New Comment:
The bug is still present in the latest snapshot (as of April 23, 2003).
Previous Comments:
------------------------------------------------------------------------
[2003-04-23 03:50:09] sniper@php.net
Please try using this CVS snapshot:
http://snaps.php.net/php4-STABLE-latest.tar.gz
For Windows:
http://snaps.php.net/win32/php4-win32-STABLE-latest.zip
------------------------------------------------------------------------
[2003-04-09 17:50:13] arnarb at oddi dot is
When calling a stored procedure on MS-SQL Server 7.0 and 2000 via the
mssql_init, mssql_bind and mssql_execute functions, the size of
parameters is always set to -1. This causes the FreeTDS library to
segfault in a memcpy.
I'm running php 4.3.1 on an apache 1.2.24 linked with FreeTDS 0.61.
This is easily fixed on one line in ext/mssql/php_mssql.c by changing
line 1966 (in the 4.3.1 release) from
datalen = -1;
to
datalen = tds_get_size_by_type(type);
I checked tis file in the CVS repository and the latest revision still
contains this bug. This seems to fix the problem for me but I haven't
tested it thoroughly and I since I'm not familiar enough with the code
I don't know if it breaks anything else.
Steps to reproduce:
This assumes that the default "pubs" demo database is set up the sql
server. Run the following script:
($link = mssql_connect("test", "sa", "supervisor")) ||
die("1");;
mssql_select_db("pubs", $link) || die("2");
print(mssql_get_last_message());
$stmt = mssql_init("byroyalty", $link);
$p = 50;
mssql_bind($stmt, "@percentage", $p, SQLINT2);
$result = mssql_execute($stmt);
print(mssql_get_last_message());
print("<table border=1>\n");
while ($line = mssql_fetch_array($result)) {
print("\t<tr>\n");
foreach ($line as $field) {
print("\t\t<td>$field</td>\n");
}
print("\t</tr>\n");
}
?>
Follwing is some output from gdb including a backtrace:
arnarb@kassi:~/public_html/mssqltests$ gdb php
GNU gdb 5.2
(gdb) run < test1.php
Starting program: /usr/bin/php < test1.php
Program received signal SIGSEGV, Segmentation fault.
0x406d8e37 in memcpy (dstpp=0x83f7634, srcpp=0x83e3984, len=4294967295)
at ../sysdeps/generic/memcpy.c:55
55 ../sysdeps/generic/memcpy.c: No such file or directory.
in ../sysdeps/generic/memcpy.c
(gdb) bt
#0 0x406d8e37 in memcpy (dstpp=0x83f7634, srcpp=0x83e3984,
len=4294967295) at ../sysdeps/generic/memcpy.c:55
#1 0x404a8f1d in param_row_alloc (params=0x83f7600, curcol=0x83f74b8,
value=0x83e3984, size=-1) at rpc.c:217
#2 0x404a9022 in param_info_alloc (rpc=0x83e43a0) at rpc.c:261
#3 0x404a8e8b in dbrpcsend (dbproc=0x83e3b10) at rpc.c:192
#4 0x08106f1b in zif_mssql_execute (ht=1, return_value=0x83e3964,
this_ptr=0x0, return_value_used=1)
at /usr/src/php-4.3.1/ext/mssql/php_mssql.c:2044
#5 0x081f5803 in execute (op_array=0x83df7b4) at
/usr/src/php-4.3.1/Zend/zend_execute.c:1598
#6 0x081e3f0e in zend_execute_scripts (type=8, retval=0x0,
file_count=3) at /usr/src/php-4.3.1/Zend/zend.c:864
#7 0x081bc68a in php_execute_script (primary_file=0xbffff788) at
/usr/src/php-4.3.1/main/main.c:1573
#8 0x08206dfc in main (argc=1, argv=0xbffff804) at
/usr/src/php-4.3.1/sapi/cli/php_cli.c:746
#9 0x4067b17d in __libc_start_main (main=0x820644c <main>, argc=1,
ubp_av=0xbffff804, init=0x8081e2c <_init>,
fini=0x82581d0 <_fini>, rtld_fini=0x4000a534 <_dl_fini>,
stack_end=0xbffff7fc)
at ../sysdeps/generic/libc-start.c:129
(gdb) p params
No symbol "params" in current context.
(gdb) select 1
(gdb) p params
$1 = (TDSPARAMINFO *) 0x83f7600
(gdb) p *params
$2 = {num_cols = 1, columns = 0x83e45e0, row_size = 8, null_info_size =
4, current_row = 0x83f7630 "",
rows_exist = 0, row_count = 0, computeid = 0, more_results = 0 '\0',
bycolumns = 0x0, by_cols = 0}
(gdb) p *curcol
$3 = {column_type = 52, column_type_save = 52, column_usertype = 0,
column_flags = 0, column_size = 2,
column_varint_size = 0 '\0', column_prec = 0 '\0', column_scale = 0
'\0', column_namelen = 0 '\0',
column_name = "@percentage", '\0' <repeats 244 times>, column_offset
= 4, column_nullable = 0,
column_writeable = 0, column_identity = 0, column_unicodedata = 0,
column_output = 0,
column_collation = "\0\0\0\0", column_operator = 0 '\0',
column_operand = 0, column_cur_size = -1,
column_bindtype = 0, column_bindfmt = 0, column_bindlen = 0,
column_nullbind = 0x0, column_varaddr = 0x0,
column_lenbind = 0x0, column_textpos = 0, column_text_sqlgetdatapos =
0}
(gdb) p params->current_row
$4 = (unsigned char *) 0x83f7630 ""
(gdb) p *value
Attempt to dereference a generic pointer.
(gdb) p value
$5 = (void *) 0x83e3984
(gdb) p (int) *value
Attempt to dereference a generic pointer.
(gdb) p *((int*) value)
$6 = 50
(gdb) p size
$7 = -1
(gdb) select 2
(gdb) p *p
$8 = {next = 0x0, name = 0x83e45d0 "@percentage", status = 0 '\0', type
= 52, maxlen = -1, datalen = -1,
value = 0x83e3984 "2"}
(gdb) p ((int*) p->value)
$9 = (int *) 0x83e3984
(gdb) p *((int*) p->value)
$10 = 50
(gdb) select 4
(gdb) p mssql_statement
Attempt to use a type name as an expression
(gdb) p statement
$11 = (mssql_statement *) 0x83e39dc
(gdb) p *statement
$12 = {id = 2, link = 0x83dfbd4, binds = 0x83e44c4, executed = 0}
(gdb) p statement->binds
$13 = (HashTable *) 0x83e44c4
(gdb) p *(statement->binds)
$14 = {nTableSize = 16, nTableMask = 15, nNumOfElements = 1,
nNextFreeElement = 0,
pInternalPointer = 0x83e457c, pListHead = 0x83e457c, pListTail =
0x83e457c, arBuckets = 0x83e452c,
pDestructor = 0x810224c <_mssql_bind_hash_dtor>, persistent = 0 '\0',
nApplyCount = 0 '\0',
bApplyProtection = 1 '\001'}
(gdb) p mssql_ptr
$15 = (mssql_link *) 0x83dfbd4
(gdb) p *mssql_ptr
$16 = {login = 0x83d8f90, link = 0x83e3b10, valid = 1}
(gdb) p *(mssql_ptr->link)
$17 = {tds_socket = 0x83e4238, row_buf = {buffering_on = 1,
first_in_buf = 0, next_row = 1, newest = -1,
oldest = 0, elcount = 2, element_size = 0, rows_in_buf = 0, rows =
0x0}, noautofree = 0, more_results = 1,
empty_result = 0, user_data = 0x0, dbbuf = 0x0, dbbufsz = 0,
text_size = 0, text_sent = 0,
bcp_hostfile = 0x0, bcp_errorfile = 0x0, bcp_tablename = 0x0,
bcp_insert_stmt = 0x0, bcp_direction = 0,
bcp_colcount = 0, host_colcount = 0, bcp_columns = 0x0, host_columns
= 0x0, firstrow = 0, lastrow = 0,
maxerrs = 0, bcpbatch = 0, sendrow_init = 0, var_cols = 0, typeinfo =
{precision = 0, scale = 0},
avail_flag = 0 '\0', dbopts = 0x83e3bf8, dboptcmd = 0x0, bcp = {hint
= 0x0}, rpc = 0x83e43a0,
envchange_rcv = 1, dbcurdb = "pubs", '\0' <repeats 26 times>,
servcharset = "iso_1", '\0' <repeats 25 times>}
(gdb) p *(mssql_ptr->link->rpc)
$18 = {next = 0x0, name = 0x83e43b8 "byroyalty", options = 0,
param_list = 0x83e45b0}
(gdb) p *(mssql_ptr->link->rpc->param_list)
$19 = {next = 0x0, name = 0x83e45d0 "@percentage", status = 0 '\0',
type = 52, maxlen = -1, datalen = -1,
value = 0x83e3984 "2"}
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=23142&edit=1