|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-08-25 14:38 UTC] php-oci8 dot pkoch at dfgh dot net
Description: ------------ Using Out-Variables results in ORA-03131: an invalid buffer was provided for the next piece when oci_execute() is called with PHP-7.4.22 under Solaris 11.4 64bit SPARC Bug https://bugs.php.net/bug.php?id=73002 from 2019 seems to deal with the same problem and provides patches. Test-Script runs fine with PHP-5.6.37 (both under Solaris 64bit and Linux 32/64bit). It also has no problems with PHP-7.4.22 under Linux 64bit. Test script: --------------- $conn=oci_new_connect("scott","tiger","ORCL"); $stat=oci_parse($conn, "begin :out:='Hello World'; end;"); oci_bind_by_name($stat, ":out", $result, 100); oci_execute($stat); print "result=$result\n"; PatchesPull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 12:00:01 2025 UTC |
Dear OCI8-developers: ext/oci8/oci8_statement.c has some comments containing the string XXX. Seems as if the developer of this sourcefile marked all lines that had to be fixed somehow. One of these lines is line 1504: /* XXX we assume that zend-zval len has 4 bytes */ *alenpp = (ub4*) &Z_STRLEN_P(val); *bufpp = Z_STRVAL_P(val); .... Of course this assumption is wrong on 64bit machines where Z_STRLEN is 8 bytes long (i.e. size_t) and ub4 is 4 bytes long. So when OCI8 retrieves a value it will store its length as as ub4-value into the first 4 bytes of a size_t value. If the 64bit machine was little-endian the resulting size_t-value is equal to the ub4-value. On big-endian machines the resulting size_t-value will be equal to the ub4-value shifted to the left by 32bits. And this causes the ORA-03131 error. If one wants to store a ub4-value into a size_t-value via a pointer then this pointer must point to the first 4 bytes of the size_t value on little-endian systems and to the last 4 bytes of the size_t value on big-endian systems. And one has to make sure, that the remaining 4 bytes will all be 0. A better solution is to let the pointer point to a ub4-value and move the value to a size_t-value later. I added the following 4 lines after line 1505: /* XXX we assume that zend-zval len has 4 bytes */ *alenpp = (ub4*) &Z_STRLEN_P(val); if(sizeof(zend_long)==2*sizeof(ub4)){ zend_long z=1; if(*(ub4*)&z==0) ++*alenpp; } *bufpp = Z_STRVAL_P(val); .... Then everything works as expected. Any comments? Regards Peter Koch