]> granicus.if.org Git - php/commitdiff
MFH: fix #40078 (ORA-01405 when fetching NULL values using oci_bind_array_by_name())
authorAntony Dovgal <tony2001@php.net>
Thu, 11 Jan 2007 11:27:52 +0000 (11:27 +0000)
committerAntony Dovgal <tony2001@php.net>
Thu, 11 Jan 2007 11:27:52 +0000 (11:27 +0000)
NEWS
ext/oci8/oci8.c
ext/oci8/oci8_statement.c
ext/oci8/php_oci8_int.h
ext/oci8/tests/bug40078.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index fcf04118c6709efcdeebf49eb6a4d4ae39d5a464..43be0c945d82df1c8fad9ea14cff628e59ef4159 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP                                                                        NEWS
 - Fixed bug #40083 (milter SAPI functions always return false/null). (Tony)
 - Fixed bug #40079 (php_get_current_user() not thread safe). (Ilia, wharmby
   at uk dot ibm dot com)
+- Fixed bug #40078 (ORA-01405 when fetching NULL values using 
+  oci_bind_array_by_name()). (Tony)
 - Fixed bug #40076 (zend_alloc.c: Value of enumeration constant must be in
   range of signed integer). (Dmitry)
 - Fixed bug #40073 (exif_read_data dies on certain images). (Tony, Marcus)
index 35f1a00d037799e6499ce572417fa9a9f0ec22fa..8be07b31cd0409d4d6fff0efefd8c237fad2763d 100644 (file)
@@ -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);
        } 
index e839950449c9f50fa0673e36ec124d21ce604e89..e043cc9717e24f2b3477884d97fcfd9ae3c15909 100644 (file)
@@ -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++) {
index 4ddefe2ae3ae89cef93f4769fe0da762c0564c99..cee37dbc73ec457bc7872edf00d0e2bbce4ab4a3 100644 (file)
@@ -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 (file)
index 0000000..4a234e1
--- /dev/null
@@ -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