From a81847e9b4ae8f72a81a51bee53a0e6df99e6f58 Mon Sep 17 00:00:00 2001
From: uzairr <uzairr@yahoo.com>
Date: Tue, 4 Feb 2020 01:54:42 +0500
Subject: [PATCH] avoid-escape-exception

---
 lti_consumer/outcomes.py                 |  5 +++--
 lti_consumer/tests/unit/test_outcomes.py | 14 ++++++++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/lti_consumer/outcomes.py b/lti_consumer/outcomes.py
index 88c804b..049742a 100644
--- a/lti_consumer/outcomes.py
+++ b/lti_consumer/outcomes.py
@@ -162,15 +162,16 @@ class OutcomeService(object):  # pylint: disable=bad-option-value, useless-objec
             'imsx_messageIdentifier': 'unknown',
             'response': ''
         }
+        request_body = request.body.decode('utf-8')
 
         if not self.xblock.accept_grades_past_due and self.xblock.is_past_due:
             failure_values['imsx_description'] = "Grade is past due"
             return response_xml_template.format(**failure_values)
 
         try:
-            imsx_message_identifier, sourced_id, score, action = parse_grade_xml_body(request.body)
+            imsx_message_identifier, sourced_id, score, action = parse_grade_xml_body(request_body)
         except LtiError as ex:  # pylint: disable=no-member
-            body = escape(request.body) if request.body else ''
+            body = escape(request_body) if request_body else ''
             error_message = "Request body XML parsing error: {} {}".format(str(ex), body)
             log.debug("[LTI]: %s", error_message)
             failure_values['imsx_description'] = error_message
diff --git a/lti_consumer/tests/unit/test_outcomes.py b/lti_consumer/tests/unit/test_outcomes.py
index 1ebb538..56dd099 100644
--- a/lti_consumer/tests/unit/test_outcomes.py
+++ b/lti_consumer/tests/unit/test_outcomes.py
@@ -370,6 +370,20 @@ class TestOutcomeService(TestLtiConsumerXBlock):
         self.assertIn('failure', response)
         self.assertIn('Grade is past due', response)
 
+    @patch('lti_consumer.outcomes.parse_grade_xml_body')
+    def test_lti_error_not_raises_type_error(self, mock_parse):
+        """
+        Test XML parsing LtiError exception doesn't raise TypeError exception
+        while escaping the request body.
+        """
+        request = make_request('test_string')
+
+        mock_parse.side_effect = LtiError
+        response = self.outcome_servce.handle_request(request)
+        self.assertNotIn('TypeError', response)
+        self.assertNotIn('a bytes-like object is required', response)
+        self.assertIn('Request body XML parsing error', response)
+
     @patch('lti_consumer.outcomes.parse_grade_xml_body')
     def test_xml_parse_lti_error(self, mock_parse):
         """
-- 
GitLab