/** * Test scenario for issue #015023: <header level="-1"> generate fatal error taking a lot of server resource * * Test Outline * ------------ * 1. Parse invalid xml using eZSimplifiedXMLInputParser * 2. Make sure we get a valid DOMDocument back with content * 3. Make sure resulting xmlText string matches a valid type * * @result: Error will be thrown in parser * @expected: level should be corrected to level 1 resulting in one section tag * @link http://issues.ez.no/015023 */ public function testInvalidHeaderLevel() { $parser = new eZSimplifiedXMLInputParser(2, eZXMLInputParser::ERROR_ALL, eZXMLInputParser::ERROR_ALL, true); $document = $parser->process('<header level="-1">Fatal error test</header>'); $this->assertTrue($document instanceof DOMDocument, 'Parser error: ' . join(", ", $parser->getMessages())); $root = $document->documentElement; $this->assertTrue($root->hasChildNodes(), 'Content missing, xml document is empty'); $xmlString = eZXMLTextType::domString($document); $this->assertEquals('<?xml version="1.0" encoding="utf-8"?> <section xmlns:image="http://ez.no/namespaces/ezpublish3/image/" xmlns:xhtml="http://ez.no/namespaces/ezpublish3/xhtml/" xmlns:custom="http://ez.no/namespaces/ezpublish3/custom/"><section><header>Fatal error test</header></section></section> ', $xmlString); }
function validateInput($http, $base, $contentObjectAttribute) { $contentObjectID = $contentObjectAttribute->attribute('contentobject_id'); $contentObjectAttributeID = $contentObjectAttribute->attribute('id'); $contentObjectAttributeVersion = $contentObjectAttribute->attribute('version'); if ($http->hasPostVariable($base . '_data_text_' . $contentObjectAttributeID)) { $data = $http->postVariable($base . '_data_text_' . $contentObjectAttributeID); // Set original input to a global variable $originalInput = 'originalInput_' . $contentObjectAttributeID; $GLOBALS[$originalInput] = $data; // Set input valid true to a global variable $isInputValid = 'isInputValid_' . $contentObjectAttributeID; $GLOBALS[$isInputValid] = true; $text = $data; $text = preg_replace('/\\r/', '', $text); $text = preg_replace('/\\t/', ' ', $text); // first empty paragraph $text = preg_replace('/^\\n/', '<p></p>', $text); eZDebugSetting::writeDebug('kernel-datatype-ezxmltext', $text, 'eZSimplifiedXMLInput::validateInput text'); $parser = new eZSimplifiedXMLInputParser($contentObjectID, true, eZXMLInputParser::ERROR_ALL, true); $document = $parser->process($text); if (!is_object($document)) { $GLOBALS[$isInputValid] = false; $errorMessage = implode(' ', $parser->getMessages()); $contentObjectAttribute->setValidationError($errorMessage); return eZInputValidator::STATE_INVALID; } if ($contentObjectAttribute->validateIsRequired()) { $root = $document->documentElement; if (!$root->hasChildNodes()) { $contentObjectAttribute->setValidationError(ezpI18n::tr('kernel/classes/datatypes', 'Content required')); return eZInputValidator::STATE_INVALID; } } $contentObjectAttribute->setValidationLog($parser->getMessages()); $xmlString = eZXMLTextType::domString($document); $urlIDArray = $parser->getUrlIDArray(); if (count($urlIDArray) > 0) { $this->updateUrlObjectLinks($contentObjectAttribute, $urlIDArray); } $contentObject = $contentObjectAttribute->attribute('object'); $contentObject->appendInputRelationList($parser->getRelatedObjectIDArray(), eZContentObject::RELATION_EMBED); $contentObject->appendInputRelationList($parser->getLinkedObjectIDArray(), eZContentObject::RELATION_LINK); $contentObjectAttribute->setAttribute('data_text', $xmlString); return eZInputValidator::STATE_ACCEPTED; } return eZInputValidator::STATE_ACCEPTED; }
/** * validateInput * Validates and parses input using {@link eZOEInputParser::process} * and saves data if valid. * * @param eZHTTPTool $http * @param string $base * @param eZContentObjectAttribute $contentObjectAttribute * @return int signals if status is valid or not */ function validateInput( $http, $base, $contentObjectAttribute ) { if ( !$this->isEditorEnabled() ) { $aliasedHandler = $this->attribute( 'aliased_handler' ); return $aliasedHandler->validateInput( $http, $base, $contentObjectAttribute ); } if ( $http->hasPostVariable( $base . '_data_text_' . $contentObjectAttribute->attribute( 'id' ) ) ) { $text = $http->postVariable( $base . '_data_text_' . $contentObjectAttribute->attribute( 'id' ) ); if ( self::browserSupportsDHTMLType() === 'Trident' ) // IE { $text = str_replace( "\t", '', $text); } eZDebugSetting::writeDebug( 'kernel-datatype-ezxmltext-ezoe', $text, __METHOD__ . ' html from client' ); $parser = new eZOEInputParser(); $document = $parser->process( $text ); // Remove last empty paragraph (added in the output part) $parent = $document->documentElement; $lastChild = $parent->lastChild; while( $lastChild && $lastChild->nodeName !== 'paragraph' ) { $parent = $lastChild; $lastChild = $parent->lastChild; } if ( $lastChild && $lastChild->nodeName === 'paragraph' ) { $textChild = $lastChild->lastChild; // $textChild->textContent == " " : string(2) whitespace in Opera if ( !$textChild || ( $lastChild->childNodes->length == 1 && $textChild->nodeType == XML_TEXT_NODE && ( $textChild->textContent == " " || $textChild->textContent == ' ' || $textChild->textContent == '' || $textChild->textContent == ' ' ) ) ) { $parent->removeChild( $lastChild ); } } $oeini = eZINI::instance( 'ezoe.ini' ); $validationParameters = $contentObjectAttribute->validationParameters(); if ( !( isset( $validationParameters['skip-isRequired'] ) && $validationParameters['skip-isRequired'] === true ) && $parser->getDeletedEmbedIDArray( $oeini->variable('EditorSettings', 'ValidateEmbedObjects' ) === 'enabled' ) ) { self::$showEmbedValidationErrors = true; $contentObjectAttribute->setValidationError( ezpI18n::tr( 'design/standard/ezoe/handler', 'Some objects used in embed(-inline) tags have been deleted and are no longer available.' ) ); return eZInputValidator::STATE_INVALID; } if ( $contentObjectAttribute->validateIsRequired() ) { $root = $document->documentElement; if ( $root->childNodes->length == 0 ) { $contentObjectAttribute->setValidationError( ezpI18n::tr( 'kernel/classes/datatypes', 'Content required' ) ); return eZInputValidator::STATE_INVALID; } } // Update URL-object links $urlIDArray = $parser->getUrlIDArray(); if ( !empty( $urlIDArray ) ) { self::updateUrlObjectLinks( $contentObjectAttribute, $urlIDArray ); } $contentObject = $contentObjectAttribute->attribute( 'object' ); $contentObject->appendInputRelationList( $parser->getEmbeddedObjectIDArray(), eZContentObject::RELATION_EMBED ); $contentObject->appendInputRelationList( $parser->getLinkedObjectIDArray(), eZContentObject::RELATION_LINK ); $xmlString = eZXMLTextType::domString( $document ); eZDebugSetting::writeDebug( 'kernel-datatype-ezxmltext-ezoe', $xmlString, __METHOD__ . ' generated xml' ); $contentObjectAttribute->setAttribute( 'data_text', $xmlString ); $contentObjectAttribute->setValidationLog( $parser->Messages ); return eZInputValidator::STATE_ACCEPTED; } else { return eZInputValidator::STATE_ACCEPTED; } }
function setEZXMLAttribute($attribute, $attributeValue, $link = false) { $contentObjectID = $attribute->attribute("contentobject_id"); $parser = new eZSimplifiedXMLInputParser($contentObjectID, false, 0, false); $attributeValue = str_replace("\r", '', $attributeValue); $attributeValue = str_replace("\n", '', $attributeValue); $attributeValue = str_replace("\t", ' ', $attributeValue); $document = $parser->process($attributeValue); if (!is_object($document)) { $cli = eZCLI::instance(); $cli->output('Error in xml parsing'); return; } $domString = eZXMLTextType::domString($document); $attribute->setAttribute('data_text', $domString); $attribute->store(); }
$xmlString = $xmlField['data_text']; if (trim($xmlString) === '') { continue; } $doc = new DOMDocument('1.0', 'utf-8'); $success = $doc->loadXML($xmlString); if ($success) { $modificationList = array(); if (!$skipEmbedAlign) { convertEmbedAlign($doc, $modificationList); } if (!$skipCustomAlign) { convertCustomAlign($doc, $xmlString, $customAlignAttribute, $customAlignTagList, $modificationList); } if ($modificationList) { $xmlText = eZXMLTextType::domString($doc); if ($db->bindingType() !== eZDBInterface::BINDING_NO) { $xmlText = $db->bindVariable($xmlText, array('name' => 'data_text')); } else { $xmlText = "'" . $db->escapeString($xmlText) . "'"; } $db->query("UPDATE ezcontentobject_attribute SET data_text={$xmlText} " . "WHERE id=" . $xmlField['id'] . " AND version=" . $xmlField['version']); if (!$isQuiet) { if ($extraVerbosOutput) { $cli->notice('Tag(s) have been converted on object id: ' . $xmlField['contentobject_id'] . ', version: ' . $xmlField['version'] . ', attribute id:' . $xmlField['id'] . ', changes: ' . var_export($modificationList, true)); } else { $cli->notice('Tag(s) have been converted on object id: ' . $xmlField['contentobject_id'] . ', version: ' . $xmlField['version'] . ', attribute id:' . $xmlField['id']); } } $totalAttrCount++; }
function batchInitializeObjectAttributeData($classAttribute) { $parser = new eZXMLInputParser(); $doc = $parser->createRootNode(); $xmlText = eZXMLTextType::domString($doc); $db = eZDB::instance(); $xmlText = "'" . $db->escapeString($xmlText) . "'"; return array('data_text' => $xmlText); }
function processEditActions(&$validation, $params) { $http = eZHTTPTool::instance(); if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Text') && $http->postVariable('SurveyQuestion_' . $this->ID . '_Text') != $this->Text) { $inputXML = $http->postVariable('SurveyQuestion_' . $this->ID . '_Text'); $xmlData = "<section xmlns:image='http://ez.no/namespaces/ezpublish3/image/' xmlns:xhtml='http://ez.no/namespaces/ezpublish3/xhtml/' xmlns:custom='http://ez.no/namespaces/ezpublish3/custom/' >"; $xmlData .= "<paragraph>"; $xmlData .= $inputXML; $xmlData .= "</paragraph>"; $xmlData .= "</section>"; $xmlObject = new eZXMLText($inputXML, null); $inputHandler = $xmlObject->attribute('input'); $data =& $inputHandler->convertInput($xmlData); $domString =& eZXMLTextType::domString($data[0]); $domString = preg_replace("#<paragraph> </paragraph>#", "<paragraph> </paragraph>", $domString); $domString = str_replace("<paragraph />", "", $domString); $domString = str_replace("<line />", "", $domString); $domString = str_replace("<paragraph></paragraph>", "", $domString); $domString = preg_replace("#<paragraph> </paragraph>#", "<paragraph />", $domString); $domString = preg_replace("#<paragraph></paragraph>#", "", $domString); $domString = preg_replace("#[\n]+#", "", $domString); $domString = preg_replace("#</line>#", "\n", $domString); $domString = preg_replace("#<paragraph>#", "\n\n", $domString); $xml = new eZXML(); $tmpDom = $xml->domTree($domString, array('CharsetConversion' => false)); $domString = eZXMLTextType::domString($tmpDom); $this->setAttribute('text', $domString); } if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Text2') && $http->postVariable('SurveyQuestion_' . $this->ID . '_Text2') != $this->Text2) { $this->setAttribute('text2', $http->postVariable('SurveyQuestion_' . $this->ID . '_Text2')); } if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Text3') && $http->postVariable('SurveyQuestion_' . $this->ID . '_Text3') != $this->Text3) { $this->setAttribute('text3', $http->postVariable('SurveyQuestion_' . $this->ID . '_Text3')); } if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Num') && $http->postVariable('SurveyQuestion_' . $this->ID . '_Num') != $this->Num) { $this->setAttribute('num', $http->postVariable('SurveyQuestion_' . $this->ID . '_Num')); } if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Num2') && $http->postVariable('SurveyQuestion_' . $this->ID . '_Num2') != $this->Num2) { $this->setAttribute('num2', $http->postVariable('SurveyQuestion_' . $this->ID . '_Num2')); } if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Mandatory_Hidden')) { if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Mandatory')) { $newMandatory = 1; } else { $newMandatory = 0; } if ($newMandatory != $this->Mandatory) { $this->setAttribute('mandatory', $newMandatory); } } if ($http->hasPostVariable('SurveyQuestion_' . $this->ID . '_Default') && $http->postVariable('SurveyQuestion_' . $this->ID . '_Default') != $this->Default) { $this->setAttribute('default_value', $http->postVariable('SurveyQuestion_' . $this->ID . '_Default')); } }
private function processXmlTextData($xml, $attribute) { $parser = new eZSimplifiedXMLInputParser($this->object->attribute('id')); $parser->ParseLineBreaks = true; $xml = $parser->process($xml); $xml = eZXMLTextType::domString($xml); $urlIdArray = $parser->getUrlIDArray(); if (count($urlIdArray) > 0) { eZSimplifiedXMLInput::updateUrlObjectLinks($attribute, $urlIdArray); } return $xml; }
throw new InvalidArgumentException($attr->validationError()); } case 'ezboolean': $attr->setAttribute('data_int', (int) $postVar); $attr->store(); break; case 'ezimage': // validation has been done by eZContentUpload $content = $attr->attribute('content'); $content->setAttribute('alternative_text', $postVar); $content->store($attr); break; case 'ezxmltext': $parser = new eZOEInputParser(); $document = $parser->process($postVar); $xmlString = eZXMLTextType::domString($document); $attr->setAttribute('data_text', $xmlString); $attr->store(); break; } } } $operationResult = eZOperationHandler::execute('content', 'publish', array('object_id' => $newObjectID, 'version' => $uploadVersion->attribute('version'))); $newObject = eZContentObject::fetch($newObjectID); $newObjectName = $newObject->attribute('name'); $newObjectNodeID = (int) $newObject->attribute('main_node_id'); $object->addContentObjectRelation($newObjectID, $uploadVersion->attribute('version'), 0, eZContentObject::RELATION_EMBED); echo '<html><head><title>HiddenUploadFrame</title><script type="text/javascript">'; echo 'window.parent.eZOEPopupUtils.selectByEmbedId( ' . $newObjectID . ', ' . $newObjectNodeID . ', ' . json_encode($newObjectName) . ' );'; echo '</script></head><body></body></html>'; } catch (InvalidArgumentException $e) {
/** * Returns eZXML content to insert into XML blocks (ezxmltext datatype) * eZXML is generated from HTML content provided as argument * @param string $htmlContent Input HTML string * @return string Generated eZXML string */ public static function getRichContent($htmlContent) { $htmlParser = new SQLIXMLInputParser(); $htmlParser->setParseLineBreaks(true); $document = $htmlParser->process($htmlContent); $richContent = eZXMLTextType::domString($document); return $richContent; }
/** * Convert input to XML format used by eZ for article ingress and body * @param String $content * @return String */ protected function xmlConvert($content) { $parser = new eZSimplifiedXMLInputParser(); $parser->setParseLineBreaks(true); $document = $parser->process($content); return eZXMLTextType::domString($document); }
private function createContentObject($classIdentifier, $parentNodeId, $fillMode) { $contentClass = eZContentClass::fetchByIdentifier($classIdentifier); if (!$contentClass) { throw new Exception("This content class does not exist: [" . $classIdentifier . "]"); } if (!eepValidate::validateContentNodeId($parentNodeId)) { throw new Exception("This is not an node id: [" . $parentNodeId . "]"); } // todo, in addition to "random" mode, datamap content should be // pullable from a suitable xml file; might also provide a way to dump // the framework for a content class "as xml" if ("random" == $fillMode) { $classId = eZContentClass::classIDByIdentifier($classIdentifier); $attributeList = eZContentClassAttribute::fetchListByClassID($classId); $words = explode(" ", self::fake_text); $dataSet = array(); foreach ($attributeList as $attr) { switch ($attr->DataTypeString) { default: case "ezmedia": echo "NOT YET SUPPORTED: [" . $attr->DataTypeString . "]\n"; $dataSet[$attr->Identifier] = "123"; break; case "ezkeyword": $randomKeys = array_flip(array_rand($words, 2)); $randomWords = array_intersect_key($words, $randomKeys); $dataSet[$attr->Identifier] = implode(",", $randomWords); break; case "ezstring": $randomKeys = array_flip(array_rand($words, 5)); $randomWords = array_intersect_key($words, $randomKeys); $dataSet[$attr->Identifier] = implode(" ", $randomWords); break; case "eztext": $randomKeys = array_flip(array_rand($words, 100)); $randomWords = array_intersect_key($words, $randomKeys); $dataSet[$attr->Identifier] = implode(" ", $randomWords); break; case "ezdatetime": $dataSet[$attr->Identifier] = time(); break; case "ezxmltext": $text = ""; for ($paraCount = 0; $paraCount < 5; $paraCount += 1) { $randomKeys = array_flip(array_rand($words, 60)); $randomWords = array_intersect_key($words, $randomKeys); $text .= "<p>" . implode(" ", $randomWords) . "</p>"; } $parser = new eZOEInputParser(); $document = $parser->process($text); $dataSet[$attr->Identifier] = eZXMLTextType::domString($document); break; } } $createResults = $this->create($parentNodeId, $classIdentifier, $dataSet); //echo "\nobject creation results\n"; //var_dump( $createResults ); } else { throw new Exception("Only 'random' is currently supported."); } }
/** * Set content object attributes * * @private * @param eZContentObject $object * @param array( attributeIdentifier => attributeStringValue ) $attributesValues * @return void */ private function setObjectAttributes(eZContentObject $object, array $attributesValues) { $attributes = $object->dataMap(); foreach ($attributesValues as $identifier => $value) { if (isset($attributes[$identifier])) { $attribute = $attributes[$identifier]; switch ($attribute->attribute('data_type_string')) { case 'ezimage': $arr = explode('|', trim($value)); $source = str_replace(' ', '%20', $arr[0]); if (file_exists($source)) { // Handle local files $content = $attribute->attribute('content'); $content->initializeFromFile($source, isset($arr[1]) ? $arr[1] : null); $content->store($attribute); } else { // Handle remote files $filename = 'var/cache/' . md5(microtime()) . substr($source, strrpos($source, '.')); if (!empty($source)) { if (in_array('curl', get_loaded_extensions())) { $ch = curl_init(); $out = fopen($filename, 'w'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_URL, $source); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FILE, $out); curl_exec($ch); curl_close($ch); fclose($out); } else { copy($source, $filename); } } if (file_exists($filename)) { $content = $attribute->attribute('content'); $content->initializeFromFile($filename, isset($arr[1]) ? $arr[1] : null); $content->store($attribute); unlink($filename); } } break; case 'ezxmltext': $parser = new eZOEInputParser(); $value = '<div>' . trim($value) . '</div>'; $document = $parser->process($value); $urlIDArray = $parser->getUrlIDArray(); if (count($urlIDArray) > 0) { eZOEXMLInput::updateUrlObjectLinks($attribute, $urlIDArray); } $object->appendInputRelationList($parser->getLinkedObjectIDArray(), eZContentObject::RELATION_LINK); $object->appendInputRelationList($parser->getEmbeddedObjectIDArray(), eZContentObject::RELATION_EMBED); $value = $document ? eZXMLTextType::domString($document) : null; $attribute->fromString($value); break; default: if (is_callable(array($attribute, 'fromString'))) { $attribute->fromString($value); } else { $attribute->setAttribute('data_text', $value); } } $attribute->store(); } } }