ZF-3334: Zend_Rest_Server faults with empty page on strange keys in _structValue()

Description

Trying to return associative structs / arrays with XML-invalid keys (e.g. Zend_Db_Profiler_Query) breaks _structValue.


    protected function _structValue($struct, DOMDocument $dom, DOMElement $parent)
    {
        $struct = (array) $struct;

        foreach ($struct as $key => $value) {
          // at this point $struct can have strange keys (.e.g "*_query")
          //  $key=preg_replace('/[^a-zA-Z0-9_-]/','_',$key); // this could sanitize $key
            if ($value === false) {
                $value = 0;
            } elseif ($value === true) {
                $value = 1;
            }

            if (ctype_digit((string) $key)) {
                $key = 'key_' . $key;
            }

            if (is_array($value) || is_object($value)) {
                $element = $dom->createElement($key); // this is generates an exception because $key is invalid XML

Finally, the fault exception handler registered in the constructor fails to output anything because fault() is designed to return the DomDocument Instead. Suggest to register a separate handler.

Comments

Actually, the issue appears with private and protected object properties:

[ http://php.net/manual/en/… ] If an object is converted to an array, the result is an array whose elements are the object's properties. The keys are the member variable names, with a few notable exceptions: private variables have the class name prepended to the variable name; protected variables have a '*' prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour:

I don't think private/protected properties should be returned. Suggested fix:


    protected function _structValue($struct, DOMDocument $dom, DOMElement $parent)
    {
        if (is_object($struct)) $struct=get_object_vars($struct);
        
        $struct = (array) $struct;

Please evaluate and fix/categorize as necessary.

See ZF-3338 - This issue has been fixed already in one of the many duplicate entries of this bug.