Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

ObjectProperty Hydrator should only hydrate public properties (fix + new test) #6869

Conversation

BinaryKitten
Copy link
Contributor

According to the docs, the Zend\Stdlib\Hydrator\ObjectProperty hydrator hydrates "Any data key matching a publicly accessible property will be hydrated; any public properties will be used for extraction."

No Test was found directly for this Hydrator and the Hydrator itself would attempt to set private or protected properties resulting in a fatal error.
To this end, I have:

  1. submitted the fix to only hydrate public properties
  2. have created a test for the hydrator

I hope that this meets guidelines for this.

}

/**
* @expectedException BadMethodCallException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use $this->setExpectedException() instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for all other instances

@BinaryKitten
Copy link
Contributor Author

Conversation with @Ocramius in IRC led to find that to prevent the random addition of non existent properties to objects the way forward would be to use a FilterComposite to remove items that didn't exist prior to hydration.

I've modified the Hydrator to now just exclude private/protected properties to prevent fatal errors occurring in these situations. Have removed the final test in the new testcase as was no longer applicable to the outcome.

@DASPRiD
Copy link
Member

DASPRiD commented Nov 13, 2014

I'd assume that many people (including myself) used the ObjectProperty hydrator to hydrate and extract protected and private properties. Changing this would break BC. Making it an option, defaulting to the prior behaviour, is probably the best way to go right now.

@Ocramius
Copy link
Member

I'd assume that many people (including myself) used the ObjectProperty hydrator to hydrate and extract protected and private properties.

Right now it will just crash (current impl).

@@ -68,6 +68,15 @@ public function hydrate(array $data, $object)
'%s expects the provided $object to be a PHP object)', __METHOD__
));
}

$reflection = new ReflectionObject($object);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking this at every hydration is going to kill performance badly. Needs to be a bit smarter

@DASPRiD
Copy link
Member

DASPRiD commented Nov 13, 2014

Ah nevermind, I'm actually using the ReflectionHydrator for that, ignore me ;)

@Ocramius Ocramius added this to the 2.3.4 milestone Nov 22, 2014

$propertyList = (array)$object;
$privatePropertyPrefix = "\0" . get_class($object) . "\0";
$protectedPropertyPrefix = "\0*\0";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just look for any property starting with "\0": that is enough to decide to skip them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't work as the array has the \0 version, not the property in
iteration
On 22 Nov 2014 07:56, "Marco Pivetta" [email protected] wrote:

In library/Zend/Stdlib/Hydrator/ObjectProperty.php:

@@ -68,8 +68,20 @@ public function hydrate(array $data, $object)
'%s expects the provided $object to be a PHP object)', METHOD
));
}
+

  •    $propertyList = (array)$object;
    
  •    $privatePropertyPrefix = "\0" . get_class($object) . "\0";
    
  •    $protectedPropertyPrefix = "\0*\0";
    

You can just look for any property starting with "\0": that is enough to
decide to skip them.


Reply to this email directly or view it on GitHub
https://github.com/zendframework/zf2/pull/6869/files#r20755730.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good point. I would still fill every array key with a value (true is fine) to avoid having calls to array_key_exists()

@BinaryKitten
Copy link
Contributor Author

Further conversations with @Ocramius has lead to the issue that private & protected properties can be unset, which the array casting will not catch, leading to the fatal error again.

Trying different solutions around this, but most likely the only solution is use reflections in the property cache. This doesn't seem to degrade the speed as much as it could do.

@Ocramius Ocramius added the bug label Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
…tName()` over direct `ReflectionProperty#$name` access
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
Ocramius added a commit that referenced this pull request Nov 29, 2014
@Ocramius Ocramius closed this in 36f30e2 Nov 29, 2014
@Ocramius
Copy link
Member

@BinaryKitten I've tweaked and merged this, thanks!

master: 36f30e2
develop: 45d5a36

gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…tAttributeSame` for strict checks. Minor CS, method naming and docblock fixes
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…uced properties on generic userland classes
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…t be hydrated by the `ObjectProperty` hydrator
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…t be hydrated by the `ObjectProperty` hydrator
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…t be extracted by the `ObjectProperty` hydrator
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…sing `ReflectionProperty#getName()` over direct `ReflectionProperty#$name` access
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…ache`/`ObjectProperty#$skippedPropertiesCache`
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants