From 0ee1d944a1d285c25fc44bdf8dd6ee2ab6c90acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Mon, 31 Dec 2018 10:14:43 +0100 Subject: [PATCH] misc: don't crash storing unicode passwords for logged users (#19217) --- tests/test_form_pages.py | 12 +++++++----- wcs/sql.py | 8 +++++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py index 9eab6b5f..d6aee513 100644 --- a/tests/test_form_pages.py +++ b/tests/test_form_pages.py @@ -1772,13 +1772,13 @@ def test_form_direct_draft_access(pub): formdata.store() resp = login(get_app(pub), 'foo', 'foo').get('/test/%s' % formdata.id, status=403) -def form_password_field_submit(pub, password): - password = unicode(password).encode(pub.site_charset) +def form_password_field_submit(app, password): formdef = create_formdef() + formdef.enable_tracking_codes = True formdef.fields = [fields.PasswordField(id='0', label='password', formats=['sha1', 'md5', 'cleartext'])] formdef.store() - page = get_app(pub).get('/test/') + page = app.get('/test/') formdef.data_class().wipe() next_page = page.forms[0].submit('submit') # but the field is required assert '
required field
' in next_page.body @@ -1800,8 +1800,10 @@ def form_password_field_submit(pub, password): }} def test_form_password_field_submit(pub): - form_password_field_submit(pub, 'foobar') - form_password_field_submit(pub, u'foobar\u00eb') + user = create_user(pub) + form_password_field_submit(get_app(pub), 'foobar') + form_password_field_submit(get_app(pub), '\xe2\x80\xa2\t83003706') + form_password_field_submit(login(get_app(pub), username='foo', password='foo'), 'foobar\u00eb') def test_form_multi_page_formdef_count_condition(pub): formdef = create_formdef() diff --git a/wcs/sql.py b/wcs/sql.py index c45e448c..a1ab573d 100644 --- a/wcs/sql.py +++ b/wcs/sql.py @@ -248,6 +248,12 @@ def str_encode(value): return value return value.encode(get_publisher().site_charset) +def site_unicode(value): + if not isinstance(value, basestring): + value = unicode(value) + if isinstance(value, unicode): + return value + return unicode(value, get_publisher().site_charset) def get_connection(new=False): if new: @@ -1072,7 +1078,7 @@ class SqlMixin(object): if value is not None: if field.key in ('ranked-items', 'password'): # turn {'poire': 2, 'abricot': 1, 'pomme': 3} into an array - value = [[x, unicode(y).encode('utf-8')] for x, y in value.items()] + value = [[x, site_unicode(y).encode('utf-8')] for x, y in value.items()] elif sql_type == 'varchar': assert isinstance(value, basestring) elif sql_type == 'date': -- 2.18.0