summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2006-07-31 10:30:23 +0000
committerAntony Dovgal <tony2001@php.net>2006-07-31 10:30:23 +0000
commitf5b5d34a271a2005189a9bf015c7400d5ebb5f64 (patch)
treeb3ebe381aa51c2a2c3d5a8187ce2ca17bfd6e362
parent610b633096049cf4455be0831e2bf2ff0db9c5c9 (diff)
downloadphp-git-f5b5d34a271a2005189a9bf015c7400d5ebb5f64.tar.gz
MFH: fix #37581 (oci_bind_array_by_name clobbers input array when using SQLT_AFC, AVC)
-rw-r--r--NEWS2
-rw-r--r--ext/oci8/oci8.c3
-rw-r--r--ext/oci8/oci8_statement.c32
-rw-r--r--ext/oci8/php_oci8_int.h4
-rw-r--r--ext/oci8/tests/array_bind_005.phpt3
-rw-r--r--ext/oci8/tests/bug37581.phpt69
6 files changed, 107 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 6fd5e96946..01e6ca861e 100644
--- a/NEWS
+++ b/NEWS
@@ -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