Skip to content

Commit

Permalink
MDL-69798 XML question export: excape special chars in idnumbers
Browse files Browse the repository at this point in the history
  • Loading branch information
timhunt committed Oct 1, 2020
1 parent e049d30 commit 3c1416d
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 2 deletions.
6 changes: 4 additions & 2 deletions question/format/xml/format.php
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,8 @@ public function writequestion($question) {
// 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);
Expand All @@ -1208,7 +1210,7 @@ public function writequestion($question) {
$expout .= " <info {$infoformat}>\n";
$expout .= " {$categoryinfo}";
$expout .= " </info>\n";
$expout .= " <idnumber>{$question->idnumber}</idnumber>\n";
$expout .= " <idnumber>{$idnumber}</idnumber>\n";
$expout .= " </question>\n";
return $expout;
}
Expand All @@ -1232,7 +1234,7 @@ public function writequestion($question) {
}
$expout .= " <penalty>{$question->penalty}</penalty>\n";
$expout .= " <hidden>{$question->hidden}</hidden>\n";
$expout .= " <idnumber>{$question->idnumber}</idnumber>\n";
$expout .= " <idnumber>{$idnumber}</idnumber>\n";

// The rest of the output depends on question type.
switch($question->qtype) {
Expand Down
43 changes: 43 additions & 0 deletions question/format/xml/tests/fixtures/html_chars_in_idnumbers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<!-- question: 0 -->
<question type="category">
<category>
<text>$course$/Alpha</text>
</category>
<info format="moodle_auto_format">
<text>This is Alpha category for test</text>
</info>
<idnumber>The inequalities &lt; &amp; &gt;</idnumber>
</question>

<!-- question: 91 -->
<question type="truefalse">
<name>
<text>Alpha Question</text>
</name>
<questiontext format="html">
<text><![CDATA[<p>Testing Alpha Question</p>]]></text>
</questiontext>
<generalfeedback format="html">
<text></text>
</generalfeedback>
<defaultgrade>1.0000000</defaultgrade>
<penalty>1.0000000</penalty>
<hidden>0</hidden>
<idnumber>T &amp; F</idnumber>
<answer fraction="100" format="moodle_auto_format">
<text>true</text>
<feedback format="html">
<text></text>
</feedback>
</answer>
<answer fraction="0" format="moodle_auto_format">
<text>false</text>
<feedback format="html">
<text></text>
</feedback>
</answer>
</question>

</quiz>
38 changes: 38 additions & 0 deletions question/format/xml/tests/qformat_xml_import_export_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,44 @@ public function test_export_nested_categories_with_questions() {
$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' => '<p>Testing Alpha Question</p>'],
'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.
*/
Expand Down

0 comments on commit 3c1416d

Please sign in to comment.