Skip to content

Commit

Permalink
Fix EZP-26096: Custom tags' text line parameters not saved correctly (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
dpobel authored Jul 28, 2016
1 parent 3929217 commit fc28f80
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 1 deletion.
30 changes: 30 additions & 0 deletions extension/ezoe/tests/ezoexmltext_regression.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@

class eZOEXMLTextRegression extends ezpDatabaseTestCase
{
/**
* Test for EZP-26096
* @link https://jira.ez.no/browse/EZP-26096
* @dataProvider providerParsingGreaterThanAttribute
*/
public function testParsingGreaterThanAttribute( $html, $expectedXml )
{
$parser = new eZOEInputParser();
$dom = $parser->process( $html );

self::assertInstanceOf( 'DomDocument', $dom );
self::assertEquals( $expectedXml, trim( $dom->saveXML() ) );
}

public function providerParsingGreaterThanAttribute()
{
return array(
array(
'<div type="custom" class="ezoeItemCustomTag factbox" customattributes="title|This > is > a > fact > attribute_separationalign|right"><p>This is a fact</p></div>',
'<?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/"><paragraph xmlns:tmp="http://ez.no/namespaces/ezpublish3/temporary/"><custom name="factbox" custom:title="This &gt; is &gt; a &gt; fact &gt; "><paragraph>This is a fact</paragraph></custom></paragraph></section>',
),
array(
'<div type="custom" class="ezoeItemCustomTag factbox" customattributes="title|<a href=&quot;#test&quot;>Test</a>attribute_separationalign|right"><p>This is a fact</p></div>',
'<?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/"><paragraph xmlns:tmp="http://ez.no/namespaces/ezpublish3/temporary/"><custom name="factbox" custom:title="&lt;a href=&amp;quot;#test&amp;quot;&gt;Test&lt;/a&gt;"><paragraph>This is a fact</paragraph></custom></paragraph></section>',
)
);
}

/**
* Test for issue #16605: Online Editor adds a lot of Non Breaking spaces (nbsp)
*
Expand Down
55 changes: 54 additions & 1 deletion kernel/classes/datatypes/ezxmltext/ezxmlinputparser.php
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ function parseTag( &$data, &$pos, &$parent )
// Regular tag: get tag's name and attributes.
else
{
$tagEndPos = strpos( $data, '>', $tagBeginPos );
$tagEndPos = $this->findEndOpeningTagPosition( $data, $tagBeginPos );
if ( $tagEndPos === false )
{
$pos = $tagBeginPos + 1;
Expand Down Expand Up @@ -583,6 +583,59 @@ function parseTag( &$data, &$pos, &$parent )
Helper functions for pass 1
*/

/**
* Finds the postion of the > character which marks the end of the opening
* tag that starts at $tagBeginPos in $data.
* It's not as easy as it seems, because some '>' can also appear in attributes.
* So we need to iterate over the next '>' characters to find the correct one.
* See https://jira.ez.no/browse/EZP-26096
*
* @param string $data
* @param integer $tagBeginPos
* @param integer $offset used for recursive call when a > is found in an attribute.
* @return integer|false
*/
private function findEndOpeningTagPosition( $data, $tagBeginPos, $offset = 0 )
{
$endPos = strpos( $data, '>', $tagBeginPos + $offset );
if ( $endPos === false )
{
return false;
}
$tagCode = substr( $data, $tagBeginPos, $endPos - $tagBeginPos );
if ( strpos( $tagCode, '=' ) === false )
{
// this tag has no attribute, so the next '>' is the right one.
return $endPos;
}
if ( $this->isValidXmlTag( $tagCode ) )
{
return $endPos;
}
return $this->findEndOpeningTagPosition( $data, $tagBeginPos, $endPos + 1 );
}

/**
* Checks whether $code can be considered as a valid XML excerpt. If not,
* it's probably because we found a '>' in the middle of an attribute.
*
* @param string $code
* @return boolean
*/
private function isValidXmlTag( $code )
{
if ( $code[strlen( $code ) - 1] !== '/' )
{
$code .= '/';
}
$code .= '>';
$code = '<' . str_replace( '<', '&lt;', substr( $code, 1 ) );
$errorHanding = libxml_use_internal_errors( true );
$simpleXml = simplexml_load_string( $code );
libxml_use_internal_errors( $errorHanding );
return ( $simpleXml !== false );
}

function parseAttributes( $attributeString )
{
$attributes = array();
Expand Down

0 comments on commit fc28f80

Please sign in to comment.