|
16 | 16 |
|
17 | 17 | #include "Firestore/core/test/unit/local/local_store_test.h"
|
18 | 18 |
|
| 19 | +#include <thread> // NOLINT(build/c++11) |
19 | 20 | #include <unordered_map>
|
20 | 21 | #include <utility>
|
21 | 22 | #include <vector>
|
|
34 | 35 | #include "Firestore/core/src/model/document.h"
|
35 | 36 | #include "Firestore/core/src/model/document_key.h"
|
36 | 37 | #include "Firestore/core/src/model/field_index.h"
|
| 38 | +#include "Firestore/core/src/model/field_mask.h" |
| 39 | +#include "Firestore/core/src/model/field_path.h" |
| 40 | +#include "Firestore/core/src/model/field_transform.h" |
37 | 41 | #include "Firestore/core/src/model/mutable_document.h"
|
38 | 42 | #include "Firestore/core/src/model/mutation.h"
|
39 | 43 | #include "Firestore/core/src/model/mutation_batch_result.h"
|
40 | 44 | #include "Firestore/core/src/model/patch_mutation.h"
|
| 45 | +#include "Firestore/core/src/model/server_timestamp_util.h" |
41 | 46 | #include "Firestore/core/src/model/set_mutation.h"
|
42 | 47 | #include "Firestore/core/src/model/transform_operation.h"
|
43 | 48 | #include "Firestore/core/src/remote/existence_filter.h"
|
@@ -92,6 +97,7 @@ using testutil::Key;
|
92 | 97 | using testutil::Map;
|
93 | 98 | using testutil::OverlayTypeMap;
|
94 | 99 | using testutil::Query;
|
| 100 | +using testutil::ServerTimestamp; |
95 | 101 | using testutil::UnknownDoc;
|
96 | 102 | using testutil::UpdateRemoteEvent;
|
97 | 103 | using testutil::UpdateRemoteEventWithLimboTargets;
|
@@ -1684,6 +1690,24 @@ TEST_P(LocalStoreTest, PatchMutationLeadsToPatchOverlay) {
|
1684 | 1690 | OverlayTypeMap({{Key("foo/baz"), model::Mutation::Type::Patch}}));
|
1685 | 1691 | }
|
1686 | 1692 |
|
| 1693 | +TEST_P(LocalStoreTest, DeeplyNestedTimestampDoesNotCauseStackOverflow) { |
| 1694 | + Timestamp timestamp = Timestamp::Now(); |
| 1695 | + Message<_google_firestore_v1_Value> initialServerTimestamp = |
| 1696 | + model::EncodeServerTimestamp(timestamp, absl::nullopt); |
| 1697 | + model::FieldPath path = model::FieldPath::FromDotSeparatedString("timestamp"); |
| 1698 | + auto makeDeeplyNestedTimestamp = [&]() { |
| 1699 | + for (int i = 0; i < 1000; ++i) { |
| 1700 | + WriteMutation(testutil::MergeMutation( |
| 1701 | + "foo/bar", |
| 1702 | + Map("timestamp", |
| 1703 | + model::EncodeServerTimestamp(timestamp, *initialServerTimestamp)), |
| 1704 | + {path}, {ServerTimestamp("timestamp")})); |
| 1705 | + } |
| 1706 | + }; |
| 1707 | + std::thread t(makeDeeplyNestedTimestamp); |
| 1708 | + EXPECT_NO_FATAL_FAILURE(t.join()); |
| 1709 | +} |
| 1710 | + |
1687 | 1711 | } // namespace local
|
1688 | 1712 | } // namespace firestore
|
1689 | 1713 | } // namespace firebase
|
0 commit comments