php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #44390 bind_param / bind_result and Object member variables
Submitted: 2008-03-10 09:21 UTC Modified: 2008-05-16 09:13 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: pumuckel at metropolis dot de Assigned: andrey (profile)
Status: Closed Package: MySQLi related
PHP Version: 5.2.5 OS: Linux Gentoo
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: pumuckel at metropolis dot de
New email:
PHP Version: OS:

 

 [2008-03-10 09:21 UTC] pumuckel at metropolis dot de
Description:
------------
Mysqli bind_param and bind_result functions are changing object member variables to be references with strange side affects.

a) I expect the object to keep the member variable types as is. Currently they change to reference variables with the result of strange side effects when you do not keep this in mind. We have to clone objects before using them for bindings, right now - this is a working workaround. I vote for a bug, at least it should be documented.

b) I expect binding on the same variable with different types working. Currently I can manage to get a memory access to arbitrary data, possibly leading to a segmentation fault or security violation. Again, I vote for a bug.


Reproduce code:
---------------
<?php
$hostname = "localhost";
$username = "dbuser";
$password = "dbpassword";
$dbname   = "dbname";

class foo {
  // @var $bar string
  public $bar;
}

$foo = new foo;
$foo->bar = "foobar";

$db = new mysqli($hostname, $username, $password, $dbname);

echo "Test 1: \n";
$stmt = $db->prepare("SELECT ? FOO");
var_dump($foo); // here you can see the bar member var beeing a string
$stmt->bind_param("s", $foo->bar);
var_dump($foo); // this will show $foo->bar beeing a reference string
$stmt->bind_result($one);
$stmt->execute();
$stmt->fetch();
$stmt->free_result();
echo("$one\n\n");

// it is getting worse. Binding the same var twice with different 
// types you can get unexpected results (e.g. binary trash for the
// string and misc data for the integer. See next 2 tests.

echo "Test 2: \n";
$stmt = $db->prepare("SELECT ? FOO, ? BAR");
var_dump($foo);
$stmt->bind_param("si", $foo->bar, $foo->bar);
var_dump($foo);
$stmt->bind_result($one, $two);
$stmt->execute();
$stmt->fetch();
$stmt->free_result();
echo("$one - $two\n\n");

echo "Test 3: \n";

$stmt = $db->prepare("SELECT ? FOO, ? BAR");
var_dump($foo);
$stmt->bind_param("is", $foo->bar, $foo->bar);
var_dump($foo);
$stmt->bind_result($one, $two);
$stmt->execute();
$stmt->fetch();
$stmt->free_result();
echo("$one - $two\n\n");

?>

Expected result:
----------------
Test 1: 
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
foobar

Test 2: 
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
foobar - 0

Test 3: 
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
0 - foobar


Actual result:
--------------
Test 1: 
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#5 (1) {
  ["bar"]=>
  &string(6) "foobar"
}
foobar

Test 2: 
object(foo)#5 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#5 (1) {
  ["bar"]=>
  &string(6) "foobar"
}
&#65533;Pbar - 0

Test 3: 
object(foo)#5 (1) {
  ["bar"]=>
  int(0)
}
object(foo)#5 (1) {
  ["bar"]=>
  &int(0)
}
140653124 - 0



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-03-18 17:36 UTC] andrey@php.net
I get the following with mysqli/mysqlnd, which seems correct, except for the reference, but I have to investigate whether this is incorrect. There is no memory error it seems.

Test 1:
object(foo)#1 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#1 (1) {
  ["bar"]=>
  &string(6) "foobar"
}
foobar

Test 2:
object(foo)#1 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#1 (1) {
  ["bar"]=>
  &string(6) "foobar"
}
foobar - 0

Test 3:
object(foo)#1 (1) {
  ["bar"]=>
  int(0)
}
object(foo)#1 (1) {
  ["bar"]=>
  &int(0)
}
0 - 0
----------------------------------
mysqli/libmysql gives the following, one sees that there is something wrong
Test 1:
object(foo)#1 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#1 (1) {
  ["bar"]=>
  &string(6) "foobar"
}
foobar

Test 2:
object(foo)#1 (1) {
  ["bar"]=>
  string(6) "foobar"
}
object(foo)#1 (1) {
  ["bar"]=>
  &string(6) "foobar"
}
ZZZZZZ - 0

Test 3:
object(foo)#1 (1) {
  ["bar"]=>
  int(0)
}
object(foo)#1 (1) {
  ["bar"]=>
  &int(0)
}
139797916 - 0


Assigning to myself
 [2008-03-18 17:37 UTC] andrey@php.net
Ohje, there is a problem, valgrind cries :

==22493== Invalid read of size 1
==22493==    at 0x40245A1: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x412563F: store_param_str (libmysql.c:2389)
==22493==    by 0x41257D6: store_param (libmysql.c:2443)
==22493==    by 0x4125CD0: cli_stmt_execute (libmysql.c:2544)
==22493==    by 0x412643F: mysql_stmt_execute (libmysql.c:2856)
==22493==    by 0x80FE3EB: zif_mysqli_stmt_execute (mysqli_api.c:734)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==  Address 0x4F7BE9D is 5 bytes inside a block of size 7 free'd
==22493==    at 0x402243F: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x82B65AB: _efree (zend_alloc.c:2291)
==22493==    by 0x82D4098: convert_to_long_base (zend_operators.c:353)
==22493==    by 0x82D3F1F: convert_to_long (zend_operators.c:325)
==22493==    by 0x80FE3A6: zif_mysqli_stmt_execute (mysqli_api.c:723)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==
==22493== Invalid read of size 1
==22493==    at 0x40245A9: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x412563F: store_param_str (libmysql.c:2389)
==22493==    by 0x41257D6: store_param (libmysql.c:2443)
==22493==    by 0x4125CD0: cli_stmt_execute (libmysql.c:2544)
==22493==    by 0x412643F: mysql_stmt_execute (libmysql.c:2856)
==22493==    by 0x80FE3EB: zif_mysqli_stmt_execute (mysqli_api.c:734)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==  Address 0x4F7BE9C is 4 bytes inside a block of size 7 free'd
==22493==    at 0x402243F: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x82B65AB: _efree (zend_alloc.c:2291)
==22493==    by 0x82D4098: convert_to_long_base (zend_operators.c:353)
==22493==    by 0x82D3F1F: convert_to_long (zend_operators.c:325)
==22493==    by 0x80FE3A6: zif_mysqli_stmt_execute (mysqli_api.c:723)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==
==22493== Invalid read of size 1
==22493==    at 0x40245B0: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x412563F: store_param_str (libmysql.c:2389)
==22493==    by 0x41257D6: store_param (libmysql.c:2443)
==22493==    by 0x4125CD0: cli_stmt_execute (libmysql.c:2544)
==22493==    by 0x412643F: mysql_stmt_execute (libmysql.c:2856)
==22493==    by 0x80FE3EB: zif_mysqli_stmt_execute (mysqli_api.c:734)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==  Address 0x4F7BE9B is 3 bytes inside a block of size 7 free'd
==22493==    at 0x402243F: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x82B65AB: _efree (zend_alloc.c:2291)
==22493==    by 0x82D4098: convert_to_long_base (zend_operators.c:353)
==22493==    by 0x82D3F1F: convert_to_long (zend_operators.c:325)
==22493==    by 0x80FE3A6: zif_mysqli_stmt_execute (mysqli_api.c:723)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==
==22493== Invalid read of size 1
==22493==    at 0x40245B7: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x412563F: store_param_str (libmysql.c:2389)
==22493==    by 0x41257D6: store_param (libmysql.c:2443)
==22493==    by 0x4125CD0: cli_stmt_execute (libmysql.c:2544)
==22493==    by 0x412643F: mysql_stmt_execute (libmysql.c:2856)
==22493==    by 0x80FE3EB: zif_mysqli_stmt_execute (mysqli_api.c:734)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==  Address 0x4F7BE9A is 2 bytes inside a block of size 7 free'd
==22493==    at 0x402243F: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x82B65AB: _efree (zend_alloc.c:2291)
==22493==    by 0x82D4098: convert_to_long_base (zend_operators.c:353)
==22493==    by 0x82D3F1F: convert_to_long (zend_operators.c:325)
==22493==    by 0x80FE3A6: zif_mysqli_stmt_execute (mysqli_api.c:723)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==
==22493== Invalid read of size 1
==22493==    at 0x40245D3: memcpy (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x412563F: store_param_str (libmysql.c:2389)
==22493==    by 0x41257D6: store_param (libmysql.c:2443)
==22493==    by 0x4125CD0: cli_stmt_execute (libmysql.c:2544)
==22493==    by 0x412643F: mysql_stmt_execute (libmysql.c:2856)
==22493==    by 0x80FE3EB: zif_mysqli_stmt_execute (mysqli_api.c:734)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)
==22493==  Address 0x4F7BE99 is 1 bytes inside a block of size 7 free'd
==22493==    at 0x402243F: free (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==22493==    by 0x82B65AB: _efree (zend_alloc.c:2291)
==22493==    by 0x82D4098: convert_to_long_base (zend_operators.c:353)
==22493==    by 0x82D3F1F: convert_to_long (zend_operators.c:325)
==22493==    by 0x80FE3A6: zif_mysqli_stmt_execute (mysqli_api.c:723)
==22493==    by 0x830DC7E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:190)
==22493==    by 0x830EF55: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:309)
==22493==    by 0x830D4F9: execute (zend_vm_execute.h:91)
==22493==    by 0x82DF4CD: zend_execute_scripts (zend.c:1170)
==22493==    by 0x825B0A7: php_execute_script (main.c:2059)
==22493==    by 0x837B57B: main (php_cli.c:1139)

 [2008-03-20 15:46 UTC] andrey@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.

Fixed in 5.3.0-dev
The original variables passed for parameter binding won't be changed anymore if there is a type conversion to be performed like:
$str = "fubar"
bind_param("i", $str);
// here $str used to be 0, after the fix it will be "fubar" again
The reference counting is needed because the variable used for param binding should not be freed, in case the script loses the last reference to it. Otherwise mysqli will point to nirvana and might crash.
 [2008-05-16 09:13 UTC] pumuckel at metropolis dot de
Can we expect a backport / patch for 5.2 ? 5.3-dev is not supported by gentoo dist, and we need a production fix.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 11:01:28 2024 UTC