]> granicus.if.org Git - php/commitdiff
fix #38161 (oci_bind_by_name() returns garbage when Oracle didn't set the variable)
authorAntony Dovgal <tony2001@php.net>
Wed, 9 Aug 2006 12:13:30 +0000 (12:13 +0000)
committerAntony Dovgal <tony2001@php.net>
Wed, 9 Aug 2006 12:13:30 +0000 (12:13 +0000)
ext/oci8/oci8_statement.c
ext/oci8/php_oci8_int.h
ext/oci8/tests/bug37581.phpt [new file with mode: 0644]
ext/oci8/tests/bug38161.phpt [new file with mode: 0644]

index 926cc5ca77ddbbee3587d5b1193124a99c343990..19f2d2c376aa32b9cafd3f8d67d42bf3aa01e7ca 100644 (file)
@@ -826,9 +826,11 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len,
                case SQLT_LNG:
                case SQLT_CHR:
                        /* this is the default case when type was not specified */
-                       convert_to_string(var);
+                       if (Z_TYPE_P(var) != IS_NULL) {
+                               convert_to_string(var);
+                       }
                        if (maxlength == -1) {
-                               value_sz = Z_STRLEN_P(var);
+                               value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : 0;
                        }
                        else {
                                value_sz = maxlength;
@@ -1003,7 +1005,7 @@ sb4 php_oci_bind_out_callback(
                zval_dtor(val);
                
                Z_STRLEN_P(val) = PHP_OCI_PIECE_SIZE; /* 64K-1 is max XXX */
-               Z_STRVAL_P(val) = emalloc(Z_STRLEN_P(phpbind->zval));
+               Z_STRVAL_P(val) = ecalloc(1, Z_STRLEN_P(phpbind->zval) + 1);
                
                /* XXX we assume that zend-zval len has 4 bytes */
                *alenpp = (ub4*) &Z_STRLEN_P(phpbind->zval); 
index 18e739f1cdb8457494c284fffe2fdba95cd31194..346abe3ce4ac87c416ea9827111e1822381ef47d 100644 (file)
@@ -186,7 +186,7 @@ typedef struct { /* php_oci_bind {{{ */
                long max_length;
                long type;
        } array;
-       sb2 indicator;                  /*  */
+       sb2 indicator;                  /* -1 means NULL */
        ub2 retcode;                    /*  */
 } php_oci_bind; /* }}} */
 
diff --git a/ext/oci8/tests/bug37581.phpt b/ext/oci8/tests/bug37581.phpt
new file mode 100644 (file)
index 0000000..ec86c51
--- /dev/null
@@ -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
diff --git a/ext/oci8/tests/bug38161.phpt b/ext/oci8/tests/bug38161.phpt
new file mode 100644 (file)
index 0000000..27cfafd
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+bug #38161 (oci_bind_by_name() returns garbage when Oracle didn't set the variable)
+--SKIPIF--
+<?php if (!extension_loaded("oci8")) print "skip"; ?>
+--FILE--
+<?php
+
+require dirname(__FILE__).'/connect.inc';
+
+$query = "begin if false then :bv := 1; end if; end;";
+$stid = oci_parse($c, $query);
+oci_bind_by_name($stid, ":bv", $bv, 22);
+oci_execute($stid, OCI_DEFAULT);
+
+var_dump($bv);
+unset($bv);
+
+$query = "begin if false then :bv := 1; end if; end;";
+$stid = oci_parse($c, $query);
+oci_bind_by_name($stid, ":bv", $bv, 22, SQLT_INT);
+oci_execute($stid, OCI_DEFAULT);
+
+var_dump($bv);
+
+echo "Done\n";
+?>
+--EXPECTF--    
+NULL
+int(0)
+Done