From 97a6827ae713a5d60fa2f31ad49276d1fa84f3f3 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Thu, 5 Mar 2015 00:15:11 -0500 Subject: [PATCH] Warns user to URL encode query parameters When making a request with a filter that uses the ``like`` operator, the user will likely provide an argument of the form ``%somestring%``. If not properly URL encoded, this will be interpreted on the server side as an unintended string. This fixes #331 and #415. --- CHANGES | 3 +++ docs/searchformat.rst | 11 ++++++++++- tests/test_views.py | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0cf47068..413fdb20 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,9 @@ Version 0.17.1-dev Not yet released. +- #331, #415: documents the importance of URL encoding when using the ``like`` + operator to filter results. + Version 0.17.0 -------------- diff --git a/docs/searchformat.rst b/docs/searchformat.rst index 760b6be8..e710a653 100644 --- a/docs/searchformat.rst +++ b/docs/searchformat.rst @@ -157,13 +157,22 @@ The operator strings recognized by the API incude: * ``>=``, ``ge``, ``gte``, ``geq``, ``<=``, ``le``, ``lte``, ``leq`` * ``in``, ``not_in`` * ``is_null``, ``is_not_null`` -* ``like`` +* ``like``, ``ilike`` * ``has`` * ``any`` These correspond to SQLAlchemy column operators as defined `here `_. +.. warning:: + + If you use a percent sign in the argument to the ``like`` operator (for + example, ``%somestring%``), make sure it is `URL encoded`_, otherwise the + server may interpret the first few characters of that argument as a + percent-encoded character when attempting to decode the URL. + + .. _URL encoded: https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_the_percent_character + Examples -------- diff --git a/tests/test_views.py b/tests/test_views.py index 82a25ad4..a7ba5af6 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -15,6 +15,7 @@ from datetime import datetime from datetime import timedelta import math +from urllib.parse import quote as urlquote import dateutil from flask import json @@ -1951,6 +1952,18 @@ def test_search_bad_arguments(self): resp = self.app.search('/api/person', dumps(d)) assert resp.status_code == 400 + def test_like(self): + """Tests for the like operator.""" + person1 = self.Person(name='foo') + person2 = self.Person(name='bar') + self.session.add_all([person1, person2]) + self.session.commit() + data = dict(filters=[dict(name='name', op='like', val='%bar%')]) + response = self.app.search('/api/person', urlquote(dumps(data))) + data = loads(response.data) + people = data['objects'] + assert ['bar'] == sorted(person['name'] for person in people) + class TestAssociationProxy(ManagerTestBase): """Unit tests for models which have a relationship involving an association