php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #45614 ArrayIterator::current(), ::key() can show 1st private prop of wrapped object
Submitted: 2008-07-24 12:50 UTC Modified: 2008-07-24 15:57 UTC
From: robin_fernandes at uk dot ibm dot com Assigned:
Status: Closed Package: SPL related
PHP Version: 5.3CVS-2008-07-24 (CVS) OS: all
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: robin_fernandes at uk dot ibm dot com
New email:
PHP Version: OS:

 

 [2008-07-24 12:50 UTC] robin_fernandes at uk dot ibm dot com
Description:
------------
If the first property of a class is private and an instance of that class is wrapped by ArrayIterator, that first private property may be exposed by ArrayIterator::current() and ArrayIterator::key(). Specifically, this occurs when: 
 - current() and key() are called right after obtaining the iterator from ArrayObject::getIterator(), OR
 - current() and key() are called right after the iterator position was reset due to the current position becoming invalid.

In the reproduce code below, notice how the iterator behaves differently depending on how it was returned to its starting position.

This issue affects snaps from 5_2, 5_3 and HEAD.
It can be fixed with some extra calls to spl_array_skip_protected() in spl_array.c.
Proposed patch against 5_3: http://pastebin.ca/1081771


Reproduce code:
---------------
<?php
class C {
	private $priv1 = 'secret1';
	private $priv2 = 'secret2';
	public $pub1 = 'public1';
	public $pub2 = 'public2';
	public $pub3 = 'public3';
} 

function showFirstTwoItems($it) {
  echo str_replace("\0", '\0', $it->key()) . " => " . $it->current() . "\n";
  $it->next();
  echo str_replace("\0", '\0', $it->key()) . " => " . $it->current() . "\n";
}

$ao = new ArrayObject(new C);
$ai = $ao->getIterator();

echo "--> Show the first two items:\n";
showFirstTwoItems($ai);

echo "\n--> Rewind and show the first two items:\n";
$ai->rewind();
showFirstTwoItems($ai);

echo "\n--> Invalidate current position and show the first two items:\n";
unset($ai[$ai->key()]);
$ai->current();
showFirstTwoItems($ai);
?>

Expected result:
----------------
--> Show the first two items:
pub1 => public1
pub2 => public2

--> Rewind and show the first two items:
pub1 => public1
pub2 => public2

--> Invalidate current position and show the first two items:
pub1 => public1
pub3 => public3

Actual result:
--------------
--> Show the first two items:
\0C\0priv1 => secret1
pub1 => public1

--> Rewind and show the first two items:
pub1 => public1
pub2 => public2

--> Invalidate current position and show the first two items:
\0C\0priv1 => secret1
pub1 => public1

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-07-24 15:57 UTC] lbarnaud@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, thanks for the patch.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC