php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #17799 Using $this->$variable_name inside object clears all variable values
Submitted: 2002-06-17 08:40 UTC Modified: 2002-06-17 14:58 UTC
From: qdot at numberporn dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: CVS OS: Any
Private report: No CVE-ID: None
 [2002-06-17 08:40 UTC] qdot at numberporn dot com
Summary: When accidently using the syntax $this->$variable_name in an object to set a variable, all the variables in the object are set to the value that is given. This seems like it could cause a serious security issue.

Steps to reproduce:
1. Create an object with multiple class variables
2. Create an setVar function with the incorrect syntax
3. Instantiate a new variable in a script to the class and use the setVar function. All variables in the object will now hold this value.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-06-17 09:58 UTC] sander@php.net
Can't reproduce:
$ php -v
PHP 4.3.0-dev (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.2.1, Copyright (c) 1998-2002 Zend Technologies
$ cat test.php 
<?php
	error_reporting(E_ALL);

	class foo {
		var $a = 'a';
		var $b = 'b';
		function foo() {
			$this->$a = 'foo';
		}
	}

	$foo = &new foo();
	print_r($foo);
?>
$ php test.php 

Notice: Undefined variable:  a in test.php on line 8

foo Object
(
    [a] => a
    [b] => b
    [] => foo
)

Can you provide a simple and selfcontained sample script that reproduces the problem?
 [2002-06-17 10:05 UTC] qdot at numberporn dot com
Here's the exact script we used when we found this bug:

----

TableProperties.class

<?

/***********************************************
 * This class represents the attributes which define
 * the properties of a Table.
 */
class TableProperties
{
	//the attributes which define a table
	var $widthTable;
	var $heightTable;
	var $cellPadding;
	var $cellSpacing;
	var $border;
	var $widthCell;
	var $heightCell;
	var $hAlignCell;
	var $vAlignCell;


	/**
	 * Constructor of the class. Main purpose is to
	 * initialize the variables with a value as a default.
	 */
	function TableProperties()
	{
		$this->$widthTable = "";
		$this->$heightTable = "";
		$this->$cellPadding = 0;
		$this->$cellSpacing = 0;
		$this->$border = 0;
		$this->$widthCell = "";
		$this->$heightCell = "";
		$this->$hAlignCell = "center";
		$this->$vAlignCell = "top";
	}

	/**
	 * Returns the attributes as a key-value pair
	 * that is compatible with HTML.
	 */
	function getWidthTablePair() { return ("width='" . $this->$widthTable . "'"); }
	function getHeightTablePair() {	return ("height='" . $this->$heightTable . "'"); }
	function getCellPaddingPair() {	return ("cellpadding='" . $this->$cellPadding . "'"); }
	function getCellSpacingPair() {	return ("cellspacing='" . $this->$cellSpacing . "'"); }
	function getBorderPair() { return ("border='" . $this->$border . "'"); }
	function getWidthCellPair() { return ("width='" . $this->$widthCell . "'"); }
	function getHeightCellPair() { return ("height='" . $this->$heightCell . "'"); }
	function getHAlignCellPair() { return ("align='" . $this->$hAlignCell . "'"); }
	function getVAlignCellPair() { return ("valign='" . $this->$vAlignCell . "'"); }

	/**
	 * Returns the values of the attributes.
	 */
	function getWidthTable() { return $this->$widthTable; }
	function getHeightTable() { return $this->$heightTable; }
	function getCellPadding() { return $this->$cellPadding; }
	function getCellSpacing() { return $this->$cellSpacing; }
	function getBorder() { return $this->$border; }
	function getWidthCell() { return $this->$widthCell; }
	function getHeightCell() { return $this->$heightCell; }
	function getHAlignCell() { return $this->$hAlignCell; }
	function getVAlignCell() { return $this->$vAlignCell; }

	/**
	 * Sets the variables to the given value.
	 */
	function setWidthTable($widthTable_ = "") { $this->$widthTable = $widthTable_; }
	function setHeightTable($heightTable_ = "") { $this->$heightTable = $heightTable_; }
	function setCellPadding($cellPadding_ = "") { $this->$cellPadding = $cellPadding_; }
	function setCellSpacing($cellSpacing_ = "") { $this->$cellSpacing = $cellSpacing_; }
	function setBorder($border_ = "") { $this->$border = $border_; }
	function setWidthCell($widthCell_ = "") { $this->$widthCell = $widthCell_; }
	function setHeightCell($heightCell_ = "") { $this->$heightCell = $heightCell_; }
	function setHAlignCell($hAlignCell_ = "") { $this->$hAlignCell = $hAlignCell_; }
	function setVAlignCell($vAlignCell_ = "") { $this->$vAlignCell = $vAlignCell_; }
}

?>


----

test-00.php

<?php
	require("TableProperties.class");


	$tp = new TableProperties();

	echo $tp->getHeightTablePair() . "<br>";
	echo $tp->getWidthTablePair() . "<br>";
	echo $tp->getBorderPair() . "<br>";
	echo $tp->getVAlignCellPair() . "<br>";

	$tp->setHeightTable(500);
	$tp->setWidthTable("600");
	$tp->setBorder(5);
	//$tp->setVAlignCell("bottom");

	echo $tp->getHeightTablePair() . "<br>";
	echo $tp->getWidthTablePair() . "<br>";
	echo $tp->getBorderPair() . "<br>";
	echo $tp->getVAlignCellPair() . "<br>";
?>

----

Output is:

>php test-00.php
X-Powered-By: PHP/4.2.1
Content-type: text/html

height='top'<br>width='top'<br>border='top'<br>valign='top'<br>height='5'<br>width='5'<br>border='5'<br>valign='5'<br>
 [2002-06-17 10:29 UTC] sander@php.net
Does my simple testscript give the same problem? Your test script is too long to serve as a test script, you'll lose track of it at once. Please track the problem down to only a couple of lines.
 [2002-06-17 12:28 UTC] mfischer@php.net
Shorter example:

<?
	class foo {
		var $a;
		var $b;

		function foo() {
			$this->$notdefined = 0;
		}

		function getA() {
			return "a='" .  $this->$a . "'";
		}
		function getB() {
			return "b='" .  $this->$b . "'";
		}

		function setA($a_ = "") {
			$this->$dontexistseither = $a_;
		}
	}

	$o = new foo();

	echo $o->getA() . "\n";
	echo $o->getB() . "\n";

	$o->setA(500);

	echo $o->getA() . "\n";
	echo $o->getB() . "\n";
?>

Outputs: $ php bug_17799.php 
a='0'
b='0'
a='500'
b='500'
 [2002-06-17 13:43 UTC] qdot at numberporn dot com
Yes, this script produces the same result when run:

Output:

>php test.php
X-Powered-By: PHP/4.2.1
Content-type: text/html

a='0'
b='0'
a='500'
b='500'
 [2002-06-17 14:09 UTC] rodif_bl@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is what it should do...

if you look at your assignments
$this->$a = "blah";

a is a variable not a member....
$this->a = "blah" is the correct syntax for what you want

basically what you are doing with
$this->$a = "blah";
is assigning the member '' with the text "blah"... cause $a is evaluated to ''.

you can use the $this->$a syntax but $a needs to be defined
$a = "somemember";
$this->$a = "sometext";

 [2002-06-17 14:35 UTC] sander@php.net
rodif_bl, this is NOT a bogus. You're right that $this->$undefined_var is not correct, but it should not empty _all_ variables/properties of that object.
 [2002-06-17 14:46 UTC] rodif_bl@php.net
THIS IS BOGUS... It DOES NOT clear out all member variables... 

if you look at the examples getA and getB return $this->$a and $this->$b which $this->$a is just as undefined as $this->$undefined. getA and getB should return $this->a and $this->b (with out the $).

$this->$undefined = "blah"; 
 will assign '' to "blah";

return $this->$a;
 is the exact same thing as
return $this->'';

so you are returning "blah"


if you change your example...
<?
	class foo {
		var $a;
		var $b;

		function foo() {
			$this->$notdefined = 0;
		}

		function getA() {
			return "a='" .  $this->a . "'";
		}
		function getB() {
			return "b='" .  $this->b . "'";
		}

		function setA($a_ = "") {
			$this->$dontexistseither = $a_;
		}
	}

	$o = new foo();

	echo $o->getA() . "\n";
	echo $o->getB() . "\n";

	$o->setA(500);

	echo $o->getA() . "\n";
	echo $o->getB() . "\n";
?>


you will see it works fine!


 [2002-06-17 14:58 UTC] sander@php.net
OK, you're right. Objects apparently can have properties named "". Not a bug -> bogus.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Oct 19 16:03:35 2021 UTC