Skip to content

Commit 8a4b07a

Browse files
authored
Prevent use of transforms as cursor values. (#6706)
Closes #6704.
1 parent a355ea1 commit 8a4b07a

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

firestore/google/cloud/firestore_v1beta1/query.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
from google.cloud.firestore_v1beta1 import _helpers
2929
from google.cloud.firestore_v1beta1 import document
30+
from google.cloud.firestore_v1beta1 import transforms
3031
from google.cloud.firestore_v1beta1.gapic import enums
3132
from google.cloud.firestore_v1beta1.proto import query_pb2
3233
from google.cloud.firestore_v1beta1.order import Order
@@ -46,6 +47,7 @@
4647
_BAD_OP_NAN_NULL = (
4748
'Only an equality filter ("==") can be used with None or NaN values')
4849
_BAD_DIR_STRING = 'Invalid direction {!r}. Must be one of {!r} or {!r}.'
50+
_INVALID_CURSOR_TRANSFORM = 'Transforms cannot be used as cursor values.'
4951
_MISSING_ORDER_BY = (
5052
'The "order by" field path {!r} is not present in the cursor data {!r}. '
5153
'All fields sent to ``order_by()`` must be present in the fields '
@@ -563,6 +565,12 @@ def _normalize_cursor(cursor, orders):
563565
document_fields, order_keys)
564566
raise ValueError(msg)
565567

568+
_transform_bases = (transforms.Sentinel, transforms._ValueList)
569+
for field in document_fields:
570+
if isinstance(field, _transform_bases):
571+
msg = _INVALID_CURSOR_TRANSFORM
572+
raise ValueError(msg)
573+
566574
return document_fields, before
567575

568576
def _to_protobuf(self):

firestore/tests/unit/test_query.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,46 @@ def test__normalize_cursor_as_dict_mismatched_order(self):
503503
with self.assertRaises(ValueError):
504504
query._normalize_cursor(cursor, query._orders)
505505

506+
def test__normalize_cursor_w_delete(self):
507+
from google.cloud.firestore_v1beta1 import DELETE_FIELD
508+
509+
cursor = ([DELETE_FIELD], True)
510+
query = self._make_one(
511+
mock.sentinel.parent).order_by('b', 'ASCENDING')
512+
513+
with self.assertRaises(ValueError):
514+
query._normalize_cursor(cursor, query._orders)
515+
516+
def test__normalize_cursor_w_server_timestamp(self):
517+
from google.cloud.firestore_v1beta1 import SERVER_TIMESTAMP
518+
519+
cursor = ([SERVER_TIMESTAMP], True)
520+
query = self._make_one(
521+
mock.sentinel.parent).order_by('b', 'ASCENDING')
522+
523+
with self.assertRaises(ValueError):
524+
query._normalize_cursor(cursor, query._orders)
525+
526+
def test__normalize_cursor_w_array_remove(self):
527+
from google.cloud.firestore_v1beta1 import ArrayRemove
528+
529+
cursor = ([ArrayRemove([1, 3, 5])], True)
530+
query = self._make_one(
531+
mock.sentinel.parent).order_by('b', 'ASCENDING')
532+
533+
with self.assertRaises(ValueError):
534+
query._normalize_cursor(cursor, query._orders)
535+
536+
def test__normalize_cursor_w_array_union(self):
537+
from google.cloud.firestore_v1beta1 import ArrayUnion
538+
539+
cursor = ([ArrayUnion([2, 4, 8])], True)
540+
query = self._make_one(
541+
mock.sentinel.parent).order_by('b', 'ASCENDING')
542+
543+
with self.assertRaises(ValueError):
544+
query._normalize_cursor(cursor, query._orders)
545+
506546
def test__normalize_cursor_as_list_hit(self):
507547
cursor = ([1], True)
508548
query = self._make_one(

0 commit comments

Comments
 (0)