fix(upstash): escape quotes in filter values and validate filter types (#5981)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import logging
|
||||
from typing import Dict, List, Optional
|
||||
import re
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -13,6 +14,23 @@ except ImportError:
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_SAFE_FILTER_KEY = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*\Z")
|
||||
|
||||
|
||||
def _validate_filter(key: str, value: Any) -> None:
|
||||
if not isinstance(key, str) or not _SAFE_FILTER_KEY.fullmatch(key):
|
||||
raise ValueError(f"Invalid filter key: {key!r}")
|
||||
if not isinstance(value, (str, int, float, bool)):
|
||||
raise ValueError(
|
||||
f"Filter value for {key!r} must be str, int, float, or bool, "
|
||||
f"got {type(value).__name__}"
|
||||
)
|
||||
if isinstance(value, str) and ('"' in value or "\\" in value):
|
||||
raise ValueError(
|
||||
f"Filter value for {key!r} contains prohibited characters "
|
||||
f"(double quote or backslash): {value!r}"
|
||||
)
|
||||
|
||||
|
||||
class OutputData(BaseModel):
|
||||
id: Optional[str] # memory id
|
||||
@@ -92,7 +110,9 @@ class UpstashVector(VectorStoreBase):
|
||||
)
|
||||
|
||||
def _stringify(self, x):
|
||||
return f'"{x}"' if isinstance(x, str) else x
|
||||
if isinstance(x, str):
|
||||
return f'"{x}"'
|
||||
return x
|
||||
|
||||
def search(
|
||||
self,
|
||||
@@ -113,6 +133,9 @@ class UpstashVector(VectorStoreBase):
|
||||
List[OutputData]: Search results.
|
||||
"""
|
||||
|
||||
if filters:
|
||||
for k, v in filters.items():
|
||||
_validate_filter(k, v)
|
||||
filters_str = " AND ".join([f"{k} = {self._stringify(v)}" for k, v in filters.items()]) if filters else None
|
||||
|
||||
response = []
|
||||
@@ -160,13 +183,16 @@ class UpstashVector(VectorStoreBase):
|
||||
Returns:
|
||||
List[OutputData]: Search results, or None if sparse/BM25 search is not supported.
|
||||
"""
|
||||
try:
|
||||
filters_str = (
|
||||
" AND ".join([f"{k} = {self._stringify(v)}" for k, v in filters.items()])
|
||||
if filters
|
||||
else None
|
||||
)
|
||||
if filters:
|
||||
for k, v in filters.items():
|
||||
_validate_filter(k, v)
|
||||
filters_str = (
|
||||
" AND ".join([f"{k} = {self._stringify(v)}" for k, v in filters.items()])
|
||||
if filters
|
||||
else None
|
||||
)
|
||||
|
||||
try:
|
||||
response = self.client.query(
|
||||
data=query,
|
||||
top_k=top_k,
|
||||
@@ -252,6 +278,9 @@ class UpstashVector(VectorStoreBase):
|
||||
Returns:
|
||||
List[OutputData]: Search results.
|
||||
"""
|
||||
if filters:
|
||||
for k, v in filters.items():
|
||||
_validate_filter(k, v)
|
||||
filters_str = " AND ".join([f"{k} = {self._stringify(v)}" for k, v in filters.items()]) if filters else None
|
||||
|
||||
info = self.client.info()
|
||||
|
||||
Reference in New Issue
Block a user