diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index a9ce23c2e5..a0631a12db 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -804,9 +804,15 @@ class MatlabInput(CodeInput): # the graded response takes precedence if 'queue_msg' in self.input_state and self.status in ['queued', 'incomplete', 'unsubmitted']: attributes = bleach.ALLOWED_ATTRIBUTES.copy() - attributes.update({'*': ['class', 'style', 'id'], 'audio': ['controls', 'autobuffer', 'autoplay', 'src']}) + # Yuck! but bleach does not offer the option of passing in allowed_protocols, + # and matlab uses data urls for images + if u'data' not in bleach.BleachSanitizer.allowed_protocols: + bleach.BleachSanitizer.allowed_protocols.append(u'data') + attributes.update({'*': ['class', 'style', 'id'], + 'audio': ['controls', 'autobuffer', 'autoplay', 'src'], + 'img': ['src', 'width', 'height', 'class']}) self.queue_msg = bleach.clean(self.input_state['queue_msg'], - tags=bleach.ALLOWED_TAGS + ['div', 'p', 'audio', 'pre'], + tags=bleach.ALLOWED_TAGS + ['div', 'p', 'audio', 'pre', 'img'], styles=['white-space'], attributes=attributes ) diff --git a/common/lib/capa/capa/tests/test_inputtypes.py b/common/lib/capa/capa/tests/test_inputtypes.py index 890dbb2ecc..cba14ff0f2 100644 --- a/common/lib/capa/capa/tests/test_inputtypes.py +++ b/common/lib/capa/capa/tests/test_inputtypes.py @@ -665,7 +665,8 @@ class MatlabTest(unittest.TestCase): Zero or more ELSEIF parts can be used as well as nested if's. The expression is usually of the form expr rop expr where rop is ==, <, >, <=, >=, or ~=. - + + Example if I == J A(I,J) = 2; @@ -692,7 +693,7 @@ class MatlabTest(unittest.TestCase): the_input = self.input_class(test_capa_system(), elt, state) context = the_input._get_render_context() # pylint: disable=W0212 self.maxDiff = None - expected = u'\n
if Conditionally execute statements.\nThe general form of the if statement is\n\n if expression\n statements\n ELSEIF expression\n statements\n ELSE\n statements\n END\n\nThe statements are executed if the real part of the expression \nhas all non-zero elements. The ELSE and ELSEIF parts are optional.\nZero or more ELSEIF parts can be used as well as nested if\'s.\nThe expression is usually of the form expr rop expr where \nrop is ==, <, >, <=, >=, or ~=.\n\nExample\n if I == J\n A(I,J) = 2;\n elseif abs(I-J) == 1\n A(I,J) = -1;\n else\n A(I,J) = 0;\n end\n\nSee also relop, else, elseif, end, for, while, switch.\n\nReference page in Help browser\n doc if\n\n
\n' + expected = u'\n
if Conditionally execute statements.\nThe general form of the if statement is\n\n if expression\n statements\n ELSEIF expression\n statements\n ELSE\n statements\n END\n\nThe statements are executed if the real part of the expression \nhas all non-zero elements. The ELSE and ELSEIF parts are optional.\nZero or more ELSEIF parts can be used as well as nested if\'s.\nThe expression is usually of the form expr rop expr where \nrop is ==, <, >, <=, >=, or ~=.\n\n\nExample\n if I == J\n A(I,J) = 2;\n elseif abs(I-J) == 1\n A(I,J) = -1;\n else\n A(I,J) = 0;\n end\n\nSee also relop, else, elseif, end, for, while, switch.\n\nReference page in Help browser\n doc if\n\n
\n' self.assertEqual(context['queue_msg'], expected)