Esempio n. 1
0
 /**
  * {@inheritdoc}
  */
 public function parse($xmlString)
 {
     if ($this->validateResponse) {
         XmlChecker::isValid($xmlString);
     }
     $result = xmlrpc_decode($xmlString, 'UTF-8');
     if ($result === null && self::isBiggerThanParseLimit($xmlString)) {
         throw ParserException::xmlrpcExtensionLibxmlParsehugeNotSupported();
     }
     $toBeVisited = [&$result];
     while (isset($toBeVisited[0]) && ($value =& $toBeVisited[0])) {
         $type = gettype($value);
         if ($type === 'object') {
             $xmlRpcType = $value->{'xmlrpc_type'};
             if ($xmlRpcType === 'datetime') {
                 $value = \DateTime::createFromFormat('Ymd\\TH:i:s', $value->scalar, isset($timezone) ? $timezone : ($timezone = new \DateTimeZone('UTC')));
             } elseif ($xmlRpcType === 'base64') {
                 if ($value->scalar !== '') {
                     $value = Base64Value::serialize($value->scalar);
                 } else {
                     $value = null;
                 }
             }
         } elseif ($type === 'array') {
             foreach ($value as &$element) {
                 $toBeVisited[] =& $element;
             }
         }
         array_shift($toBeVisited);
     }
     if (is_array($result)) {
         reset($result);
         if (xmlrpc_is_fault($result)) {
             throw FaultException::createFromResponse($result);
         }
     }
     return $result;
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  */
 public function parse($xmlString)
 {
     if ($this->validateResponse) {
         XmlChecker::isValid($xmlString);
     }
     $useErrors = libxml_use_internal_errors(true);
     $xml = new \XMLReader();
     $xml->xml($xmlString, 'UTF-8', LIBXML_COMPACT | LIBXML_NOCDATA | LIBXML_NOBLANKS | LIBXML_PARSEHUGE);
     $xml->setParserProperty(\XMLReader::VALIDATE, false);
     $xml->setParserProperty(\XMLReader::LOADDTD, false);
     // This following assignments are auto-generated using Fxmlrpc\Serialization\CodeGenerator\XmlReaderParserBitmaskGenerator
     // Don’t edit manually
     static $flagmethodResponse = 0b1;
     static $flagparams = 0b10;
     static $flagfault = 0b100;
     static $flagparam = 0b1000;
     static $flagvalue = 0b10000;
     static $flagarray = 0b100000;
     static $flagmember = 0b1000000;
     static $flagname = 0b10000000;
     ${'flag#text'} = 0b100000000;
     static $flagstring = 0b1000000000;
     static $flagstruct = 0b10000000000;
     static $flagint = 0b100000000000;
     static $flagbiginteger = 0b1000000000000;
     static $flagi8 = 0b10000000000000;
     static $flagi4 = 0b100000000000000;
     static $flagi2 = 0b1000000000000000;
     static $flagi1 = 0b10000000000000000;
     static $flagboolean = 0b100000000000000000;
     static $flagdouble = 0b1000000000000000000;
     static $flagfloat = 0b10000000000000000000;
     static $flagbigdecimal = 0b100000000000000000000;
     ${'flagdateTime.iso8601'} = 0b1000000000000000000000;
     static $flagdateTime = 0b10000000000000000000000;
     static $flagbase64 = 0b100000000000000000000000;
     static $flagnil = 0b1000000000000000000000000;
     static $flagdom = 0b10000000000000000000000000;
     static $flagdata = 0b100000000000000000000000000;
     // End of auto-generated code
     $aggregates = [];
     $depth = 0;
     $nextExpectedElements = 0b1;
     $i = 0;
     $isFault = false;
     while ($xml->read()) {
         ++$i;
         $nodeType = $xml->nodeType;
         if ($nodeType === \XMLReader::COMMENT || $nodeType === \XMLReader::DOC_TYPE || $nodeType === \XMLReader::SIGNIFICANT_WHITESPACE && ($nextExpectedElements & 0b100000000) !== 0b100000000) {
             continue;
         }
         if ($nodeType === \XMLReader::ENTITY_REF) {
             return '';
         }
         $tagName = $xml->localName;
         if ($nextExpectedElements !== null && ($flag = isset(${'flag' . $tagName}) ? ${'flag' . $tagName} : -1) && ($nextExpectedElements & $flag) !== $flag) {
             throw new UnexpectedTagException($tagName, $nextExpectedElements, get_defined_vars(), $xml->depth, $xml->readOuterXml());
         }
         processing:
         switch ($nodeType) {
             case \XMLReader::ELEMENT:
                 switch ($tagName) {
                     case 'methodResponse':
                         // Next: params, fault
                         $nextExpectedElements = 0b110;
                         break;
                     case 'params':
                         // Next: param
                         $nextExpectedElements = 0b1000;
                         $aggregates[$depth] = [];
                         break;
                     case 'fault':
                         $isFault = true;
                         // Break intentionally omitted
                     // Break intentionally omitted
                     case 'param':
                         // Next: value
                         $nextExpectedElements = 0b10000;
                         break;
                     case 'array':
                         $aggregates[++$depth] = [];
                         // Break intentionally omitted
                     // Break intentionally omitted
                     case 'data':
                         // Next: array, data, value
                         $nextExpectedElements = 0b100000000000000000000110000;
                         break;
                     case 'struct':
                         // Next: struct, member, value
                         $nextExpectedElements = 0b10001010000;
                         $aggregates[++$depth] = [];
                         break;
                     case 'member':
                         // Next: name, value
                         $nextExpectedElements = 0b10010000;
                         $aggregates[++$depth] = [];
                         break;
                     case 'name':
                         // Next: #text
                         $nextExpectedElements = 0b100000000;
                         $type = 'name';
                         break;
                     case 'value':
                         $nextExpectedElements = 0b11111111111111111100110000;
                         $type = 'value';
                         $aggregates[$depth + 1] = '';
                         break;
                     case 'base64':
                     case 'string':
                     case 'biginteger':
                     case 'i8':
                     case 'dateTime.iso8601':
                     case 'dateTime':
                         // Next: value, $tagName, #text
                         $nextExpectedElements = 0b100010000 | ${'flag' . $tagName};
                         $type = $tagName;
                         $aggregates[$depth + 1] = '';
                         break;
                     case 'nil':
                         // Next: value, $tagName
                         $nextExpectedElements = 0b1000000000000000000010000 | ${'flag' . $tagName};
                         $type = $tagName;
                         $aggregates[$depth + 1] = null;
                         break;
                     case 'int':
                     case 'i4':
                     case 'i2':
                     case 'i1':
                         // Next: value, #text, $tagName
                         $nextExpectedElements = 0b100010000 | ${'flag' . $tagName};
                         $type = $tagName;
                         $aggregates[$depth + 1] = 0;
                         break;
                     case 'boolean':
                         // Next: value, #text, $tagName
                         $nextExpectedElements = 0b100010000 | ${'flag' . $tagName};
                         $type = 'boolean';
                         $aggregates[$depth + 1] = false;
                         break;
                     case 'double':
                     case 'float':
                     case 'bigdecimal':
                         // Next: value, #text, $tagName
                         $nextExpectedElements = 0b100010000 | ${'flag' . $tagName};
                         $type = $tagName;
                         $aggregates[$depth + 1] = 0.0;
                         break;
                     case 'dom':
                         $type = 'dom';
                         // Disable type checking
                         $nextExpectedElements = null;
                         $aggregates[$depth + 1] = $xml->readInnerXml();
                         break;
                 }
                 break;
             case \XMLReader::END_ELEMENT:
                 switch ($tagName) {
                     case 'params':
                     case 'fault':
                         break 3;
                     case 'param':
                         // Next: params, param
                         $nextExpectedElements = 0b1010;
                         break;
                     case 'value':
                         $nextExpectedElements = 0b100100000011100100011011100;
                         $aggregates[$depth][] = $aggregates[$depth + 1];
                         break;
                     case 'array':
                     case 'struct':
                         --$depth;
                         // Break intentionally omitted
                     // Break intentionally omitted
                     case 'string':
                     case 'int':
                     case 'biginteger':
                     case 'i8':
                     case 'i4':
                     case 'i2':
                     case 'i1':
                     case 'boolean':
                     case 'double':
                     case 'float':
                     case 'bigdecimal':
                     case 'dateTime.iso8601':
                     case 'dateTime':
                     case 'base64':
                     case 'nil':
                         // Next: value
                         $nextExpectedElements = 0b10000;
                         break;
                     case 'data':
                         // Next: array
                         $nextExpectedElements = 0b100000;
                         break;
                     case 'name':
                         // Next: value, member
                         $nextExpectedElements = 0b1010000;
                         $aggregates[$depth]['name'] = $aggregates[$depth + 1];
                         break;
                     case 'member':
                         // Next: struct, member
                         $nextExpectedElements = 0b10001000000;
                         $aggregates[$depth - 1][$aggregates[$depth]['name']] = $aggregates[$depth][0];
                         unset($aggregates[$depth], $aggregates[$depth + 1]);
                         --$depth;
                         break;
                 }
                 break;
             case \XMLReader::TEXT:
             case \XMLReader::SIGNIFICANT_WHITESPACE:
                 switch ($type) {
                     case 'int':
                     case 'i4':
                     case 'i2':
                     case 'i1':
                         $value = (int) $xml->value;
                         break;
                     case 'boolean':
                         $value = $xml->value === '1';
                         break;
                     case 'double':
                     case 'float':
                     case 'bigdecimal':
                         $value = (double) $xml->value;
                         break;
                     case 'dateTime.iso8601':
                         $value = \DateTime::createFromFormat('Ymd\\TH:i:s', $xml->value, isset($timezone) ? $timezone : ($timezone = new \DateTimeZone('UTC')));
                         break;
                     case 'dateTime':
                         $value = \DateTime::createFromFormat('Y-m-d\\TH:i:s.uP', $xml->value, isset($timezone) ? $timezone : ($timezone = new \DateTimeZone('UTC')));
                         break;
                     case 'base64':
                         $value = Base64Value::deserialize($xml->value);
                         break;
                     case 'dom':
                         $doc = new \DOMDocument('1.0', 'UTF-8');
                         $doc->loadXML($aggregates[$depth + 1]);
                         $value = $doc;
                         break;
                     default:
                         $value =& $xml->value;
                         break;
                 }
                 $aggregates[$depth + 1] = $value;
                 if ($nextExpectedElements === null) {
                     break;
                 }
                 // Next: any
                 $nextExpectedElements = 0b111111111111111111111111111;
                 break;
         }
         if ($xml->isEmptyElement && $nodeType !== \XMLReader::END_ELEMENT) {
             $nodeType = \XMLReader::END_ELEMENT;
             goto processing;
         }
     }
     libxml_use_internal_errors($useErrors);
     $result = $aggregates ? array_pop($aggregates[0]) : null;
     if ($isFault) {
         throw FaultException::createFromResponse($result);
     }
     return $result;
 }