From 23f0859a9c31b9781f84f9c792a541fc080f3166 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Mon, 1 Mar 2021 21:47:01 +0000 Subject: [PATCH] MDL-71016 gradeexport_xml: ensure user/grade idnumbers are encoded. --- grade/export/xml/grade_export_xml.php | 16 ++++++++++++++-- grade/export/xml/tests/behat/export.feature | 18 +++++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/grade/export/xml/grade_export_xml.php b/grade/export/xml/grade_export_xml.php index 659fa6bca4f7e..c0789196f9748 100644 --- a/grade/export/xml/grade_export_xml.php +++ b/grade/export/xml/grade_export_xml.php @@ -23,6 +23,16 @@ class grade_export_xml extends grade_export { public $plugin = 'xml'; public $updatedgradesonly = false; // default to export ALL grades + /** + * Ensure we produce correctly formed XML content by encoding idnumbers appropriately + * + * @param string $idnumber + * @return string + */ + private static function xml_export_idnumber(string $idnumber): string { + return htmlspecialchars($idnumber, ENT_QUOTES | ENT_XML1); + } + /** * To be implemented by child classes * @param boolean $feedback @@ -84,9 +94,11 @@ public function print_grades($feedback = false) { } // only need id number - fwrite($handle, "\t\t{$grade_item->idnumber}\n"); + $gradeitemidnumber = self::xml_export_idnumber($grade_item->idnumber); + fwrite($handle, "\t\t{$gradeitemidnumber}\n"); // this column should be customizable to use either student id, idnumber, uesrname or email. - fwrite($handle, "\t\t{$user->idnumber}\n"); + $useridnumber = self::xml_export_idnumber($user->idnumber); + fwrite($handle, "\t\t{$useridnumber}\n"); // Format and display the grade in the selected display type (real, letter, percentage). if (is_array($this->displaytype)) { // Grades display type came from the return of export_bulk_export_data() on grade publishing. diff --git a/grade/export/xml/tests/behat/export.feature b/grade/export/xml/tests/behat/export.feature index 38f6d78b42f3d..c9515c8af17ca 100644 --- a/grade/export/xml/tests/behat/export.feature +++ b/grade/export/xml/tests/behat/export.feature @@ -12,10 +12,12 @@ Feature: I need to export grades as xml | username | firstname | lastname | email | idnumber | | teacher1 | Teacher | 1 | teacher1@example.com | t1 | | student1 | Student | 1 | student1@example.com | s1 | + | student2 | Student | 2 | student2@example.com | 'Bill'&"Ben"Hello | And the following "course enrolments" exist: | user | course | role | | teacher1 | C1 | editingteacher | | student1 | C1 | student | + | student2 | C1 | student | And the following "activities" exist: | activity | course | idnumber | name | intro | | assign | C1 | a1 | Test assignment name | Submit something! | @@ -24,15 +26,21 @@ Feature: I need to export grades as xml And I navigate to "View > Grader report" in the course gradebook And I turn editing mode on And I give the grade "80.00" to the user "Student 1" for the grade item "Test assignment name" + And I give the grade "42.00" to the user "Student 2" for the grade item "Test assignment name" And I press "Save changes" @javascript - Scenario: Export grades as text + Scenario: Export grades as XML When I navigate to "Export > XML file" in the course gradebook And I expand all fieldsets And I set the field "Grade export decimal places" to "1" And I press "Download" - Then I should see "s1" - And I should see "a1" - And I should see "80.0" - And I should not see "80.00" + Then I should see "s1" in the "//results//result[1]//student" "xpath_element" + And I should see "a1" in the "//results//result[1]//assignment" "xpath_element" + And I should see "80.0" in the "//results//result[1]//score" "xpath_element" + And I should not see "80.00" in the "//results//result[1]//score" "xpath_element" + # Ensure we have the encoded ID number of student 2. + And I should see "'Bill'&\"Ben\"Hello" in the "//results//result[2]//student" "xpath_element" + And I should see "a1" in the "//results//result[2]//assignment" "xpath_element" + And I should see "42.0" in the "//results//result[2]//score" "xpath_element" + And I should not see "42.00" in the "//results//result[2]//score" "xpath_element"