diff --git a/question/format/xml/format.php b/question/format/xml/format.php index b2b71ffd1e5..0e63bdf0471 100644 --- a/question/format/xml/format.php +++ b/question/format/xml/format.php @@ -1196,6 +1196,8 @@ class qformat_xml extends qformat_default { // Check question type. $questiontype = $this->get_qtype($question->qtype); + $idnumber = htmlspecialchars($question->idnumber); + // Categories are a special case. if ($question->qtype == 'category') { $categorypath = $this->writetext($question->category); @@ -1208,7 +1210,7 @@ class qformat_xml extends qformat_default { $expout .= " \n"; $expout .= " {$categoryinfo}"; $expout .= " \n"; - $expout .= " {$question->idnumber}\n"; + $expout .= " {$idnumber}\n"; $expout .= " \n"; return $expout; } @@ -1232,7 +1234,7 @@ class qformat_xml extends qformat_default { } $expout .= " {$question->penalty}\n"; $expout .= " {$question->hidden}\n"; - $expout .= " {$question->idnumber}\n"; + $expout .= " {$idnumber}\n"; // The rest of the output depends on question type. switch($question->qtype) { diff --git a/question/format/xml/tests/fixtures/html_chars_in_idnumbers.xml b/question/format/xml/tests/fixtures/html_chars_in_idnumbers.xml new file mode 100644 index 00000000000..cc1d37676e9 --- /dev/null +++ b/question/format/xml/tests/fixtures/html_chars_in_idnumbers.xml @@ -0,0 +1,43 @@ + + + + + + $course$/Alpha + + + This is Alpha category for test + + The inequalities < & > + + + + + + Alpha Question + + + Testing Alpha Question

]]>
+
+ + + + 1.0000000 + 1.0000000 + 0 + T & F + + true + + + + + + false + + + + +
+ +
diff --git a/question/format/xml/tests/qformat_xml_import_export_test.php b/question/format/xml/tests/qformat_xml_import_export_test.php index 4926bea1040..ebd9fcdc4e6 100644 --- a/question/format/xml/tests/qformat_xml_import_export_test.php +++ b/question/format/xml/tests/qformat_xml_import_export_test.php @@ -426,6 +426,44 @@ class qformat_xml_import_export_test extends advanced_testcase { $this->assert_same_xml($expectedxml, $qformat->exportprocess()); } + /** + * Simple check for exporting a category. + */ + public function test_export_category_with_special_chars() { + $generator = $this->getDataGenerator()->get_plugin_generator('core_question'); + $this->resetAfterTest(true); + $course = $this->getDataGenerator()->create_course(); + $this->setAdminUser(); + // Note while this loads $qformat with all the 'right' data from the xml file, + // the call to setCategory, followed by exportprocess will actually only export data + // from the database (created by the generator). + $qformat = $this->create_qformat('export_category.xml', $course); + + $category = $generator->create_question_category([ + 'name' => 'Alpha', + 'contextid' => '2', + 'info' => 'This is Alpha category for test', + 'infoformat' => '0', + 'idnumber' => 'The inequalities < & >', + 'stamp' => make_unique_id_code(), + 'parent' => '0', + 'sortorder' => '999']); + $generator->create_question('truefalse', null, [ + 'category' => $category->id, + 'name' => 'Alpha Question', + 'questiontext' => ['format' => '1', 'text' => '

Testing Alpha Question

'], + 'generalfeedback' => ['format' => '1', 'text' => ''], + 'idnumber' => 'T & F', + 'correctanswer' => '1', + 'feedbacktrue' => ['format' => '1', 'text' => ''], + 'feedbackfalse' => ['format' => '1', 'text' => ''], + 'penalty' => '1']); + $qformat->setCategory($category); + + $expectedxml = file_get_contents(__DIR__ . '/fixtures/html_chars_in_idnumbers.xml'); + $this->assert_same_xml($expectedxml, $qformat->exportprocess()); + } + /** * Test that bad multianswer questions are not imported. */