Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #6160, #9111 -- Consistently apply conditional_escape to form e…

…rrors and labels when outputing them as HTML.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9365 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit bcd63cbfb0590a2e2bed3e4beab3f467279ad3db 1 parent 04354e1
Karen Tracey authored November 06, 2008
6  django/contrib/auth/tests/views.py
@@ -16,7 +16,7 @@ def test_email_not_found(self):
16 16
         response = self.client.get('/password_reset/')
17 17
         self.assertEquals(response.status_code, 200)
18 18
         response = self.client.post('/password_reset/', {'email': 'not_a_real_email@email.com'})
19  
-        self.assertContains(response, "That e-mail address doesn't have an associated user account")
  19
+        self.assertContains(response, "That e-mail address doesn't have an associated user account")
20 20
         self.assertEquals(len(mail.outbox), 0)
21 21
 
22 22
     def test_email_found(self):
@@ -87,7 +87,7 @@ def test_confirm_different_passwords(self):
87 87
         response = self.client.post(path, {'new_password1': 'anewpassword',
88 88
                                            'new_password2':' x'})
89 89
         self.assertEquals(response.status_code, 200)
90  
-        self.assert_("The two password fields didn't match" in response.content)
  90
+        self.assert_("The two password fields didn't match" in response.content)
91 91
 
92 92
 
93 93
 class ChangePasswordTest(TestCase):
@@ -147,7 +147,7 @@ def test_password_change_fails_with_mismatched_passwords(self):
147 147
             }
148 148
         )
149 149
         self.assertEquals(response.status_code, 200)
150  
-        self.assert_("The two password fields didn't match." in response.content)
  150
+        self.assert_("The two password fields didn't match." in response.content)
151 151
 
152 152
     def test_password_change_succeeds(self):
153 153
         self.login()
8  django/forms/forms.py
@@ -5,7 +5,7 @@
5 5
 from copy import deepcopy
6 6
 
7 7
 from django.utils.datastructures import SortedDict
8  
-from django.utils.html import escape
  8
+from django.utils.html import conditional_escape
9 9
 from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode
10 10
 from django.utils.safestring import mark_safe
11 11
 
@@ -140,7 +140,7 @@ def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_
140 140
         output, hidden_fields = [], []
141 141
         for name, field in self.fields.items():
142 142
             bf = BoundField(self, field, name)
143  
-            bf_errors = self.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable.
  143
+            bf_errors = self.error_class([conditional_escape(error) for error in bf.errors]) # Escape and cache in local variable.
144 144
             if bf.is_hidden:
145 145
                 if bf_errors:
146 146
                     top_errors.extend([u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors])
@@ -149,7 +149,7 @@ def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_
149 149
                 if errors_on_separate_row and bf_errors:
150 150
                     output.append(error_row % force_unicode(bf_errors))
151 151
                 if bf.label:
152  
-                    label = escape(force_unicode(bf.label))
  152
+                    label = conditional_escape(force_unicode(bf.label))
153 153
                     # Only add the suffix if the label does not end in
154 154
                     # punctuation.
155 155
                     if self.label_suffix:
@@ -395,7 +395,7 @@ def label_tag(self, contents=None, attrs=None):
395 395
 
396 396
         If attrs are given, they're used as HTML attributes on the <label> tag.
397 397
         """
398  
-        contents = contents or escape(self.label)
  398
+        contents = contents or conditional_escape(self.label)
399 399
         widget = self.field.widget
400 400
         id_ = widget.attrs.get('id') or self.auto_id
401 401
         if id_:
2  django/forms/util.py
@@ -39,7 +39,7 @@ def __unicode__(self):
39 39
     def as_ul(self):
40 40
         if not self: return u''
41 41
         return mark_safe(u'<ul class="errorlist">%s</ul>'
42  
-                % ''.join([u'<li>%s</li>' % force_unicode(e) for e in self]))
  42
+                % ''.join([u'<li>%s</li>' % conditional_escape(force_unicode(e)) for e in self]))
43 43
 
44 44
     def as_text(self):
45 45
         if not self: return u''
18  tests/regressiontests/forms/forms.py
@@ -593,17 +593,25 @@
593 593
 u'Yesterday'
594 594
 
595 595
 Validation errors are HTML-escaped when output as HTML.
  596
+>>> from django.utils.safestring import mark_safe
596 597
 >>> class EscapingForm(Form):
597  
-...     special_name = CharField()
  598
+...     special_name = CharField(label="<em>Special</em> Field")
  599
+...     special_safe_name = CharField(label=mark_safe("<em>Special</em> Field"))
598 600
 ...     def clean_special_name(self):
599 601
 ...         raise ValidationError("Something's wrong with '%s'" % self.cleaned_data['special_name'])
  602
+...     def clean_special_safe_name(self):
  603
+...         raise ValidationError(mark_safe("'<b>%s</b>' is a safe string" % self.cleaned_data['special_safe_name']))
600 604
 
601  
->>> f = EscapingForm({'special_name': "Nothing to escape"}, auto_id=False)
  605
+>>> f = EscapingForm({'special_name': "Nothing to escape", 'special_safe_name': "Nothing to escape"}, auto_id=False)
602 606
 >>> print f
603  
-<tr><th>Special name:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Nothing to escape&#39;</li></ul><input type="text" name="special_name" value="Nothing to escape" /></td></tr>
604  
->>> f = EscapingForm({'special_name': "Should escape < & > and <script>alert('xss')</script>"}, auto_id=False)
  607
+<tr><th>&lt;em&gt;Special&lt;/em&gt; Field:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Nothing to escape&#39;</li></ul><input type="text" name="special_name" value="Nothing to escape" /></td></tr>
  608
+<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>'<b>Nothing to escape</b>' is a safe string</li></ul><input type="text" name="special_safe_name" value="Nothing to escape" /></td></tr>
  609
+>>> f = EscapingForm(
  610
+...     {'special_name': "Should escape < & > and <script>alert('xss')</script>",
  611
+...     'special_safe_name': "<i>Do not escape</i>"}, auto_id=False)
605 612
 >>> print f
606  
-<tr><th>Special name:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;&#39;</li></ul><input type="text" name="special_name" value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;" /></td></tr>
  613
+<tr><th>&lt;em&gt;Special&lt;/em&gt; Field:</th><td><ul class="errorlist"><li>Something&#39;s wrong with &#39;Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;&#39;</li></ul><input type="text" name="special_name" value="Should escape &lt; &amp; &gt; and &lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;" /></td></tr>
  614
+<tr><th><em>Special</em> Field:</th><td><ul class="errorlist"><li>'<b><i>Do not escape</i></b>' is a safe string</li></ul><input type="text" name="special_safe_name" value="&lt;i&gt;Do not escape&lt;/i&gt;" /></td></tr>
607 615
 
608 616
 """ + \
609 617
 r""" # [This concatenation is to keep the string below the jython's 32K limit].
7  tests/regressiontests/forms/util.py
@@ -49,4 +49,11 @@
49 49
 # Can take a non-string.
50 50
 >>> print ValidationError(VeryBadError()).messages
51 51
 <ul class="errorlist"><li>A very bad error.</li></ul>
  52
+
  53
+# Escapes non-safe input but not input marked safe.
  54
+>>> example = 'Example of link: <a href="http://www.example.com/">example</a>'
  55
+>>> print ValidationError(example).messages
  56
+<ul class="errorlist"><li>Example of link: &lt;a href=&quot;http://www.example.com/&quot;&gt;example&lt;/a&gt;</li></ul>
  57
+>>> print ValidationError(mark_safe(example)).messages
  58
+<ul class="errorlist"><li>Example of link: <a href="http://www.example.com/">example</a></li></ul>
52 59
 """

0 notes on commit bcd63cb

Please sign in to comment.
Something went wrong with that request. Please try again.