diff --git a/roundup/cgi/actions.py b/roundup/cgi/actions.py --- a/roundup/cgi/actions.py +++ b/roundup/cgi/actions.py @@ -624,9 +624,10 @@ try: message = self._editnodes(props, links) except (ValueError, KeyError, IndexError, - roundup.exceptions.Reject), message: + roundup.exceptions.Reject) as exc: self.client.add_error_message( - self._('Edit Error: %s') % str(message)) + self._('Edit Error: %s') % str(exc), + escape=getattr(exc, 'escape_html', True)) return # commit now that all the tricky stuff is done @@ -670,9 +671,11 @@ # when it hits the None element, it'll set self.nodeid messages = self._editnodes(props, links) except (ValueError, KeyError, IndexError, - roundup.exceptions.Reject), message: + roundup.exceptions.Reject) as exc: # these errors might just be indicative of user dumbness - self.client.add_error_message(_('Error: %s') % str(message)) + self.client.add_error_message( + _('Error: %s') % str(exc), + escape=getattr(exc, 'escape_html', True)) return # commit now that all the tricky stuff is done @@ -853,9 +856,11 @@ # when it hits the None element, it'll set self.nodeid messages = self._editnodes(props, links) except (ValueError, KeyError, IndexError, - roundup.exceptions.Reject), message: + roundup.exceptions.Reject) as exc: # these errors might just be indicative of user dumbness - self.client.add_error_message(_('Error: %s') % str(message)) + self.client.add_error_message( + _('Error: %s') % str(exc), + escape=getattr(exc, 'escape_html', True)) return # fix up the initial roles diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py --- a/roundup/cgi/client.py +++ b/roundup/cgi/client.py @@ -1263,7 +1263,8 @@ return action_klass(self).execute() except (ValueError, Reject), err: - self.add_error_message(str(err)) + self.add_error_message(str(err), + escape=getattr(exc, 'escape_html', True)) def get_action_class(self, action_name): if (hasattr(self.instance, 'cgi_actions') and diff --git a/roundup/exceptions.py b/roundup/exceptions.py --- a/roundup/exceptions.py +++ b/roundup/exceptions.py @@ -18,8 +18,13 @@ - mailgw will trap and ignore Reject for file attachments and messages - cgi will trap and present the exception in a nice format + + If escape_html is True (default), HTML contained in the error message + will be escaped. """ - pass + def __init__(self, *args, **kwargs): + self.escape_html = kwargs.pop('escape_html', True) + super(Reject, self).__init__(*args, **kwargs) class UsageError(ValueError): pass