|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-09-02 11:14 UTC] lzsiga at freemail dot c3 dot hu
Description: ------------ Hi, I think I've found a little bug in component ext/oci8 that affects only 64-bit big-endian platforms. In ext/oci8/oci8_statement.c:php_oci_bind_out_callback (line 1461) the program assumes that &val->string->len (type size_t *) can be type-casted to (ub4 *) Well, that works on 32-bit platforms, also on 64-bit/little-endian platforms, but fails on bi-bit/big-endian platforms such as PowerPc64/Aix (size_t is eight bytes, ub4 is four bytes, and a simple type-cast does the wrong thing). The attached patch seems to solve the problem. Test script: --------------- /* anonymous PL/SQL block */ BEGIN SELECT ename INTO :ename FROM emp WHERE empno=7876; END; Expected result: ---------------- ename=ADAMS Actual result: -------------- oci_execute(): ORA-03131: an invalid buffer was provided for the next piece Patchesoci8_statement.patch_8_2_0 (last revision 2022-12-31 20:02 UTC by lzsiga at freemail dot c3 dot hu)oci8_statement.patch_8_0_9 (last revision 2021-08-30 09:49 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_8_0_0 (last revision 2020-08-17 10:52 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_4_0boolean2 (last revision 2019-12-16 10:52 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_4_0boolean (last revision 2019-12-16 10:17 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_4_0 (last revision 2019-11-27 10:12 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_3_0_RC2 (last revision 2018-10-01 11:57 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_3_0 (last revision 2018-06-12 15:01 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_1_11 (last revision 2017-10-29 14:53 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_1_8 (last revision 2017-08-10 13:06 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_1_4 (last revision 2017-04-28 08:33 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_0_13_v2 (last revision 2016-11-14 19:12 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_0_13 (last revision 2016-11-14 12:11 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement_v2.patch_7_0_11 (last revision 2016-09-16 11:13 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch_7_0_11 (last revision 2016-09-16 10:28 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement_v2.patch (last revision 2016-09-08 10:22 UTC by lzsiga at freemail dot c3 dot hu) oci8_statement.patch (last revision 2016-09-02 11:14 UTC by lzsiga at freemail dot c3 dot hu) Pull Requests
Pull requests:
HistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 07:00:01 2025 UTC |
Found solution for power bigendian 64 bit *** ext / oci8 / oci8_statement.c Tue Aug 1 19:36:51 2017 --- ../php-7.1.8-changed/ext/oci8/oci8_statement.c Thu Aug 10 13:25:20 2017 *************** *** 979,995 **** } zval_dtor (val); ZVAL_NULL (val); ! } Else if (Z_TYPE_P (bind-> zval) == IS_STRING ! && Z_STRLEN_P (bind-> zval)> 0 ! && Z_STRVAL_P (bind-> zval) [Z_STRLEN_P (bind-> zval)]! = '\ 0') { ! / * The post- PHP 5.3 feature for "interned" strings disallows ! * Their reallocation but (i) any IN binds either interned or ! * Should not already be null terminated and (ii) for OUT ! Binds, php_oci_bind_out_callback () should have allocated a ! * New string that we can modify here. ! * / ! Z_STR_P (bind-> zval) = zend_string_extend (Z_STR_P (bind-> zval), Z_STRLEN_P (bind-> zval) +1, 0); ! Z_STRVAL_P (bind-> zval) [Z_STRLEN_P (bind-> zval)] = '\ 0'; } Else if (Z_TYPE_P (bind-> zval) == IS_ARRAY) { Int i; Zval * entry = NULL; --- 979,997 ---- } zval_dtor (val); ZVAL_NULL (val); ! } Else if (Z_TYPE_P (bind-> zval) == IS_STRING) { ! Z_STRLEN_P (bind-> zval) = bind-> dummy_len; ! If (Z_STRLEN_P (bind-> zval)> 0 && ! Z_STRVAL_P (bind-> zval) [Z_STRLEN_P (bind-> zval)]! = '\ 0') { ! / * The post- PHP 5.3 feature for "interned" strings disallows ! * Their reallocation but (i) any IN binds either interned or ! * Should not already be null terminated and (ii) for OUT ! Binds, php_oci_bind_out_callback () should have allocated a ! * New string that we can modify here. ! * / ! Z_STR_P (bind-> zval) = zend_string_extend (Z_STR_P (bind-> zval), Z_STRLEN_P (bind-> zval) +1, 0); ! Z_STRVAL_P (bind-> zval) [Z_STRLEN_P (bind-> zval)] = '\ 0'; ! } } Else if (Z_TYPE_P (bind-> zval) == IS_ARRAY) { Int i; Zval * entry = NULL; *************** *** 1371,1376 **** --- 1373.1379 ---- * Bufpp = 0; * Alenp = -1; * Indpp = (dvoid *) & phpbind-> indicator; + Phpbind-> dummy_len = 0; / * So far, 'dummy_len' meant the maximum length; From now, it is the actual length * / } Else if ((phpbind-> descriptor == 0) && (phpbind-> statement == 0)) { / * "Normal string bind * / convert_to_string (val); *************** *** 1386,1391 **** --- 1389.1395 ---- If ((phpbind-> dummy_len> 0) && (phpbind-> dummy_len <* alenp)) * Alenp = phpbind-> dummy_len; * Indpp = (dvoid *) & phpbind-> indicator; + Phpbind-> dummy_len = * alenp; / * So far, 'dummy_len' meant the maximum length; From now, it is the actual length * / } Else if (phpbind-> statement! = 0) { / * RSET * / * Bufpp = phpbind-> statement; *************** *** 1477,1484 **** ZVAL_STRINGL (val, NULL, Z_STRLEN (phpbind-> zval) + 1); #endif ! / * XXX we assume that zend-zval len has 4 bytes * / ! * Alenpp = (ub4 *) & Z_STRLEN_P (phpbind-> zval); * Bufpp = Z_STRVAL_P (phpbind-> zval); * Piecep = OCI_ONE_PIECE; * Rcodepp = & phpbind-> retcode; --- 1481.1489 ---- ZVAL_STRINGL (val, NULL, Z_STRLEN (phpbind-> zval) + 1); #endif ! / * XXX we assume that zend-zval len has 4 bytes - does not work on big endian PowerPC-64 * / ! Phpbind-> dummy_len = Z_STRLEN_P (phpbind-> zval); ! * Alenpp = & phpbind-> dummy_len; * Bufpp = Z_STRVAL_P (phpbind-> zval); * Piecep = OCI_ONE_PIECE; * Rcodepp = & phpbind-> retcode;@davereddy Hi, sorry for the delay; I tried `php bind_boolean_1.phpt` with 7.4.0; the very first test gave Test 1 bool(false) bool(false) while the file says it should be Test 1 bool(true) bool(false) I hope I'll be able look into this problem.Please test the latest patch, it might solve the boolean-problem. The clue of the patch is this macro: #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define LongPtr2Int32Ptr(longptr) ((int32_t *)(longptr)) #else #define LongPtr2Int32Ptr(longptr) \ ((int32_t *)((char *)(longptr)+(sizeof(long)-sizeof(int32_t)))) #endif It should work on both big-endian/32-bit and big-endian/64-bit; nonetheless it will fail 'long' isn't equal to 'zend_long' (e.g. Windows/64-bit)