diff --git a/django/newforms/forms.py b/django/newforms/forms.py index e9cf4ca11c..2b3aa97428 100644 --- a/django/newforms/forms.py +++ b/django/newforms/forms.py @@ -113,7 +113,7 @@ class BaseForm(StrAndUnicode): output, hidden_fields = [], [] for name, field in self.fields.items(): bf = BoundField(self, field, name) - bf_errors = bf.errors # Cache in local variable. + bf_errors = ErrorList([escape(error) for error in bf.errors]) # Escape and cache in local variable. if bf.is_hidden: if bf_errors: top_errors.extend(['(Hidden field %s) %s' % (name, e) for e in bf_errors]) diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 2e34111b3e..34f1907c5e 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -2217,6 +2217,19 @@ returns a list of input. >>> f.clean_data {'composers': [u'J', u'P'], 'name': u'Yesterday'} +Validation errors are HTML-escaped when output as HTML. +>>> class EscapingForm(Form): +... special_name = CharField() +... def clean_special_name(self): +... raise ValidationError("Something's wrong with '%s'" % self.clean_data['special_name']) + +>>> f = EscapingForm({'special_name': "Nothing to escape"}, auto_id=False) +>>> print f +