Skip to content

Commit 60c298a

Browse files
authored
Merge pull request #33 from cloudblue/lite-20235-not-balanced-brackets
LITE-20235 Added regex special symbols escape
2 parents 29c9a92 + d11997c commit 60c298a

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

dj_rql/filter_cls.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#
22
# Copyright © 2021 Ingram Micro Inc. All rights reserved.
33
#
4+
45
import decimal
6+
import re
57
from collections import defaultdict
68
from datetime import datetime
79
from uuid import uuid4
@@ -879,13 +881,27 @@ def _get_searching_typed_value(cls, django_lookup, str_value):
879881
if val == RQL_ANY_SYMBOL:
880882
return any_symbol_regex
881883

882-
new_val = val
884+
new_val = cls._escape_regex_special_symbols(val)
883885
new_val = new_val[1:] if val[0] == RQL_ANY_SYMBOL else '^{0}'.format(new_val)
884886
new_val = new_val[:-1] if val[-1] == RQL_ANY_SYMBOL else '{0}$'.format(new_val)
885887
return new_val.replace(RQL_ANY_SYMBOL, any_symbol_regex).replace(
886888
star_replacer, RQL_ANY_SYMBOL,
887889
)
888890

891+
@staticmethod
892+
def _escape_regex_special_symbols(str_value):
893+
"""Returns escaped string
894+
895+
Current like/ilike protocol (* in any place) implementation requires to execute regex.
896+
Input string could be a not valid (braces not balanced db error)
897+
or misinterpreted (symbols range). Regex is not supported by RQL so we can safely
898+
escape redundant special symbols.
899+
"""
900+
return (
901+
re.escape(str_value)
902+
.replace(r'\{0}'.format(RQL_ANY_SYMBOL), RQL_ANY_SYMBOL)
903+
)
904+
889905
@classmethod
890906
def _convert_value(cls, django_field, str_value, use_repr=False):
891907
val = cls.remove_quotes(str_value)

tests/test_filter_cls/test_fields_filtering.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,10 @@ def test_empty_value_fail(filter_name):
472472
('*\*\*value', DjangoLookups.ENDSWITH, '**value'),
473473
('*val\*ue*', DjangoLookups.CONTAINS, 'val*ue'),
474474
('va\*l*\*ue*', DjangoLookups.REGEX, '^va*l(.*)*ue'),
475+
('val*[ue}*', DjangoLookups.REGEX, r'^val(.*)\[ue\}'),
476+
('val*ue)*', DjangoLookups.REGEX, r'^val(.*)ue\)'),
477+
('*val*ue{2*', DjangoLookups.REGEX, r'val(.*)ue\{2'),
478+
('val*ue{2}*', DjangoLookups.REGEX, r'^val(.*)ue\{2\}'),
475479
])
476480
def test_searching_q_ok(value, db_lookup, db_value):
477481
cls = BooksFilterClass(book_qs)

0 commit comments

Comments
 (0)