summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2007-01-11 11:27:52 +0000
committerAntony Dovgal <tony2001@php.net>2007-01-11 11:27:52 +0000
commit12d54fa6832df1860970470ccd404141ca700997 (patch)
tree077ad264623ad89c38819d7c430254b3ddb4ecd2 /ext
parent5e74c607a2bf0d00a850a251cc935e3967ee50f0 (diff)
downloadphp-git-12d54fa6832df1860970470ccd404141ca700997.tar.gz
MFH: fix #40078 (ORA-01405 when fetching NULL values using oci_bind_array_by_name())
Diffstat (limited to 'ext')
-rw-r--r--ext/oci8/oci8.c7
-rw-r--r--ext/oci8/oci8_statement.c10
-rw-r--r--ext/oci8/php_oci8_int.h2
-rw-r--r--ext/oci8/tests/bug40078.phpt55
4 files changed, 70 insertions, 4 deletions
diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c
index 35f1a00d03..8be07b31cd 100644
--- a/ext/oci8/oci8.c
+++ b/ext/oci8/oci8.c
@@ -778,13 +778,16 @@ void php_oci_bind_hash_dtor(void *data)
if (bind->array.elements) {
efree(bind->array.elements);
}
+
if (bind->array.element_lengths) {
efree(bind->array.element_lengths);
}
-/*
+
if (bind->array.indicators) {
efree(bind->array.indicators);
- }
+ }
+
+/*
if (bind->array.retcodes) {
efree(bind->array.retcodes);
}
diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c
index e839950449..e043cc9717 100644
--- a/ext/oci8/oci8_statement.c
+++ b/ext/oci8/oci8_statement.c
@@ -1270,7 +1270,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam
(dvoid *) bindp->array.elements,
(sb4) bind->array.max_length,
type,
- (dvoid *)0, /* bindp->array.indicators, */
+ (dvoid *)bindp->array.indicators,
(ub2 *)bind->array.element_lengths,
(ub2 *)0, /* bindp->array.retcodes, */
(ub4) max_table_length,
@@ -1320,6 +1320,8 @@ php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length,
bind->array.max_length = maxlength;
bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
memset(bind->array.element_lengths, 0, max_table_length*sizeof(ub2));
+ bind->array.indicators = safe_emalloc(max_table_length, sizeof(sb2), 0);
+ memset(bind->array.indicators, 0, max_table_length*sizeof(sb2));
zend_hash_internal_pointer_reset(hash);
@@ -1327,6 +1329,9 @@ php_oci_bind *php_oci_bind_array_helper_string(zval* var, long max_table_length,
if (zend_hash_get_current_data(hash, (void **) &entry) != FAILURE) {
convert_to_string_ex(entry);
bind->array.element_lengths[i] = Z_STRLEN_PP(entry);
+ if (Z_STRLEN_PP(entry) == 0) {
+ bind->array.indicators[i] = -1;
+ }
zend_hash_move_forward(hash);
} else {
break;
@@ -1372,6 +1377,7 @@ php_oci_bind *php_oci_bind_array_helper_number(zval* var, long max_table_length
bind->array.max_length = sizeof(ub4);
bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
+ bind->array.indicators = NULL;
zend_hash_internal_pointer_reset(hash);
for (i = 0; i < max_table_length; i++) {
@@ -1409,6 +1415,7 @@ php_oci_bind *php_oci_bind_array_helper_double(zval* var, long max_table_length
bind->array.max_length = sizeof(double);
bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
+ bind->array.indicators = NULL;
zend_hash_internal_pointer_reset(hash);
for (i = 0; i < max_table_length; i++) {
@@ -1446,6 +1453,7 @@ php_oci_bind *php_oci_bind_array_helper_date(zval* var, long max_table_length, p
bind->array.max_length = sizeof(OCIDate);
bind->array.element_lengths = safe_emalloc(max_table_length, sizeof(ub2), 0);
memset(bind->array.element_lengths, 0, max_table_length * sizeof(ub2));
+ bind->array.indicators = NULL;
zend_hash_internal_pointer_reset(hash);
for (i = 0; i < max_table_length; i++) {
diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h
index 4ddefe2ae3..cee37dbc73 100644
--- a/ext/oci8/php_oci8_int.h
+++ b/ext/oci8/php_oci8_int.h
@@ -180,7 +180,7 @@ typedef struct { /* php_oci_bind {{{ */
php_oci_statement *parent_statement; /* pointer to the parent statement */
struct {
void *elements;
-/* ub2 *indicators; */
+ sb2 *indicators;
ub2 *element_lengths;
/* ub2 *retcodes; */
ub4 current_length;
diff --git a/ext/oci8/tests/bug40078.phpt b/ext/oci8/tests/bug40078.phpt
new file mode 100644
index 0000000000..4a234e176d
--- /dev/null
+++ b/ext/oci8/tests/bug40078.phpt
@@ -0,0 +1,55 @@
+--TEST--
+Bug #40078 (ORA-01405 when fetching NULL values using oci_bind_array_by_name())
+--SKIPIF--
+<?php if (!extension_loaded('oci8')) die("skip no oci8 extension"); ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$create_pkg = "
+CREATE OR REPLACE PACKAGE ARRAYBINDPKG1 AS
+ TYPE ARRTYPE IS TABLE OF VARCHAR(20) INDEX BY BINARY_INTEGER;
+ PROCEDURE nullbind(c1 OUT ARRTYPE);
+END ARRAYBINDPKG1;";
+$statement = oci_parse($c, $create_pkg);
+oci_execute($statement);
+
+$create_pkg_body = "
+CREATE OR REPLACE PACKAGE BODY ARRAYBINDPKG1 AS
+ PROCEDURE nullbind(c1 OUT ARRTYPE) IS
+ BEGIN
+ c1(1) := 'one';
+ c1(2) := 'two';
+ c1(3) := '';
+ c1(4) := 'four';
+ c1(5) := 'five';
+ END nullbind;
+END ARRAYBINDPKG1;";
+$statement = oci_parse($c, $create_pkg_body);
+oci_execute($statement);
+
+$statement = oci_parse($c, "BEGIN ARRAYBINDPKG1.nullbind(:c1); END;");
+
+oci_bind_array_by_name($statement, ":c1", $array, 5, 20, SQLT_CHR);
+
+oci_execute($statement);
+
+var_dump($array);
+
+echo "Done\n";
+?>
+--EXPECTF--
+array(5) {
+ [0]=>
+ string(3) "one"
+ [1]=>
+ string(3) "two"
+ [2]=>
+ string(0) ""
+ [3]=>
+ string(4) "four"
+ [4]=>
+ string(4) "five"
+}
+Done