diff options
author | Antony Dovgal <tony2001@php.net> | 2006-07-31 10:30:23 +0000 |
---|---|---|
committer | Antony Dovgal <tony2001@php.net> | 2006-07-31 10:30:23 +0000 |
commit | f5b5d34a271a2005189a9bf015c7400d5ebb5f64 (patch) | |
tree | b3ebe381aa51c2a2c3d5a8187ce2ca17bfd6e362 | |
parent | 610b633096049cf4455be0831e2bf2ff0db9c5c9 (diff) | |
download | php-git-f5b5d34a271a2005189a9bf015c7400d5ebb5f64.tar.gz |
MFH: fix #37581 (oci_bind_array_by_name clobbers input array when using SQLT_AFC, AVC)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/oci8/oci8.c | 3 | ||||
-rw-r--r-- | ext/oci8/oci8_statement.c | 32 | ||||
-rw-r--r-- | ext/oci8/php_oci8_int.h | 4 | ||||
-rw-r--r-- | ext/oci8/tests/array_bind_005.phpt | 3 | ||||
-rw-r--r-- | ext/oci8/tests/bug37581.phpt | 69 |
6 files changed, 107 insertions, 6 deletions
@@ -49,6 +49,8 @@ PHP NEWS - Fixed bug #38047 ("file" and "line" sometimes not set in backtrace from inside error handler). (Dmitry) - Fixed bug #37846 (wordwrap() wraps incorrectly). (ddk at krasn dot ru, Tony) +- Fixed bug #37581 (oci_bind_array_by_name clobbers input array when using + SQLT_AFC, AVC). (Tony) - Fixed bug #37564 (AES privacy encryption not possible due to net-snmp 5.2 compatibility issue). (Jani, patch by scott dot moynes+php at gmail dot com) diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index b34316da0e..ba483f1189 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -760,9 +760,10 @@ void php_oci_bind_hash_dtor(void *data) if (bind->array.elements) { efree(bind->array.elements); } -/* if (bind->array.element_lengths) { + if (bind->array.element_lengths) { efree(bind->array.element_lengths); } +/* if (bind->array.indicators) { efree(bind->array.indicators); } diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 32cf84d913..819bf2405b 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -664,6 +664,8 @@ int php_oci_bind_post_exec(void *data TSRMLS_DC) zval **entry; HashTable *hash = HASH_OF(bind->zval); + zend_hash_internal_pointer_reset(hash); + switch (bind->array.type) { case SQLT_NUM: case SQLT_INT: @@ -731,7 +733,8 @@ int php_oci_bind_post_exec(void *data TSRMLS_DC) case SQLT_STR: case SQLT_LVC: for (i = 0; i < bind->array.current_length; i++) { - int curr_element_length = strlen(((text *)bind->array.elements)+i*bind->array.max_length); + /* int curr_element_length = strlen(((text *)bind->array.elements)+i*bind->array.max_length); */ + int curr_element_length = bind->array.element_lengths[i]; if ((i < bind->array.old_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) { zval_dtor(*entry); ZVAL_STRINGL(*entry, ((text *)bind->array.elements)+i*bind->array.max_length, curr_element_length, 1); @@ -1174,7 +1177,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam (sb4) bind->array.max_length, type, (dvoid *)0, /* bindp->array.indicators, */ - (ub2 *)0, /* bindp->array.element_lengths, */ + (ub2 *)bind->array.element_lengths, (ub2 *)0, /* bindp->array.retcodes, */ (ub4) max_table_length, (ub4 *) &(bindp->array.current_length), @@ -1220,6 +1223,19 @@ php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length, bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); bind->array.old_length = bind->array.current_length; bind->array.max_length = maxlength; + bind->array.element_lengths = ecalloc(1, max_table_length * sizeof(ub2)); + + zend_hash_internal_pointer_reset(hash); + + for (i = 0; i < bind->array.current_length; i++) { + if (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) { + convert_to_string_ex(entry); + bind->array.element_lengths[i] = Z_STRLEN_PP(entry); + zend_hash_move_forward(hash); + } else { + break; + } + } zend_hash_internal_pointer_reset(hash); for (i = 0; i < max_table_length; i++) { @@ -1259,9 +1275,13 @@ php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); bind->array.old_length = bind->array.current_length; bind->array.max_length = sizeof(ub4); + bind->array.element_lengths = ecalloc(1, max_table_length * sizeof(ub2)); zend_hash_internal_pointer_reset(hash); for (i = 0; i < max_table_length; i++) { + if (i < bind->array.current_length) { + bind->array.element_lengths[i] = sizeof(ub4); + } if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) { convert_to_long_ex(entry); ((ub4 *)bind->array.elements)[i] = (ub4) Z_LVAL_PP(entry); @@ -1292,9 +1312,13 @@ php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); bind->array.old_length = bind->array.current_length; bind->array.max_length = sizeof(double); + bind->array.element_lengths = ecalloc(1, max_table_length * sizeof(ub2)); zend_hash_internal_pointer_reset(hash); for (i = 0; i < max_table_length; i++) { + if (i < bind->array.current_length) { + bind->array.element_lengths[i] = sizeof(double); + } if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) { convert_to_double_ex(entry); ((double *)bind->array.elements)[i] = (double) Z_DVAL_PP(entry); @@ -1325,10 +1349,14 @@ php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, p bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); bind->array.old_length = bind->array.current_length; bind->array.max_length = sizeof(OCIDate); + bind->array.element_lengths = ecalloc(1, max_table_length * sizeof(ub2)); zend_hash_internal_pointer_reset(hash); for (i = 0; i < max_table_length; i++) { OCIDate oci_date; + if (i < bind->array.current_length) { + bind->array.element_lengths[i] = sizeof(OCIDate); + } if ((i < bind->array.current_length) && (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE)) { convert_to_string_ex(entry); diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index b3e2c46137..18e739f1cd 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -178,9 +178,9 @@ typedef struct { /* php_oci_bind {{{ */ php_oci_statement *parent_statement; /* pointer to the parent statement */ struct { void *elements; -/* ub2 *indicators; +/* ub2 *indicators; */ ub2 *element_lengths; - ub2 *retcodes; */ +/* ub2 *retcodes; */ long current_length; long old_length; long max_length; diff --git a/ext/oci8/tests/array_bind_005.phpt b/ext/oci8/tests/array_bind_005.phpt index 192d15563d..15278532ea 100644 --- a/ext/oci8/tests/array_bind_005.phpt +++ b/ext/oci8/tests/array_bind_005.phpt @@ -58,7 +58,8 @@ var_dump($array); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- +Warning: oci_execute(): ORA-01405: fetched column value is NULL in %s on line %d array(5) { [0]=> string(0) "" diff --git a/ext/oci8/tests/bug37581.phpt b/ext/oci8/tests/bug37581.phpt new file mode 100644 index 0000000000..ec86c51959 --- /dev/null +++ b/ext/oci8/tests/bug37581.phpt @@ -0,0 +1,69 @@ +--TEST-- +Bug #37581 (oci_bind_array_by_name clobbers input array when using SQLT_AFC, AVC) +--SKIPIF-- +<?php if (!extension_loaded("oci8")) print "skip"; ?> +--FILE-- +<?php + +require dirname(__FILE__)."/connect.inc"; + +$p1 = "create or replace package ARRAYBINDPKG1 as +type str_array is table of char(2) index by binary_integer; +procedure array_bind(in_str in str_array, out_str out string); +end ARRAYBINDPKG1;"; + +$p2 = "create or replace package body ARRAYBINDPKG1 as + procedure array_bind(in_str in str_array, out_str out string) is + begin + for i in 1 .. in_str.count loop + out_str := in_str(i); + end loop; + end array_bind; +end ARRAYBINDPKG1;"; + +$s1 = oci_parse($c, $p1); +$s2 = oci_parse($c, $p2); +oci_execute($s1); +oci_execute($s2); + + +$stmt = oci_parse($c,'begin ARRAYBINDPKG1.array_bind(:in_arr, :out_str); end;'); +$strings = array('A','B','C','D','E'); + +oci_bind_array_by_name($stmt,':in_arr',$strings,5,1,SQLT_AFC); +oci_bind_by_name($stmt,':out_str',$result,10); + +oci_execute($stmt); +var_dump($strings); + +oci_execute($stmt); +var_dump($strings); + +echo "Done\n"; +?> +--EXPECTF-- +array(5) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + [4]=> + string(1) "E" +} +array(5) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + [4]=> + string(1) "E" +} +Done |