diff --git a/lang/en_utf8/error.php b/lang/en_utf8/error.php index cca5596c2f..697eb667e4 100644 --- a/lang/en_utf8/error.php +++ b/lang/en_utf8/error.php @@ -41,6 +41,7 @@ $string['errorreadingfile'] = 'Error reading file \"$a\"'; $string['errorsavingrequest'] = 'An error occurred when trying to save your request.'; $string['errorunzippingfiles'] = 'Error unzipping files'; +$string['errorxmlfile'] = 'Incorrect xml file ($a->errorstring, line $a->errorline, character $a->errorchar)'; $string['fieldrequired'] = '\"$a\" is a required field'; $string['filenotfound'] = 'Sorry, the requested file could not be found'; $string['forumblockingtoomanyposts'] = 'You have exceeded the posting threshold set for this forum'; diff --git a/lib/xmlize.php b/lib/xmlize.php index 5a9a8ad679..100faeea86 100644 --- a/lib/xmlize.php +++ b/lib/xmlize.php @@ -1,4 +1,20 @@ errorstring = $errorstring; + $errorinfo->errorline = $errorline; + $errorinfo->errorchar = $errorchar; + parent::__construct('errorxmlfile', 'error', '', $errorinfo); + } +} /** * xmlize.php - xmlize() is by Hans Anderson, {@link http://www.hansanderson.com/contact/} @@ -41,16 +57,28 @@ * @param array $data The array to be converted * @param int $WHITE If set to 1 allows the parser to skip "space" characters in xml document. Default is 1 * @param string $encoding Specify an OUTPUT encoding. If not specified, it defaults to UTF-8. + * @param bool $error if set on true it checks whether xml-file is well-formed and throw an exception when xml is not well-formed, * @return array */ -function xmlize($data, $WHITE=1, $encoding='UTF-8') { +function xmlize($data, $WHITE=1, $encoding='UTF-8', $error=false) { $data = trim($data); $vals = $index = $array = array(); $parser = xml_parser_create($encoding); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, $WHITE); - xml_parse_into_struct($parser, $data, $vals, $index); + xml_parse_into_struct($parser, $data, &$vals, &$index); + + // Error handling when the xml file is not well-formed + if ($error) { + $errorcode = xml_get_error_code($parser); + if ($errorcode) { + $errorstring = xml_error_string($errorcode); + $errorline = xml_get_current_line_number($parser); + $errorchar = xml_get_current_column_number($parser); + throw new xml_format_exception($errorstring, $errorline, $errorchar); + } + } xml_parser_free($parser); $i = 0; diff --git a/question/format.php b/question/format.php index eb90857cf3..410b275431 100644 --- a/question/format.php +++ b/question/format.php @@ -242,6 +242,9 @@ function importprocess() { } if (! $questions = $this->readquestions($lines)) { // Extract all the questions + if (!is_array($questions)) { + return false; + } notify( get_string('noquestionsinfile','quiz') ); return false; } diff --git a/question/format/xml/format.php b/question/format/xml/format.php index b179fa1bfb..86f03d83f4 100755 --- a/question/format/xml/format.php +++ b/question/format/xml/format.php @@ -652,8 +652,12 @@ function readquestions($lines) { // This converts xml to big nasty data structure // the 0 means keep white space as it is (important for markdown format) - $xml = xmlize($text, 0); - + try { + $xml = xmlize($text, 0, 'UTF-8', true); + } catch (xml_format_exception $e){ + $this->error ($e->getMessage(), ''); + return false; + } // Set up array to hold all our questions $questions = array();