Skip to content

Commit 74d9427

Browse files
committed
Address incorrect CQL2 "LIKE" pattern substitutions
1 parent 89c8999 commit 74d9427

File tree

1 file changed

+25
-15
lines changed
  • stac_fastapi/core/stac_fastapi/core/extensions

1 file changed

+25
-15
lines changed

stac_fastapi/core/stac_fastapi/core/extensions/filter.py

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,41 @@
1717
from enum import Enum
1818
from typing import Any, Dict
1919

20+
_cql2_like_patterns = re.compile(r"\\.|[%_]|\\$")
21+
_valid_like_substitutions = {
22+
"\\\\": "\\",
23+
"\\%": "%",
24+
"\\_": "_",
25+
"%": "*",
26+
"_": "?",
27+
}
28+
29+
30+
def _replace_like_patterns(match: re.Match) -> str:
31+
pattern = match.group()
32+
try:
33+
return _valid_like_substitutions[pattern]
34+
except KeyError:
35+
raise ValueError(f"'{pattern}' is not a valid escape sequence")
36+
2037

2138
def cql2_like_to_es(string: str) -> str:
2239
"""
23-
Convert CQL2 wildcard characters to Elasticsearch wildcard characters. Specifically, it converts '_' to '?' and '%' to '*', handling escape characters properly.
40+
Convert CQL2 "LIKE" characters to Elasticsearch "wildcard" characters.
2441
2542
Args:
2643
string (str): The string containing CQL2 wildcard characters.
2744
2845
Returns:
2946
str: The converted string with Elasticsearch compatible wildcards.
47+
48+
Raises:
49+
ValueError: If an invalid escape sequence is encountered.
3050
"""
31-
# Translate '%' and '_' only if they are not preceded by a backslash '\'
32-
percent_pattern = r"(?<!\\)%"
33-
underscore_pattern = r"(?<!\\)_"
34-
# Remove the escape character before '%' or '_'
35-
escape_pattern = r"\\(?=[_%])"
36-
37-
# Replace '%' with '*' for broad wildcard matching
38-
string = re.sub(percent_pattern, "*", string)
39-
# Replace '_' with '?' for single character wildcard matching
40-
string = re.sub(underscore_pattern, "?", string)
41-
# Remove the escape character used in the CQL2 format
42-
string = re.sub(escape_pattern, "", string)
43-
44-
return string
51+
return _cql2_like_patterns.sub(
52+
repl=_replace_like_patterns,
53+
string=string,
54+
)
4555

4656

4757
class LogicalOp(str, Enum):

0 commit comments

Comments
 (0)