Skip to content

Commit 3fbaa3f

Browse files
committed
Properly handle quotes in help_text
Prior to this, django-bootstrap3 didn't escape quotes, so help_text with quotes resulted in cut-off text and additional random (bogus) attributes. Add some appropriate help text to preexisting unit test fields for test purposes.
1 parent f72c9e0 commit 3fbaa3f

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

bootstrap3/renderers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from django.forms.extras import SelectDateWidget
1010
from django.forms.forms import BaseForm, BoundField
1111
from django.forms.formsets import BaseFormSet
12-
from django.utils.html import conditional_escape, strip_tags
12+
from django.utils.html import conditional_escape, escape, strip_tags
1313
from django.template import Context
1414
from django.template.loader import get_template
1515
from django.utils.safestring import mark_safe
@@ -273,7 +273,7 @@ def add_placeholder_attrs(self):
273273
def add_help_attrs(self):
274274
if not isinstance(self.widget, CheckboxInput):
275275
self.widget.attrs['title'] = self.widget.attrs.get(
276-
'title', strip_tags(self.field_help))
276+
'title', escape(strip_tags(self.field_help)))
277277

278278
def add_required_attrs(self):
279279
if self.set_required and is_widget_required_attribute(self.widget):
@@ -306,7 +306,7 @@ def put_inside_label(self, html):
306306
content = '{field} {label}'.format(field=html, label=self.field.label)
307307
return render_label(
308308
content=content, label_for=self.field.id_for_label,
309-
label_title=strip_tags(self.field_help))
309+
label_title=escape(strip_tags(self.field_help)))
310310

311311
def fix_date_select_input(self, html):
312312
div1 = '<div class="col-xs-4">'

bootstrap3/tests.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
from .exceptions import BootstrapError
1414
from .utils import add_css_class
1515

16+
try:
17+
from html.parser import HTMLParser
18+
except ImportError:
19+
from HTMLParser import HTMLParser
20+
1621

1722
RADIO_CHOICES = (
1823
('1', 'Radio 1'),
@@ -47,10 +52,15 @@ class TestForm(forms.Form):
4752
)
4853
password = forms.CharField(widget=forms.PasswordInput)
4954
message = forms.CharField(required=False, help_text='<i>my_help_text</i>')
50-
sender = forms.EmailField(label='Sender © unicode')
55+
sender = forms.EmailField(
56+
label='Sender © unicode',
57+
help_text='E.g., "[email protected]"')
5158
secret = forms.CharField(initial=42, widget=forms.HiddenInput)
5259
cc_myself = forms.BooleanField(
53-
required=False, help_text='You will get a copy in your mailbox.')
60+
required=False,
61+
help_text='cc stands for "carbon copy." '
62+
'You will get a copy in your mailbox.'
63+
)
5464
select1 = forms.ChoiceField(choices=RADIO_CHOICES)
5565
select2 = forms.MultipleChoiceField(
5666
choices=RADIO_CHOICES,
@@ -136,6 +146,23 @@ def render_field(field, **context_args):
136146
return render_template('{% bootstrap_field field %}', **context_args)
137147

138148

149+
def get_title_from_html(html):
150+
class GetTitleParser(HTMLParser):
151+
def __init__(self):
152+
HTMLParser.__init__(self)
153+
self.title = None
154+
155+
def handle_starttag(self, tag, attrs):
156+
for attr, value in attrs:
157+
if attr == 'title':
158+
self.title = value
159+
160+
parser = GetTitleParser()
161+
parser.feed(html)
162+
163+
return parser.title
164+
165+
139166
class SettingsTest(TestCase):
140167
def test_settings(self):
141168
from .bootstrap import BOOTSTRAP3
@@ -265,6 +292,14 @@ def test_show_help(self):
265292
res = render_template('{% bootstrap_field form.subject show_help=0 %}')
266293
self.assertNotIn('my_help_text', res)
267294

295+
def test_help_with_quotes(self):
296+
# Checkboxes get special handling, so test a checkbox and something else
297+
res = render_form_field('sender')
298+
self.assertEqual(get_title_from_html(res), TestForm.base_fields['sender'].help_text)
299+
300+
res = render_form_field('cc_myself')
301+
self.assertEqual(get_title_from_html(res), TestForm.base_fields['cc_myself'].help_text)
302+
268303
def test_subject(self):
269304
res = render_form_field('subject')
270305
self.assertIn('type="text"', res)

0 commit comments

Comments
 (0)