/** * Small wrapper around ZendXml to turn their exceptions into picoFeed * exceptions * @param $input the xml to load * @param $dom pass in a dom document or use null/omit if simpleXml should * be used */ private static function scan($input, $dom = null) { try { return Security::scan($input, $dom); } catch (\ZendXml\Exception\RuntimeException $e) { throw new XmlEntityException($e->getMessage()); } }
/** * Converts XML to JSON. * * Converts an XML formatted string into a JSON formatted string. * * The caller of this function needs to provide only the first parameter, * which is an XML formatted string. * * The second parameter, also optional, allows the user to select if the * XML attributes in the input XML string should be included or ignored * during the conversion. * * This function converts the XML formatted string into a PHP array via a * recursive function; it then converts that array to json via * Json::encode(). * * NOTE: Encoding native javascript expressions via Zend\Json\Expr is not * possible. * * @deprecated by https://github.com/zendframework/zf2/pull/6778 * @param string $xmlStringContents XML String to be converted. * @param bool $ignoreXmlAttributes Include or exclude XML attributes in * the conversion process. * @return string JSON formatted string on success. * @throws Exception\RuntimeException If the input not a XML formatted string. */ public static function fromXml($xmlStringContents, $ignoreXmlAttributes = true) { // Load the XML formatted string into a Simple XML Element object. $simpleXmlElementObject = XmlSecurity::scan($xmlStringContents); // If it is not a valid XML content, throw an exception. if (!$simpleXmlElementObject) { throw new Exception\RuntimeException('Function fromXml was called with invalid XML'); } // Call the recursive function to convert the XML into a PHP array. $resultArray = static::processXml($simpleXmlElementObject, $ignoreXmlAttributes); // Convert the PHP array to JSON using Json::encode. return Json::encode($resultArray); }
/** * Constructor * * @param string $data XML Result * @throws \ZendRest\Client\Exception\ResultException * @return void */ public function __construct($data) { set_error_handler(array($this, 'handleXmlErrors')); $this->_sxml = XmlSecurity::scan($data); restore_error_handler(); if ($this->_sxml === false) { if ($this->_errstr === null) { $message = "An error occured while parsing the REST response with simplexml."; } else { $message = "REST Response Error: " . $this->_errstr; $this->_errstr = null; } throw new Exception\ResultException($message); } }
/** * Create auth adapter * * @param string $rolefile File containing XML with users and roles */ public function __construct($rolefile) { $this->_acl = new Zend_Acl(); $xml = \ZendXml\Security::scanFile($rolefile); /* Roles file format: <roles> <role id=”admin”> <user name=”user1” password=”pwd”/> </role> <role id=”hr”> <user name=”user2” password=”pwd2”/> </role> </roles> */ foreach ($xml->role as $role) { $this->_acl->addRole(new Zend_Acl_Role((string) $role["id"])); foreach ($role->user as $user) { $this->_users[(string) $user["name"]] = array("password" => (string) $user["password"], "role" => (string) $role["id"]); } } }
/** * Extract metadata from document * * @param \ZipArchive $package ZipArchive AbstractOpenXML package * @return array Key-value pairs containing document meta data */ protected function extractMetaData(\ZipArchive $package) { // Data holders $coreProperties = array(); // Read relations and search for core properties $relations = XMLSecurity::Scan($package->getFromName("_rels/.rels")); foreach ($relations->Relationship as $rel) { if ($rel["Type"] == self::SCHEMA_COREPROPERTIES || $rel["Type"] == self::SCHEMA_OFFICE_COREPROPERTIES) { // Found core properties! Read in contents... $contents = XMLSecurity::Scan($package->getFromName(dirname($rel["Target"]) . "/" . basename($rel["Target"]))); foreach ($contents->children(self::SCHEMA_DUBLINCORE) as $child) { $coreProperties[$child->getName()] = (string) $child; } foreach ($contents->children(self::SCHEMA_COREPROPERTIES) as $child) { $coreProperties[$child->getName()] = (string) $child; } foreach ($contents->children(self::SCHEMA_DUBLINCORETERMS) as $child) { $coreProperties[$child->getName()] = (string) $child; } } } return $coreProperties; }
/** * Load a response from an XML response * * Attempts to load a response from an XMLRPC response, autodetecting if it * is a fault response. * * @param string $response * @throws Exception\ValueException if invalid XML * @return bool True if a valid XMLRPC response, false if a fault * response or invalid input */ public function loadXml($response) { if (!is_string($response)) { $this->fault = new Fault(650); $this->fault->setEncoding($this->getEncoding()); return false; } try { $xml = XmlSecurity::scan($response); } catch (\ZendXml\Exception\RuntimeException $e) { $this->fault = new Fault(651); $this->fault->setEncoding($this->getEncoding()); return false; } if (!empty($xml->fault)) { // fault response $this->fault = new Fault(); $this->fault->setEncoding($this->getEncoding()); $this->fault->loadXml($response); return false; } if (empty($xml->params)) { // Invalid response $this->fault = new Fault(652); $this->fault->setEncoding($this->getEncoding()); return false; } try { if (!isset($xml->params) || !isset($xml->params->param) || !isset($xml->params->param->value)) { throw new Exception\ValueException('Missing XML-RPC value in XML'); } $valueXml = $xml->params->param->value->asXML(); $value = AbstractValue::getXmlRpcValue($valueXml, AbstractValue::XML_STRING); } catch (Exception\ValueException $e) { $this->fault = new Fault(653); $this->fault->setEncoding($this->getEncoding()); return false; } $this->setReturnValue($value->getValue()); return true; }
/** * Protected method that queries REST service and returns SimpleXML response set * * @throws Exception\RuntimeException * @param string $service Name of Audioscrobbler service file we're accessing * @param string $params Parameters that we send to the service if needded * @return \SimpleXMLElement Result set */ protected function getInfo($service, $params = null) { $service = (string) $service; $params = (string) $params; if ($params === '') { $this->getHttpClient()->setUri("http://ws.audioscrobbler.com{$service}"); } else { $this->getHttpClient()->setUri("http://ws.audioscrobbler.com{$service}?{$params}"); } $response = $this->getHttpClient()->send(); $responseBody = $response->getBody(); if (strpos($responseBody, 'No such path') !== false) { throw new Exception\RuntimeException('Could not find: ' . $this->getHttpClient()->getUri()); } elseif (strpos($responseBody, 'No user exists with this name') !== false) { throw new Exception\RuntimeException('No user exists with this name'); } elseif (!$response->isSuccess()) { throw new Exception\RuntimeException('The web service ' . $this->getHttpClient()->getUri() . ' returned the following status code: ' . $response->getStatusCode()); } set_error_handler(array($this, 'errorHandler')); $simpleXmlElementResponse = XmlSecurity::scan(str_replace('&', '&', $responseBody)); if (!$simpleXmlElementResponse) { restore_error_handler(); $exception = new Exception\RuntimeException('Response failed to load with SimpleXML'); $exception->error = $this->error; $exception->response = $responseBody; throw $exception; } restore_error_handler(); return $simpleXmlElementResponse; }
/** * Load an XMLRPC fault from XML * * @param string $fault * @return bool Returns true if successfully loaded fault response, false * if response was not a fault response * @throws Exception\ExceptionInterface if no or faulty XML provided, or if fault * response does not contain either code or message */ public function loadXml($fault) { if (!is_string($fault)) { throw new Exception\InvalidArgumentException('Invalid XML provided to fault'); } $xmlErrorsFlag = libxml_use_internal_errors(true); try { $xml = XmlSecurity::scan($fault); } catch (\ZendXml\Exception\RuntimeException $e) { // Unsecure XML throw new Exception\RuntimeException('Failed to parse XML fault: ' . $e->getMessage(), 500, $e); } if (!$xml instanceof SimpleXMLElement) { $errors = libxml_get_errors(); $errors = array_reduce($errors, function ($result, $item) { if (empty($result)) { return $item->message; } return $result . '; ' . $item->message; }, ''); libxml_use_internal_errors($xmlErrorsFlag); throw new Exception\InvalidArgumentException('Failed to parse XML fault: ' . $errors, 500); } libxml_use_internal_errors($xmlErrorsFlag); // Check for fault if (!$xml->fault) { // Not a fault return false; } if (!$xml->fault->value->struct) { // not a proper fault throw new Exception\InvalidArgumentException('Invalid fault structure', 500); } $structXml = $xml->fault->value->asXML(); $struct = AbstractValue::getXmlRpcValue($structXml, AbstractValue::XML_STRING); $struct = $struct->getValue(); if (isset($struct['faultCode'])) { $code = $struct['faultCode']; } if (isset($struct['faultString'])) { $message = $struct['faultString']; } if (empty($code) && empty($message)) { throw new Exception\InvalidArgumentException('Fault code and string required'); } if (empty($code)) { $code = '404'; } if (empty($message)) { if (isset($this->internal[$code])) { $message = $this->internal[$code]; } else { $message = 'Unknown Error'; } } $this->setCode($code); $this->setMessage($message); return true; }
/** * Overwrites standard __wakeup method to make this object unserializable. * * Restores object status before serialization. * Converts XML string into a DomDocument object and creates a valid * DOMXpath instance for given DocDocument. * * @return void */ public function __wakeup() { $dom = new DOMDocument(); $dom = XmlSecurity::scan($this->xml, $dom); $this->init($dom); $this->xml = null; // reset XML content }
/** * Object constructor * * @param string $fileName * @param boolean $storeContent * @throws \ZendSearch\Lucene\Exception\ExtensionNotLoadedException * @throws \ZendSearch\Lucene\Exception\RuntimeException */ private function __construct($fileName, $storeContent) { if (!class_exists('ZipArchive', false)) { throw new ExtensionNotLoadedException('MS Office documents processing functionality requires Zip extension to be loaded'); } // Document data holders $sharedStrings = array(); $worksheets = array(); $documentBody = array(); $coreProperties = array(); // Open AbstractOpenXML package $package = new \ZipArchive(); $package->open($fileName); // Read relations and search for officeDocument $relationsXml = $package->getFromName('_rels/.rels'); if ($relationsXml === false) { throw new RuntimeException('Invalid archive or corrupted .xlsx file.'); } $relations = XmlSecurity::scan($relationsXml); foreach ($relations->Relationship as $rel) { if ($rel["Type"] == AbstractOpenXML::SCHEMA_OFFICEDOCUMENT) { // Found office document! Read relations for workbook... $workbookRelations = XmlSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/_rels/" . basename($rel["Target"]) . ".rels"))); $workbookRelations->registerXPathNamespace("rel", AbstractOpenXML::SCHEMA_RELATIONSHIP); // Read shared strings $sharedStringsPath = $workbookRelations->xpath("rel:Relationship[@Type='" . self::SCHEMA_SHAREDSTRINGS . "']"); $sharedStringsPath = (string) $sharedStringsPath[0]['Target']; $xmlStrings = XmlSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . $sharedStringsPath))); if (isset($xmlStrings) && isset($xmlStrings->si)) { foreach ($xmlStrings->si as $val) { if (isset($val->t)) { $sharedStrings[] = (string) $val->t; } elseif (isset($val->r)) { $sharedStrings[] = $this->_parseRichText($val); } } } // Loop relations for workbook and extract worksheets... foreach ($workbookRelations->Relationship as $workbookRelation) { if ($workbookRelation["Type"] == self::SCHEMA_WORKSHEETRELATION) { $worksheets[str_replace('rId', '', (string) $workbookRelation["Id"])] = XmlSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($workbookRelation["Target"]) . "/" . basename($workbookRelation["Target"])))); } } break; } } // Sort worksheets ksort($worksheets); // Extract contents from worksheets foreach ($worksheets as $sheetKey => $worksheet) { foreach ($worksheet->sheetData->row as $row) { foreach ($row->c as $c) { // Determine data type $dataType = (string) $c["t"]; switch ($dataType) { case "s": // Value is a shared string if ((string) $c->v != '') { $value = $sharedStrings[intval($c->v)]; } else { $value = ''; } break; case "b": // Value is boolean $value = (string) $c->v; if ($value == '0') { $value = false; } elseif ($value == '1') { $value = true; } else { $value = (bool) $c->v; } break; case "inlineStr": // Value is rich text inline $value = $this->_parseRichText($c->is); break; case "e": // Value is an error message if ((string) $c->v != '') { $value = (string) $c->v; } else { $value = ''; } break; default: // Value is a string $value = (string) $c->v; // Check for numeric values if (is_numeric($value) && $dataType != 's') { if ($value == (int) $value) { $value = (int) $value; } elseif ($value == (double) $value) { $value = (double) $value; } elseif ($value == (double) $value) { $value = (double) $value; } } } $documentBody[] = $value; } } } // Read core properties $coreProperties = $this->extractMetaData($package); // Close file $package->close(); // Store filename $this->addField(Field::Text('filename', $fileName, 'UTF-8')); // Store contents if ($storeContent) { $this->addField(Field::Text('body', implode(' ', $documentBody), 'UTF-8')); } else { $this->addField(Field::UnStored('body', implode(' ', $documentBody), 'UTF-8')); } // Store meta data properties foreach ($coreProperties as $key => $value) { $this->addField(Field::Text($key, $value, 'UTF-8')); } // Store title (if not present in meta data) if (!isset($coreProperties['title'])) { $this->addField(Field::Text('title', $fileName, 'UTF-8')); } }
/** * Object constructor * * @param string $fileName * @param boolean $storeContent * @throws \ZendSearch\Lucene\Exception\ExtensionNotLoadedException * @throws \ZendSearch\Lucene\Exception\RuntimeException */ private function __construct($fileName, $storeContent) { if (!class_exists('ZipArchive', false)) { throw new ExtensionNotLoadedException('MS Office documents processing functionality requires Zip extension to be loaded'); } // Document data holders $documentBody = array(); $coreProperties = array(); // Open AbstractOpenXML package $package = new \ZipArchive(); $package->open($fileName); // Read relations and search for officeDocument $relationsXml = $package->getFromName('_rels/.rels'); if ($relationsXml === false) { throw new RuntimeException('Invalid archive or corrupted .docx file.'); } $relations = XMLSecurity::scan($relationsXml); foreach ($relations->Relationship as $rel) { if ($rel["Type"] == AbstractOpenXML::SCHEMA_OFFICEDOCUMENT) { // Found office document! Read in contents... $contents = XMLSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel['Target']) . '/' . basename($rel['Target'])))); $contents->registerXPathNamespace('w', self::SCHEMA_WORDPROCESSINGML); $paragraphs = $contents->xpath('//w:body/w:p'); foreach ($paragraphs as $paragraph) { $runs = $paragraph->xpath('.//w:r/*[name() = "w:t" or name() = "w:br"]'); if ($runs === false) { // Paragraph doesn't contain any text or breaks continue; } foreach ($runs as $run) { if ($run->getName() == 'br') { // Break element $documentBody[] = ' '; } else { $documentBody[] = (string) $run; } } // Add space after each paragraph. So they are not bound together. $documentBody[] = ' '; } break; } } // Read core properties $coreProperties = $this->extractMetaData($package); // Close file $package->close(); // Store filename $this->addField(Field::Text('filename', $fileName, 'UTF-8')); // Store contents if ($storeContent) { $this->addField(Field::Text('body', implode('', $documentBody), 'UTF-8')); } else { $this->addField(Field::UnStored('body', implode('', $documentBody), 'UTF-8')); } // Store meta data properties foreach ($coreProperties as $key => $value) { $this->addField(Field::Text($key, $value, 'UTF-8')); } // Store title (if not present in meta data) if (!isset($coreProperties['title'])) { $this->addField(Field::Text('title', $fileName, 'UTF-8')); } }
function plugin_showrss_get_rss($target, $cachehour = 6, $raw = false) { global $cache; $time = UTIME; $xml = null; $cache_name = PLUGIN_SHOWRSS_CACHE_PREFIX . md5($target); $reason = 'Failed fetching RSS from the server.'; // デフォルトのエラー $recreate = false; if ($cache['raw']->hasItem($cache_name)) { $cache_meta = $cache['raw']->getMetadata($cache_name); $time = $cache_meta['mtime']; // キャッシュの時刻 if (UTIME - $time >= $cachehour * 360) { $cache['raw']->removeItem($cache_name); } } if (!$cache['raw']->hasItem($cache_name)) { // キャッシュが有効期限を過ぎてた場合 try { // file_get_contentsでException飛ばすメモ // https://gist.github.com/mia-0032/4374687 ob_start(); //warningが出るコード $data = file_get_contents($target); $warning = ob_get_contents(); ob_end_clean(); //Warningがあれば例外を投げる if ($warning) { throw new Exception($warning); } } catch (Exception $e) { // ファイルが取得できなかった return array(false, UTIME, $e->getMessage()); } $cache['raw']->setItem($cache_name, $data); } else { $data = $cache['raw']->getItem($cache_name); } // ZendXmlでXMLの XML eXternal Entity (XXE) とXML Entity Expansion (XEE)の脆弱性をついた攻撃を排除 $xml = XmlSecurity::scan($data); if (!$xml instanceof \SimpleXMLElement) { return array(false, UTIME, 'Invalied XML.'); } // 出力 return $raw ? array($xml->asXML(), $time, $reason) : array($xml, $time, null); }
public function testScanXmlWithDTD() { $xml = <<<XML <?xml version="1.0"?> <!DOCTYPE results [ <!ELEMENT results (result+)> <!ELEMENT result (#PCDATA)> ]> <results> <result>test</result> </results> XML; $dom = new DOMDocument('1.0'); $result = XmlSecurity::scan($xml, $dom); $this->assertTrue($result instanceof DOMDocument); $this->assertTrue($result->validate()); }
/** * Convert XML to SimpleXml * If user wants DomDocument they can use dom_import_simplexml * * @return SimpleXml Object */ public function readXmlString() { $string = $this->_stream->readLongUTF(); return \ZendXml\Security::scan($string); //simplexml_load_string($string); }
/** * Object constructor * * @param string $fileName * @param boolean $storeContent * @throws \ZendSearch\Lucene\Exception\ExtensionNotLoadedException * @throws \ZendSearch\Lucene\Exception\RuntimeException */ private function __construct($fileName, $storeContent) { if (!class_exists('ZipArchive', false)) { throw new ExtensionNotLoadedException('MS Office documents processing functionality requires Zip extension to be loaded'); } // Document data holders $slides = array(); $slideNotes = array(); $documentBody = array(); $coreProperties = array(); // Open AbstractOpenXML package $package = new \ZipArchive(); $package->open($fileName); // Read relations and search for officeDocument $relationsXml = $package->getFromName('_rels/.rels'); if ($relationsXml === false) { throw new RuntimeException('Invalid archive or corrupted .pptx file.'); } $relations = XmlSecurity::scan($relationsXml); foreach ($relations->Relationship as $rel) { if ($rel["Type"] == AbstractOpenXML::SCHEMA_OFFICEDOCUMENT) { // Found office document! Search for slides... $slideRelations = XmlSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/_rels/" . basename($rel["Target"]) . ".rels"))); foreach ($slideRelations->Relationship as $slideRel) { if ($slideRel["Type"] == self::SCHEMA_SLIDERELATION) { // Found slide! $slides[str_replace('rId', '', (string) $slideRel["Id"])] = XmlSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($slideRel["Target"]) . "/" . basename($slideRel["Target"])))); // Search for slide notes $slideNotesRelations = XmlSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($slideRel["Target"]) . "/_rels/" . basename($slideRel["Target"]) . ".rels"))); foreach ($slideNotesRelations->Relationship as $slideNoteRel) { if ($slideNoteRel["Type"] == self::SCHEMA_SLIDENOTESRELATION) { // Found slide notes! $slideNotes[str_replace('rId', '', (string) $slideRel["Id"])] = XmlSecurity::scan($package->getFromName($this->absoluteZipPath(dirname($rel["Target"]) . "/" . dirname($slideRel["Target"]) . "/" . dirname($slideNoteRel["Target"]) . "/" . basename($slideNoteRel["Target"])))); break; } } } } break; } } // Sort slides ksort($slides); ksort($slideNotes); // Extract contents from slides foreach ($slides as $slideKey => $slide) { // Register namespaces $slide->registerXPathNamespace("p", self::SCHEMA_PRESENTATIONML); $slide->registerXPathNamespace("a", self::SCHEMA_DRAWINGML); // Fetch all text $textElements = $slide->xpath('//a:t'); foreach ($textElements as $textElement) { $documentBody[] = (string) $textElement; } // Extract contents from slide notes if (isset($slideNotes[$slideKey])) { // Fetch slide note $slideNote = $slideNotes[$slideKey]; // Register namespaces $slideNote->registerXPathNamespace("p", self::SCHEMA_PRESENTATIONML); $slideNote->registerXPathNamespace("a", self::SCHEMA_DRAWINGML); // Fetch all text $textElements = $slideNote->xpath('//a:t'); foreach ($textElements as $textElement) { $documentBody[] = (string) $textElement; } } } // Read core properties $coreProperties = $this->extractMetaData($package); // Close file $package->close(); // Store filename $this->addField(Field::Text('filename', $fileName, 'UTF-8')); // Store contents if ($storeContent) { $this->addField(Field::Text('body', implode(' ', $documentBody), 'UTF-8')); } else { $this->addField(Field::UnStored('body', implode(' ', $documentBody), 'UTF-8')); } // Store meta data properties foreach ($coreProperties as $key => $value) { $this->addField(Field::Text($key, $value, 'UTF-8')); } // Store title (if not present in meta data) if (!isset($coreProperties['title'])) { $this->addField(Field::Text('title', $fileName, 'UTF-8')); } }
/** * Gets the SimpleXML document object for this response * * @return \SimpleXMLElement */ public function getSimpleXMLDocument() { try { $body = $this->_httpResponse->getBody(); } catch (Http\Exception\ExceptionInterface $e) { $body = false; } return XmlSecurity::scan($body); }
/** * fromXml - Converts XML to JSON * * Converts a XML formatted string into a JSON formatted string. * The value returned will be a string in JSON format. * * The caller of this function needs to provide only the first parameter, * which is an XML formatted String. The second parameter is optional, which * lets the user to select if the XML attributes in the input XML string * should be included or ignored in xml2json conversion. * * This function converts the XML formatted string into a PHP array by * calling a recursive (protected static) function in this class. Then, it * converts that PHP array into JSON by calling the "encode" static function. * * NOTE: Encoding native javascript expressions via Zend\Json\Expr is not possible. * * @static * @access public * @param string $xmlStringContents XML String to be converted * @param bool $ignoreXmlAttributes Include or exclude XML attributes in * the xml2json conversion process. * @return mixed - JSON formatted string on success * @throws \Zend\Json\Exception\RuntimeException if the input not a XML formatted string */ public static function fromXml($xmlStringContents, $ignoreXmlAttributes = true) { // Load the XML formatted string into a Simple XML Element object. $simpleXmlElementObject = XmlSecurity::scan($xmlStringContents); // If it is not a valid XML content, throw an exception. if (!$simpleXmlElementObject) { throw new RuntimeException('Function fromXml was called with an invalid XML formatted string.'); } // End of if ($simpleXmlElementObject == null) $resultArray = null; // Call the recursive function to convert the XML into a PHP array. $resultArray = static::_processXml($simpleXmlElementObject, $ignoreXmlAttributes); // Convert the PHP array to JSON using Zend\Json\Json encode method. // It is just that simple. $jsonStringOutput = static::encode($resultArray); return $jsonStringOutput; }
/** * Convert XML to SimpleXml * If user wants DomDocument they can use dom_import_simplexml * * @return SimpleXml Object */ public function readXmlString() { $xmlReference = $this->readInteger(); $length = $xmlReference >> 1; $string = $this->_stream->readBytes($length); return \ZendXml\Security::scan($string); }