aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core/test
diff options
context:
space:
mode:
authorGravatar rsgowman <rgowman@google.com>2018-06-05 12:24:14 -0400
committerGravatar GitHub <noreply@github.com>2018-06-05 12:24:14 -0400
commit9307f4893008f7d6cf9473e906d4c896546c5c8c (patch)
tree5919d80429ec89a1c805cd0f5692d8cb0547bc85 /Firestore/core/test
parent77227f58a03ac1383237f7239a337a7c061b5227 (diff)
Skip unknown fields while decoding BatchGetDocumentsResponse proto objects (#1377)
Diffstat (limited to 'Firestore/core/test')
-rw-r--r--Firestore/core/test/firebase/firestore/remote/serializer_test.cc62
1 files changed, 62 insertions, 0 deletions
diff --git a/Firestore/core/test/firebase/firestore/remote/serializer_test.cc b/Firestore/core/test/firebase/firestore/remote/serializer_test.cc
index 7dcdf6e..a902b5d 100644
--- a/Firestore/core/test/firebase/firestore/remote/serializer_test.cc
+++ b/Firestore/core/test/firebase/firestore/remote/serializer_test.cc
@@ -804,6 +804,68 @@ TEST_F(SerializerTest, EncodesNonEmptyDocument) {
ExpectRoundTrip(key, fields, update_time, proto);
}
+TEST_F(SerializerTest,
+ BadBatchGetDocumentsResponseTagWithOtherValidTagsPresent) {
+ // A bad tag should be ignored, in which case, we should successfully
+ // deserialize the rest of the bytes as if it wasn't there. To craft these
+ // bytes, we'll use the same technique as
+ // EncodesFieldValuesWithRepeatedEntries (so go read the comments there
+ // first).
+
+ // Copy of the real one (from the nanopb generated firestore.pb.h), but with
+ // only "missing" (a field from the original proto) and an extra_field.
+ struct google_firestore_v1beta1_BatchGetDocumentsResponse_Fake {
+ pb_callback_t missing;
+ int64_t extra_field;
+ };
+
+ // Copy of the real one (from the nanopb generated firestore.pb.c), but with
+ // only missing and an extra_field. Also modified such that extra_field
+ // now has a tag of 31.
+ const int invalid_tag = 31;
+ const pb_field_t
+ google_firestore_v1beta1_BatchGetDocumentsResponse_fields_Fake[2] = {
+ PB_FIELD(2, STRING, SINGULAR, CALLBACK, FIRST,
+ google_firestore_v1beta1_BatchGetDocumentsResponse_Fake,
+ missing, missing, 0),
+ PB_FIELD(invalid_tag, INT64, SINGULAR, STATIC, OTHER,
+ google_firestore_v1beta1_BatchGetDocumentsResponse_Fake,
+ extra_field, missing, 0),
+ };
+
+ const char* missing_value = "projects/p/databases/d/documents/one/two";
+ google_firestore_v1beta1_BatchGetDocumentsResponse_Fake crafty_value;
+ crafty_value.missing.funcs.encode =
+ [](pb_ostream_t* stream, const pb_field_t* field, void* const* arg) {
+ const char* missing_value = static_cast<const char*>(*arg);
+ if (!pb_encode_tag_for_field(stream, field)) return false;
+ return pb_encode_string(stream,
+ reinterpret_cast<const uint8_t*>(missing_value),
+ strlen(missing_value));
+ };
+ crafty_value.missing.arg = const_cast<char*>(missing_value);
+ crafty_value.extra_field = 42;
+
+ std::vector<uint8_t> bytes(128);
+ pb_ostream_t stream = pb_ostream_from_buffer(bytes.data(), bytes.size());
+ pb_encode(&stream,
+ google_firestore_v1beta1_BatchGetDocumentsResponse_fields_Fake,
+ &crafty_value);
+ bytes.resize(stream.bytes_written);
+
+ // Decode the bytes into the model
+ StatusOr<std::unique_ptr<MaybeDocument>> actual_model_status =
+ serializer.DecodeMaybeDocument(bytes);
+ EXPECT_OK(actual_model_status);
+ std::unique_ptr<MaybeDocument> actual_model =
+ std::move(actual_model_status).ValueOrDie();
+
+ // Ensure the decoded model is as expected.
+ NoDocument expected_model =
+ NoDocument(Key("one/two"), SnapshotVersion::None());
+ EXPECT_EQ(expected_model, *actual_model.get());
+}
+
TEST_F(SerializerTest, DecodesNoDocument) {
// We can't actually *encode* a NoDocument; the method exposed by the
// serializer requires both the document key and contents (as an ObjectValue,