Django

Code

Changeset 6722

Show
Ignore:
Timestamp:
11/28/07 14:19:54 (9 months ago)
Author:
mtredinnick
Message:

Fixed #5730: Conditionally escape widget contents in newforms to avoid
inadvertent double-escaping. This still isn't perfect behaviour (since it's
unaware of the current context's auto-escaping setting), but that's a larger
problem that needs fixing and this change at least makes the existing
behaviour consistent. Patch from SmileyChris?.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/newforms/widgets.py

    r6717 r6722  
    1212 
    1313from django.utils.datastructures import MultiValueDict 
    14 from django.utils.html import escape 
     14from django.utils.html import escape, conditional_escape 
    1515from django.utils.translation import ugettext 
    1616from django.utils.encoding import StrAndUnicode, force_unicode 
     
    156156        final_attrs = self.build_attrs(attrs, name=name) 
    157157        return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), 
    158                 escape(value))) 
     158                conditional_escape(force_unicode(value)))) 
    159159 
    160160class DateTimeInput(Input): 
     
    218218            option_value = force_unicode(option_value) 
    219219            selected_html = (option_value == str_value) and u' selected="selected"' or '' 
    220             output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label)))) 
     220            output.append(u'<option value="%s"%s>%s</option>' % ( 
     221                    escape(option_value), selected_html, 
     222                    conditional_escape(force_unicode(option_label)))) 
    221223        output.append(u'</select>') 
    222224        return mark_safe(u'\n'.join(output)) 
     
    255257            option_value = force_unicode(option_value) 
    256258            selected_html = (option_value in str_values) and ' selected="selected"' or '' 
    257             output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label)))) 
     259            output.append(u'<option value="%s"%s>%s</option>' % ( 
     260                    escape(option_value), selected_html, 
     261                    conditional_escape(force_unicode(option_label)))) 
    258262        output.append(u'</select>') 
    259263        return mark_safe(u'\n'.join(output)) 
     
    279283    def __unicode__(self): 
    280284        return mark_safe(u'<label>%s %s</label>' % (self.tag(), 
    281                 self.choice_label)) 
     285                conditional_escape(force_unicode(self.choice_label)))) 
    282286 
    283287    def is_checked(self): 
     
    364368            option_value = force_unicode(option_value) 
    365369            rendered_cb = cb.render(name, option_value) 
    366             output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, escape(force_unicode(option_label)))) 
     370            output.append(u'<li><label>%s %s</label></li>' % (rendered_cb, 
     371                    conditional_escape(force_unicode(option_label)))) 
    367372        output.append(u'</ul>') 
    368373        return mark_safe(u'\n'.join(output)) 
  • django/trunk/tests/regressiontests/forms/widgets.py

    r6717 r6722  
    33>>> from django.newforms import * 
    44>>> from django.newforms.widgets import RadioFieldRenderer 
     5>>> from django.utils.safestring import mark_safe 
    56>>> import datetime 
    67>>> import time 
     
    206207>>> w.render('msg', 'some "quoted" & ampersanded value') 
    207208u'<textarea rows="10" cols="40" name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>' 
     209>>> w.render('msg', mark_safe('pre &quot;quoted&quot; value')) 
     210u'<textarea rows="10" cols="40" name="msg">pre &quot;quoted&quot; value</textarea>' 
    208211>>> w.render('msg', 'value', attrs={'class': 'pretty', 'rows': 20}) 
    209212u'<textarea class="pretty" rows="20" cols="40" name="msg">value</textarea>' 
     
    376379</select> 
    377380 
     381# Choices are escaped correctly 
     382>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you &gt; me')))) 
     383<select name="escape"> 
     384<option value="1">1</option> 
     385<option value="2">2</option> 
     386<option value="3">3</option> 
     387<option value="bad">you &amp; me</option> 
     388<option value="good">you &gt; me</option> 
     389</select> 
     390 
     391# Unicode choices are correctly rendered as HTML 
    378392>>> w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) 
    379393u'<select name="email">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>' 
     
    539553</select> 
    540554 
     555# Choices are escaped correctly 
     556>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you &gt; me')))) 
     557<select multiple="multiple" name="escape"> 
     558<option value="1">1</option> 
     559<option value="2">2</option> 
     560<option value="3">3</option> 
     561<option value="bad">you &amp; me</option> 
     562<option value="good">you &gt; me</option> 
     563</select> 
     564 
     565# Unicode choices are correctly rendered as HTML 
    541566>>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) 
    542567u'<select multiple="multiple" name="nums">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>' 
     
    693718IndexError: list index out of range 
    694719 
     720# Choices are escaped correctly 
     721>>> w = RadioSelect() 
     722>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you &gt; me')))) 
     723<ul> 
     724<li><label><input type="radio" name="escape" value="bad" /> you &amp; me</label></li> 
     725<li><label><input type="radio" name="escape" value="good" /> you &gt; me</label></li> 
     726</ul> 
     727 
    695728# Unicode choices are correctly rendered as HTML 
    696729>>> w = RadioSelect() 
     
    822855</ul> 
    823856 
     857# Choices are escaped correctly 
     858>>> print w.render('escape', None, choices=(('bad', 'you & me'), ('good', mark_safe('you &gt; me')))) 
     859<ul> 
     860<li><label><input type="checkbox" name="escape" value="1" /> 1</label></li> 
     861<li><label><input type="checkbox" name="escape" value="2" /> 2</label></li> 
     862<li><label><input type="checkbox" name="escape" value="3" /> 3</label></li> 
     863<li><label><input type="checkbox" name="escape" value="bad" /> you &amp; me</label></li> 
     864<li><label><input type="checkbox" name="escape" value="good" /> you &gt; me</label></li> 
     865</ul> 
     866 
     867# Unicode choices are correctly rendered as HTML 
    824868>>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) 
    825869u'<ul>\n<li><label><input type="checkbox" name="nums" value="1" /> 1</label></li>\n<li><label><input type="checkbox" name="nums" value="2" /> 2</label></li>\n<li><label><input type="checkbox" name="nums" value="3" /> 3</label></li>\n<li><label><input checked="checked" type="checkbox" name="nums" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="checkbox" name="nums" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>'