From d49f37eac46a14558408c9e7677ba1dd1b96cf56 Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Sat, 9 Sep 2017 00:17:48 -0400 Subject: [PATCH] Fixing unlocking hints for challenges with unicode names (#383) * Fixing unlocking hints for challenges with unicode names * Add tests for unlocking hints with no cost --- CTFd/challenges.py | 3 ++- CTFd/utils.py | 7 ++++++ tests/helpers.py | 8 +++++++ tests/user/test_challenges.py | 43 +++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/CTFd/challenges.py b/CTFd/challenges.py index 58112f97..1a5252cd 100644 --- a/CTFd/challenges.py +++ b/CTFd/challenges.py @@ -11,6 +11,7 @@ from CTFd.plugins.keys import get_key_class from CTFd.plugins.challenges import get_chal_class from CTFd import utils +from CTFd.utils import text_type challenges = Blueprint('challenges', __name__) @@ -40,7 +41,7 @@ def hints_view(hintid): if team.score() < hint.cost: return jsonify({'errors': 'Not enough points'}) unlock = Unlocks(model='hints', teamid=session['id'], itemid=hint.id) - award = Awards(teamid=session['id'], name='Hint for {}'.format(chal.name), value=(-hint.cost)) + award = Awards(teamid=session['id'], name=text_type('Hint for {}'.format(chal.name)), value=(-hint.cost)) db.session.add(unlock) db.session.add(award) db.session.commit() diff --git a/CTFd/utils.py b/CTFd/utils.py index d9fcf021..14972461 100644 --- a/CTFd/utils.py +++ b/CTFd/utils.py @@ -31,6 +31,13 @@ from werkzeug.utils import secure_filename from CTFd.models import db, WrongKeys, Pages, Config, Tracking, Teams, Files, ip2long, long2ip +if six.PY2: + text_type = unicode + binary_type = str +else: + text_type = str + binary_type = bytes + cache = Cache() migrate = Migrate() markdown = mistune.Markdown() diff --git a/tests/helpers.py b/tests/helpers.py index 01e8222c..c77943cb 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -3,6 +3,14 @@ from CTFd.models import * from sqlalchemy_utils import database_exists, create_database, drop_database from sqlalchemy.engine.url import make_url import datetime +import six + +if six.PY2: + text_type = unicode + binary_type = str +else: + text_type = str + binary_type = bytes def create_ctfd(ctf_name="CTFd", name="admin", email="admin@ctfd.io", password="password", setup=True): diff --git a/tests/user/test_challenges.py b/tests/user/test_challenges.py index 91914db4..37aeb50e 100644 --- a/tests/user/test_challenges.py +++ b/tests/user/test_challenges.py @@ -81,6 +81,7 @@ def test_chals_solves(): ''') received = json.loads(output) assert saved == received + destroy_ctfd(app) def test_submitting_correct_flag(): @@ -185,3 +186,45 @@ def test_submitting_flags_with_large_ips(): assert resp.get('status') == 1 and resp.get('message') == "Correct" assert Solves.query.filter_by(ip=ip_address).first() destroy_ctfd(app) + + +def test_unlocking_hints_with_no_cost(): + '''Test that hints with no cost can be unlocked''' + app = create_ctfd() + with app.app_context(): + register_user(app) + chal = gen_challenge(app.db) + chal_id = chal.id + hint = gen_hint(app.db, chal_id) + + client = login_as_user(app) + with client.session_transaction() as sess: + data = { + "nonce": sess.get('nonce') + } + r = client.post('/hints/1', data=data) + output = r.get_data(as_text=True) + output = json.loads(output) + assert output.get('hint') == 'This is a hint' + destroy_ctfd(app) + + +def test_unlocking_hint_for_unicode_challenge(): + '''Test that hints for challenges with unicode names can be unlocked''' + app = create_ctfd() + with app.app_context(): + register_user(app) + chal = gen_challenge(app.db, name=text_type('🐺')) + chal_id = chal.id + hint = gen_hint(app.db, chal_id) + + client = login_as_user(app) + with client.session_transaction() as sess: + data = { + "nonce": sess.get('nonce') + } + r = client.post('/hints/1', data=data) + output = r.get_data(as_text=True) + output = json.loads(output) + assert output.get('hint') == 'This is a hint' + destroy_ctfd(app)