Permalink
Browse files

0012178: fix encoder to cope with broken xml characters

* and add test for invalid XML characters

https://forge.tine20.org/view.php?id=12178

Change-Id: I7dab5f0d6528e0dd50e8ed17b6d025845e2dd16a
Reviewed-on: https://gerrit.tine20.org/syncroton/295
Tested-by: jenkins
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
  • Loading branch information...
paulmhh authored and pschuele committed Sep 7, 2016
1 parent 3839ecd commit 688d7963ee9e7f39a653141c77790f9b2ab05206
Showing with 43 additions and 22 deletions.
  1. +1 −0 .gitignore
  2. +17 −22 lib/Syncroton/Wbxml/Encoder.php
  3. +25 −0 tests/Syncroton/Wbxml/EncoderTests.php
@@ -1,6 +1,7 @@
.settings
.project
.buildpath
.idea
/build
/vendor
/tests/junit_log_syncroton.xml
@@ -150,35 +150,30 @@ protected function _writeCharSet($_charSet)
public function encode(DOMDocument $_dom)
{
$_dom->formatOutput = false;
$tempStream = fopen('php://temp/maxmemory:5242880', 'r+');
fwrite($tempStream, $_dom->saveXML());
rewind($tempStream);
$xmlString = preg_replace('/[^\x09\x0A\x0D\x20-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u', '', $_dom->saveXML());
$this->_initialize($_dom);
$parser = xml_parser_create_ns($this->_charSet, ';');
xml_set_object($parser, $this);
xml_set_element_handler($parser, '_handleStartTag', '_handleEndTag');
xml_set_character_data_handler($parser, '_handleCharacters');
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
while (!feof($tempStream)) {
if (!xml_parse($parser, fread($tempStream, 1048576), feof($tempStream))) {
// uncomment to write xml document to file
#rewind($tempStream);
#$xmlStream = fopen(tempnam(sys_get_temp_dir(), "xmlerrors"), 'r+');
#stream_copy_to_stream($tempStream, $xmlStream);
#fclose($xmlStream);
throw new Syncroton_Wbxml_Exception(sprintf('XML error: %s at line %d',
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
}
fclose($tempStream);
if (!xml_parse($parser, $xmlString, true)) {
// uncomment to write xml document to file
#rewind($tempStream);
#$xmlStream = fopen(tempnam(sys_get_temp_dir(), "xmlerrors"), 'r+');
#stream_copy_to_stream($tempStream, $xmlStream);
#fclose($xmlStream);
throw new Syncroton_Wbxml_Exception(sprintf('XML error: %s at line %d',
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)
));
}
xml_parser_free($parser);
}
@@ -324,7 +319,7 @@ protected function _writeTag($_tag, $_attributes=NULL, $_hasContent=false, $_dat
// handle the data
if($_data !== NULL) {
if ($encoding == 'opaque') {
$this->_writeOpaqueString(base64_decode($_data));
$this->_writeOpaqueString(base64_decode($_data));
} else {
$this->_writeTerminatedString($_data);
}
@@ -71,4 +71,29 @@ public function testEncode()
$this->assertEquals(183, ftell($outputStream));
}
public function testEncodeBrokenXML()
{
// Creates an instance of the DOMImplementation class
$imp = new DOMImplementation();
// Creates a DOMDocumentType instance
$dtd = $imp->createDocumentType('AirSync', "-//AIRSYNC//DTD AirSync//EN", "http://www.microsoft.com/");
// Creates a DOMDocument instance
$testDoc = $imp->createDocument('uri:AirSync', 'Sync', $dtd);
$testDoc->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:Syncroton', 'uri:Syncroton');
$testDoc->formatOutput = false;
$testDoc->encoding = 'utf-8';
// chr(0x1F) is not a valid XML char!
$testDoc->getElementsByTagName('Sync')->item(0)->appendChild($testDoc->createTextNode('foo'.chr(0x20).chr(0x1F).'a'));
$testDoc->formatOutput = true;
$outputStream = fopen("php://temp", 'r+');
$encoder = new Syncroton_Wbxml_Encoder($outputStream, 'UTF-8', 3);
$encoder->encode($testDoc);
}
}

0 comments on commit 688d796

Please sign in to comment.