php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #37581 oci_bind_array_by_name clobbers input array when using SQLT_AFC, AVC
Submitted: 2006-05-24 17:47 UTC Modified: 2006-07-31 10:30 UTC
From: jlevy at imerica dot com Assigned: tony2001
Status: Closed Package: OCI8 related
PHP Version: 5.1.4 OS: Redhat, Debian
Private report: No CVE-ID:
 [2006-05-24 17:47 UTC] jlevy at imerica dot com
Description:
------------
Please note that this relates to 5.1.2, not 5.1.4.

Configuration: 
     Box #1 - PHP 5.1.2 compiled against oracle instant client 10.x, Debian
     Box #2 - PHP 5.1.2 compiled against oracle full libs, Redhat

Calling oci_bind_array_by_name will append extraneous members to input array if using SQLT_AFC or SQLT_AVC (other types untested due to lack of due dilligence)

Sample script to reproduce bug at pastebin.com, see URL below.



Reproduce code:
---------------
http://http://pastebin.com/735456

Expected result:
----------------
Array
(
    [0] => LH
    [1] => JC
    [2] => PJ
)
Array
(
    [0] => LH
    [1] => JC
    [2] => PJ
)
Array
(
    [0] => LH
    [1] => JC
    [2] => PJ
)

Actual result:
--------------
Array
(
    [0] => LH
    [1] => JC
    [2] => PJ
)
Array
(
    [0] => LHJCPJ
    [1] => JCPJ
    [2] => PJ
)
Array
(
    [0] => LHJCPJ
    [1] => JCPJ
    [2] => PJ
    [3] => JCPJ
    [4] => PJ
)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-05-24 17:49 UTC] jlevy at imerica dot com
Apologies for bad pastebin URL. Strip the excess http:// and it should load properly.
 [2006-05-24 17:51 UTC] jlevy at imerica dot com
Another developer in my office verified this bug is also present in PHP 5.1.4

Thank you.
 [2006-05-24 18:00 UTC] tony2001@php.net
I don't think I have a quote.manage_quote.add_plan() procedure, so your reproduce case is not very useful. 
 [2006-05-24 18:36 UTC] jlevy at imerica dot com
create or replace package QUOTE.MANAGE_QUOTE

is

 /**

  * collection of plan_ids

  */

  type array_plan_id is table of char(2) index by binary_integer;

  /**

   * collection of premiums for a plan and quote id

   */

   type array_premium is table of number(16,4) index by binary_integer;

/**

 * Adds a lot of plans to quote.

 *

 * Accepts two arrays, one for plan ids and another for premium and loads them into the database in one

 * sweep.  If the reload parameter is set to Y all existing plan associations will be removed from

 * the database.

 *

 * @param in_quote_id in int quote id to add plans to

 * @param in_plan_id in array_plan_id integer indexed array of plans to add

 * @param in_premium in array_premium integer indexed array of premiums for the corresponding record in plan_id

 * @param reload        Y or N.  Determines if we should flush all plans already saved in the database

 */

procedure add_plan(in_quote_id in int, in_plan_id in array_plan_id, in_premium in array_premium,reload in string);

end MANAGE_QUOTE;

 

create or replace package body QUOTE.MANAGE_QUOTE

as

 

procedure add_plan(in_quote_id in int, in_plan_id in array_plan_id, in_premium in array_premium,reload in string) is

 begin

  if(reload = 'Y') then

    delete quote.quote_plan where quote_id = in_quote_id;

    commit;

  end if;

  for i in 1 .. in_plan_id.count loop

    insert into quote.quote_plan(quote_id,plan_id,premium) values(in_quote_id,in_plan_id(i),in_premium(i));

  end loop;

  commit;

end add_plan;

 

end MANAGE_QUOTE;
 [2006-05-24 18:46 UTC] tony2001@php.net
Could you please just provide a dummy procedure which can help me to replicate the problem?
I don't have quote.quote_plan table and I guess I'll need even more tables, triggers and stored procedures just to recreate a simple problem.
Thanks.
 [2006-05-24 19:55 UTC] jlevy at imerica dot com
/*
 * Oracle package for test procedure. required to define user
 * defined type.
 */
create or replace package phptest as
  type str_array is table of char(2) index by binary_integer;
  /**
   * procedure accepting a char input array and a string output.
   */
  procedure array_bind(in_str in str_array, out_str out string); end phptest; / show errors;

create or replace package body phptest 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 phptest;
/
show errors;



PHP Code as Follows:

$db             = oci_connect('user','pass'.','server');
$stmt           = oci_parse($db,'begin phptest.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);
echo "values of Strings array after 1st run:\n"; print_r($strings); oci_execute($stmt); echo "values of Strings array after 2nd run:\n"; print_r($strings);
 [2006-07-31 10:30 UTC] tony2001@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 24 20:02:09 2014 UTC