From 1f3fdd85cf1232c74f714e57ec19916eea2dffcb Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Fri, 25 Mar 2016 23:25:39 +0100 Subject: [PATCH 2/2] prevent non utf-8 strings from breaking /inspect (#10447) --- tests/test_backoffice_pages.py | 34 +++++++++++++++++++++++++++++++--- wcs/backoffice/management.py | 19 +++++++++++++++++-- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/tests/test_backoffice_pages.py b/tests/test_backoffice_pages.py index 2f99437..e441817 100644 --- a/tests/test_backoffice_pages.py +++ b/tests/test_backoffice_pages.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import datetime import json import os @@ -93,7 +94,7 @@ def create_environment(pub, set_receiver=True): fields.ItemField(id='2', label='2nd field', type='item', items=['foo', 'bar', 'baz']), fields.ItemField(id='3', label='3rd field', type='item', - data_source=datasource, in_listing=False), + data_source=datasource, in_listing=False, varname='foo'), ] formdef.store() @@ -1991,14 +1992,41 @@ def test_backoffice_criticality_formdata_view(pub): resp = app.get(formdata.get_url(backoffice=True)) assert 'Criticality Level: red' in resp.body + +class IHateUnicode(object): + def __unicode__(self): + raise Exception('HATE!!') + + def __repr__(self): + return 'ok' + + def test_inspect_page(pub): - user = create_user(pub) + create_user(pub) create_environment(pub) formdef = FormDef.get_by_urlname('form-title') formdata = [x for x in formdef.data_class().select() if x.status == 'wf-new'][0] + # temper with field 3 structured values + + formdata.data['3_structured'] = { + 'unicode': u'uné', + 'str_but_non_utf8': '\xed\xa0\x00', + 'non_unicode_convertible': IHateUnicode(), + } + formdata.store() resp = login(get_app(pub)).get('%sinspect' % formdata.get_url(backoffice=True), status=403) - user = create_user(pub, is_admin=True) + create_user(pub, is_admin=True) resp = login(get_app(pub)).get('%sinspect' % formdata.get_url(backoffice=True), status=200) + pq = resp.pyquery.remove_namespaces() + assert (pq('[title="form_var_foo_unicode"]') + .parents('li').children('div.value span') + .text() == u'uné') + assert (pq('[title="form_var_foo_non_unicode_convertible"]') + .parents('li').children('div.value span') + .text().startswith('ok ')) + assert (pq('[title="form_var_foo_str_but_non_utf8"]') + .parents('li').children('div.value span') + .text() == '\'\\xed\\xa0\\x00\'') diff --git a/wcs/backoffice/management.py b/wcs/backoffice/management.py index 0d4735e..081bcaa 100644 --- a/wcs/backoffice/management.py +++ b/wcs/backoffice/management.py @@ -1805,6 +1805,7 @@ class FormBackOfficeStatusPage(FormStatusPage): if not (get_publisher().get_backoffice_root().is_accessible('forms') or get_publisher().get_backoffice_root().is_accessible('workflows')): raise errors.AccessForbiddenError() + charset = get_publisher().site_charset get_response().breadcrumb.append(('inspect', _('Form Inspector'))) self.html_top(self.formdef.name) r = TemplateIO(html=True) @@ -1814,11 +1815,25 @@ class FormBackOfficeStatusPage(FormStatusPage): r += htmltext('
  • %s

  • ') % _('Substitution variables') substvars = self.filled.get_substitution_variables() substvars.update(self.filled.formdef.get_substitution_variables()) + + def safe(v): + if isinstance(v, str): + try: + unicode(v, charset) + except UnicodeDecodeError: + v = repr(v) + else: + try: + v = unicode(v).encode(charset) + except: + v = repr(v) + return v for k, v in sorted(substvars.items()): + k = safe(k) r += htmltext('
  • %s') % (k, k) - r += htmltext('
    %s') % v + r += htmltext('
    %s') % safe(v) if not isinstance(v, basestring): - r += htmltext(' (%s)') % type(v) + r += htmltext(' (%r)') % type(v) r += htmltext('
    ') r += htmltext('') return r.getvalue() -- 2.1.4