Skip to content

Commit de45a95

Browse files
committed
Merge branch 'master' into mila/BloomFilter
2 parents 9dc9f3e + 5c68128 commit de45a95

File tree

21 files changed

+125
-35
lines changed

21 files changed

+125
-35
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ To develop Firebase software, **install**:
132132
To install [clang-format] and [mint] using [Homebrew]:
133133

134134
```console
135-
brew install clang-format@15
135+
brew install clang-format@16
136136
brew install mint
137137
```
138138

Crashlytics/Crashlytics/Helpers/FIRCLSDefines.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
// These macros generate a function to force a symbol for the containing .o, to work around an issue
2424
// where strip will not strip debug information without a symbol to strip.
2525
#define DUMMY_FUNCTION_NAME(x) CONCAT(fircls_strip_this_, x)
26-
#define INJECT_STRIP_SYMBOL(x) \
27-
void DUMMY_FUNCTION_NAME(x)(void) {}
26+
#define INJECT_STRIP_SYMBOL(x) \
27+
void DUMMY_FUNCTION_NAME(x)(void) { \
28+
}
2829

2930
// These make some target os types available to previous versions of xcode that do not yet have them
3031
// in their SDKs

Crashlytics/Shared/FIRCLSMachO/FIRCLSCodeMapping.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ @interface FIRCLSCodeMapping () {
2222

2323
@implementation FIRCLSCodeMapping
2424

25-
+ (instancetype)mappingWithURL:(NSURL*)URL {
25+
+ (instancetype)mappingWithURL:(NSURL *)URL {
2626
return [[self alloc] initWithURL:URL];
2727
}
2828

29-
- (instancetype)initWithURL:(NSURL*)URL {
29+
- (instancetype)initWithURL:(NSURL *)URL {
3030
self = [super init];
3131
if (!self) {
3232
return nil;

Crashlytics/UnitTests/FIRCLSDwarfExpressionTests.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ - (void)testDwarfExpressionMachineInit {
131131
uint8_t fakeData;
132132
FIRCLSThreadContext registers;
133133

134-
XCTAssert(FIRCLSDwarfExpressionMachineInit(&machine, (void*)&fakeData, &registers, 42));
134+
XCTAssert(FIRCLSDwarfExpressionMachineInit(&machine, (void *)&fakeData, &registers, 42));
135135
XCTAssert(FIRCLSDwarfExpressionStackIsValid(&machine.stack));
136136

137137
XCTAssertEqual(FIRCLSDwarfExpressionStackPeek(&machine.stack), 42);

FirebaseDatabase/Tests/Helpers/SenTest+FWaiter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
@interface XCTest (FWaiter)
2020

2121
- (NSTimeInterval)waitUntil:(BOOL (^)(void))predicate;
22-
- (NSTimeInterval)waitUntil:(BOOL (^)(void))predicate description:(NSString*)desc;
22+
- (NSTimeInterval)waitUntil:(BOOL (^)(void))predicate description:(NSString *)desc;
2323
- (NSTimeInterval)waitUntil:(BOOL (^)(void))predicate timeout:(NSTimeInterval)seconds;
2424
- (NSTimeInterval)waitUntil:(BOOL (^)(void))predicate
2525
timeout:(NSTimeInterval)seconds
26-
description:(NSString*)desc;
26+
description:(NSString *)desc;
2727

2828
@end

FirebaseDatabase/Tests/Integration/FData.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ - (void)testWriteLeafNodeOverwriteAtParentMultipleTimesVerifyExpectedEvents {
328328
"already finished." /
329329
Users / runner / runners / 2.262.1 / work / firebase -
330330
ios - sdk / firebase - ios -
331-
sdk / Example / Database / Tests / Helpers / FEventTester.m : 123
331+
sdk / Example / Database / Tests / Helpers / FEventTester.m:
332+
123
332333
``` FTupleEventTypeString *recvd = [self.actualPathsAndEvents objectAtIndex:i];
333334
XCTAssertTrue([target isEqualTo:recvd], @"Expected %@ to match %@", target, recvd);
334335

FirebaseInstallations/Source/Tests/Integration/FIRInstallationsIntegrationTests.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
// Uncomment or set the flag in GCC_PREPROCESSOR_DEFINITIONS to enable integration tests.
18-
//#define FIR_INSTALLATIONS_INTEGRATION_TESTS_REQUIRED 1
18+
// #define FIR_INSTALLATIONS_INTEGRATION_TESTS_REQUIRED 1
1919

2020
// macOS requests a user password when accessing the Keychain for the first time,
2121
// so the tests may fail. Disable integration tests on macOS so far.

FirebaseRemoteConfig/Sources/Public/FirebaseRemoteConfig/FIRRemoteConfig.h

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern NSString *const _Nonnull FIRRemoteConfigThrottledEndTimeInSecondsKey NS_S
3232

3333
/**
3434
* Listener registration returned by `addOnConfigUpdateListener`. Calling its method `remove` stops
35-
* the listener from receiving config updates and unregisters itself.
35+
* the associated listener from receiving config updates and unregisters itself.
3636
*
3737
* If remove is called and no other listener registrations remain, the connection to the real-time
3838
* RC backend is closed. Subsequently calling `addOnConfigUpdateListener` will re-open the
@@ -41,8 +41,8 @@ extern NSString *const _Nonnull FIRRemoteConfigThrottledEndTimeInSecondsKey NS_S
4141
NS_SWIFT_NAME(ConfigUpdateListenerRegistration)
4242
@interface FIRConfigUpdateListenerRegistration : NSObject
4343
/**
44-
* Removes the listener being tracked by this `ConfigUpdateListenerRegistration`. After the initial
45-
* call, subsequent calls have no effect.
44+
* Removes the listener associated with this `ConfigUpdateListenerRegistration`. After the
45+
* initial call, subsequent calls have no effect.
4646
*/
4747
- (void)remove;
4848
@end
@@ -82,17 +82,17 @@ typedef NS_ERROR_ENUM(FIRRemoteConfigErrorDomain, FIRRemoteConfigError){
8282
FIRRemoteConfigErrorInternalError = 8003,
8383
} NS_SWIFT_NAME(RemoteConfigError);
8484

85-
/// Remote Config error domain that handles errors for the real-time service.
85+
/// Remote Config error domain that handles errors for the real-time config update service.
8686
extern NSString *const _Nonnull FIRRemoteConfigUpdateErrorDomain NS_SWIFT_NAME(RemoteConfigUpdateErrorDomain);
87-
/// Firebase Remote Config real-time service error.
87+
/// Firebase Remote Config real-time config update service error.
8888
typedef NS_ERROR_ENUM(FIRRemoteConfigUpdateErrorDomain, FIRRemoteConfigUpdateError){
89-
/// Unable to make a connection to the backend.
89+
/// Unable to make a connection to the Remote Config backend.
9090
FIRRemoteConfigUpdateErrorStreamError = 8001,
91-
/// Unable to fetch the latest config.
91+
/// Unable to fetch the latest version of the config.
9292
FIRRemoteConfigUpdateErrorNotFetched = 8002,
9393
/// The ConfigUpdate message was unparsable.
9494
FIRRemoteConfigUpdateErrorMessageInvalid = 8003,
95-
/// The real-time Remote Config service is unavailable.
95+
/// The Remote Config real-time config update service is unavailable.
9696
FIRRemoteConfigUpdateErrorUnavailable = 8004,
9797
} NS_SWIFT_NAME(RemoteConfigUpdateError);
9898

@@ -171,7 +171,9 @@ NS_SWIFT_NAME(RemoteConfigSettings)
171171
@end
172172

173173
#pragma mark - FIRRemoteConfigUpdate
174-
/// Firebase Remote Config update
174+
/// Used by Remote Config real-time config update service, this class represents changes between the
175+
/// newly fetched config and the current one. An instance of this class is passed to
176+
/// `FIRRemoteConfigUpdateCompletion` when a new config version has been automatically fetched.
175177
NS_SWIFT_NAME(RemoteConfigUpdate)
176178
@interface FIRRemoteConfigUpdate : NSObject
177179

@@ -325,12 +327,13 @@ NS_SWIFT_NAME(RemoteConfig)
325327
/// nil if the key doesn't exist in the default config.
326328
- (nullable FIRRemoteConfigValue *)defaultValueForKey:(nullable NSString *)key;
327329

328-
#pragma mark - Realtime
330+
#pragma mark - Real-time Config Updates
329331

330332
/// Completion handler invoked by `addOnConfigUpdateListener` when there is an update to
331333
/// the config from the backend.
332334
///
333-
/// @param configUpdate Information on which key's values have changed
335+
/// @param configUpdate An instance of `FIRRemoteConfigUpdate` that contains information on which
336+
/// key's values have changed.
334337
/// @param error Error message on failure.
335338
typedef void (^FIRRemoteConfigUpdateCompletion)(FIRRemoteConfigUpdate *_Nullable configUpdate,
336339
NSError *_Nullable error)
@@ -349,8 +352,7 @@ typedef void (^FIRRemoteConfigUpdateCompletion)(FIRRemoteConfigUpdate *_Nullable
349352
///
350353
/// @param listener The configured listener that is called for every config update.
351354
/// @return Returns a registration representing the listener. The registration contains
352-
/// a remove method, which can be used to stop receiving for updates for this particular
353-
/// registration.
355+
/// a remove method, which can be used to stop receiving updates for the provided listener.
354356
- (FIRConfigUpdateListenerRegistration *_Nonnull)addOnConfigUpdateListener:
355357
(FIRRemoteConfigUpdateCompletion _Nonnull)listener
356358
NS_SWIFT_NAME(addOnConfigUpdateListener(remoteConfigUpdateCompletion:));

FirebaseRemoteConfig/Tests/Sample/RemoteConfigSampleApp/FRCLog.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@
1919

2020
+ (instancetype)sharedInstance;
2121

22-
- (void)setLogView:(UITextView*)view;
23-
- (void)logToConsole:(NSString*)text;
22+
- (void)setLogView:(UITextView *)view;
23+
- (void)logToConsole:(NSString *)text;
2424
@end

FirebaseRemoteConfig/Tests/Unit/RCNConfigAnalyticsTest.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#import <OCMock/OCMock.h>
1818
#import <XCTest/XCTest.h>
1919

20-
//#import "RCNConfigAnalytics.h"
20+
// #import "RCNConfigAnalytics.h"
2121

2222
@interface RCNConfigAnalyticsTest : XCTestCase {
2323
id _mockAnalytics;

FirebaseRemoteConfig/Tests/Unit/RCNRemoteConfig+FIRAppTest.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
#import <OCMock/OCMock.h>
1818
#import <XCTest/XCTest.h>
1919

20-
//#import "FIRRemoteConfig+FIRApp.h"
20+
// #import "FIRRemoteConfig+FIRApp.h"
2121
#import "FirebaseCore/Extension/FirebaseCoreInternal.h"
2222
#import "FirebaseRemoteConfig/Sources/Private/FIRRemoteConfig_Private.h"
23-
//#import "third_party/firebase/ios/Releases/FirebaseCore/Tests/FIRTestCase.h"
23+
// #import "third_party/firebase/ios/Releases/FirebaseCore/Tests/FIRTestCase.h"
2424

2525
@interface RCNRemoteConfig_FIRAppTest : FIRTestCase
2626

Firestore/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# 10.7.0
22
- [feature] Add support for disjunctions in queries (`OR` queries).
3+
- [fixed] Fixed stack overflow caused by deeply nested server timestamps.
34

45
# 10.6.0
56
- [fixed] Fix a potential high memory usage issue.

Firestore/Source/API/FSTUserDataWriter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ namespace api = firebase::firestore::api;
3535
- (instancetype)initWithFirestore:(std::shared_ptr<api::Firestore>)firestore
3636
serverTimestampBehavior:(FIRServerTimestampBehavior)serverTimestampBehavior;
3737

38-
- (id)convertedValue:(const firebase::firestore::google_firestore_v1_Value&)value;
38+
- (id)convertedValue:(const firebase::firestore::google_firestore_v1_Value &)value;
3939

4040
@end

Firestore/core/src/model/server_timestamp_util.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ const char kServerTimestampSentinel[] = "server_timestamp";
3535
Message<google_firestore_v1_Value> EncodeServerTimestamp(
3636
const Timestamp& local_write_time,
3737
absl::optional<google_firestore_v1_Value> previous_value) {
38+
// We should avoid storing deeply nested server timestamp map values
39+
// because we never use the intermediate "previous values".
40+
// For example:
41+
// previous: 42L, add: t1, result: t1 -> 42L
42+
// previous: t1, add: t2, result: t2 -> 42L (NOT t2 -> t1 -> 42L)
43+
// previous: t2, add: t3, result: t3 -> 42L (NOT t3 -> t2 -> t1 -> 42L)
44+
// `getPreviousValue` recursively traverses server timestamps to find the
45+
// least recent Value.
46+
if (previous_value.has_value() && IsServerTimestamp(*previous_value)) {
47+
previous_value = GetPreviousValue(*previous_value);
48+
}
3849
pb_size_t count = previous_value ? 3 : 2;
3950

4051
Message<google_firestore_v1_Value> result;

Firestore/core/src/remote/serializer.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@
4343
#include "Firestore/core/src/model/resource_path.h"
4444
#include "Firestore/core/src/model/server_timestamp_util.h"
4545
#include "Firestore/core/src/model/set_mutation.h"
46+
#include "Firestore/core/src/model/snapshot_version.h"
4647
#include "Firestore/core/src/model/value_util.h"
4748
#include "Firestore/core/src/model/verify_mutation.h"
4849
#include "Firestore/core/src/nanopb/byte_string.h"
4950
#include "Firestore/core/src/nanopb/nanopb_util.h"
5051
#include "Firestore/core/src/nanopb/reader.h"
5152
#include "Firestore/core/src/nanopb/writer.h"
5253
#include "Firestore/core/src/timestamp_internal.h"
54+
#include "Firestore/core/src/util/comparison.h"
5355
#include "Firestore/core/src/util/hard_assert.h"
5456
#include "Firestore/core/src/util/status.h"
5557
#include "Firestore/core/src/util/statusor.h"
@@ -112,6 +114,7 @@ using nanopb::SetRepeatedField;
112114
using nanopb::SharedMessage;
113115
using nanopb::Writer;
114116
using remote::WatchChange;
117+
using util::ComparisonResult;
115118
using util::ReadContext;
116119
using util::Status;
117120
using util::StatusOr;
@@ -638,8 +641,19 @@ google_firestore_v1_Target Serializer::EncodeTarget(
638641
nanopb::CopyBytesArray(target_data.resume_token().get());
639642

640643
if (target_data.expected_count().has_value()) {
644+
int32_t expected_count = target_data.expected_count().value();
641645
result.has_expected_count = true;
646+
result.expected_count.value = expected_count;
647+
}
648+
} else if (target_data.snapshot_version().CompareTo(
649+
SnapshotVersion::None()) == ComparisonResult::Descending) {
650+
result.which_resume_type = google_firestore_v1_Target_read_time_tag;
651+
result.resume_type.read_time =
652+
EncodeVersion(target_data.snapshot_version());
653+
654+
if (target_data.expected_count().has_value()) {
642655
int32_t expected_count = target_data.expected_count().value();
656+
result.has_expected_count = true;
643657
result.expected_count.value = expected_count;
644658
}
645659
}

Firestore/core/test/unit/local/local_store_test.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "Firestore/core/test/unit/local/local_store_test.h"
1818

19+
#include <thread> // NOLINT(build/c++11)
1920
#include <unordered_map>
2021
#include <utility>
2122
#include <vector>
@@ -34,10 +35,14 @@
3435
#include "Firestore/core/src/model/document.h"
3536
#include "Firestore/core/src/model/document_key.h"
3637
#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"
3741
#include "Firestore/core/src/model/mutable_document.h"
3842
#include "Firestore/core/src/model/mutation.h"
3943
#include "Firestore/core/src/model/mutation_batch_result.h"
4044
#include "Firestore/core/src/model/patch_mutation.h"
45+
#include "Firestore/core/src/model/server_timestamp_util.h"
4146
#include "Firestore/core/src/model/set_mutation.h"
4247
#include "Firestore/core/src/model/transform_operation.h"
4348
#include "Firestore/core/src/remote/existence_filter.h"
@@ -92,6 +97,7 @@ using testutil::Key;
9297
using testutil::Map;
9398
using testutil::OverlayTypeMap;
9499
using testutil::Query;
100+
using testutil::ServerTimestamp;
95101
using testutil::UnknownDoc;
96102
using testutil::UpdateRemoteEvent;
97103
using testutil::UpdateRemoteEventWithLimboTargets;
@@ -1685,6 +1691,24 @@ TEST_P(LocalStoreTest, PatchMutationLeadsToPatchOverlay) {
16851691
OverlayTypeMap({{Key("foo/baz"), model::Mutation::Type::Patch}}));
16861692
}
16871693

1694+
TEST_P(LocalStoreTest, DeeplyNestedTimestampDoesNotCauseStackOverflow) {
1695+
Timestamp timestamp = Timestamp::Now();
1696+
Message<_google_firestore_v1_Value> initialServerTimestamp =
1697+
model::EncodeServerTimestamp(timestamp, absl::nullopt);
1698+
model::FieldPath path = model::FieldPath::FromDotSeparatedString("timestamp");
1699+
auto makeDeeplyNestedTimestamp = [&]() {
1700+
for (int i = 0; i < 1000; ++i) {
1701+
WriteMutation(testutil::MergeMutation(
1702+
"foo/bar",
1703+
Map("timestamp",
1704+
model::EncodeServerTimestamp(timestamp, *initialServerTimestamp)),
1705+
{path}, {ServerTimestamp("timestamp")}));
1706+
}
1707+
};
1708+
std::thread t(makeDeeplyNestedTimestamp);
1709+
EXPECT_NO_FATAL_FAILURE(t.join());
1710+
}
1711+
16881712
} // namespace local
16891713
} // namespace firestore
16901714
} // namespace firebase

Firestore/core/test/unit/remote/serializer_test.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,42 @@ TEST_F(SerializerTest, EncodesFirstLevelKeyQueries) {
11251125
ExpectRoundTrip(model, proto);
11261126
}
11271127

1128+
TEST_F(SerializerTest, EncodesTargetDataWithExpectedResumeType) {
1129+
TargetData target = CreateTargetData("docs/1");
1130+
1131+
{
1132+
SCOPED_TRACE("EncodesTargetDataWithoutResumeType");
1133+
v1::Target proto;
1134+
proto.mutable_documents()->add_documents(ResourceName("docs/1"));
1135+
proto.set_target_id(1);
1136+
ExpectRoundTrip(target, proto);
1137+
}
1138+
1139+
{
1140+
SCOPED_TRACE("EncodesTargetDataWithResumeToken");
1141+
v1::Target proto;
1142+
proto.mutable_documents()->add_documents(ResourceName("docs/1"));
1143+
proto.set_target_id(1);
1144+
proto.set_resume_token("resume_token");
1145+
ExpectRoundTrip(target.WithResumeToken(nanopb::ByteString{"resume_token"},
1146+
model::SnapshotVersion::None()),
1147+
proto);
1148+
}
1149+
1150+
{
1151+
SCOPED_TRACE("EncodesTargetDataWithResumeByReadTime");
1152+
v1::Target proto;
1153+
proto.mutable_documents()->add_documents(ResourceName("docs/1"));
1154+
proto.set_target_id(1);
1155+
proto.mutable_read_time()->set_seconds(1000);
1156+
proto.mutable_read_time()->set_nanos(42);
1157+
ExpectRoundTrip(
1158+
target.WithResumeToken(nanopb::ByteString{""},
1159+
model::SnapshotVersion(Timestamp(1000, 42))),
1160+
proto);
1161+
}
1162+
}
1163+
11281164
TEST_F(SerializerTest, EncodesFirstLevelAncestorQueries) {
11291165
TargetData model = CreateTargetData("messages");
11301166

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ GEM
33
specs:
44
CFPropertyList (3.0.6)
55
rexml
6-
activesupport (7.0.4.2)
6+
activesupport (7.0.4.3)
77
concurrent-ruby (~> 1.0, >= 1.0.2)
88
i18n (>= 1.6, < 2)
99
minitest (>= 5.1)
@@ -119,7 +119,7 @@ GEM
119119
rexml
120120
kramdown-parser-gfm (1.1.0)
121121
kramdown (~> 2.0)
122-
minitest (5.17.0)
122+
minitest (5.18.0)
123123
molinillo (0.8.0)
124124
multipart-post (2.1.1)
125125
nanaimo (0.3.0)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ GitHub Actions will verify that any code changes are done in a style compliant
140140
way. Install `clang-format` and `mint`:
141141

142142
```console
143-
brew install clang-format@15
143+
brew install clang-format@16
144144
brew install mint
145145
```
146146

scripts/setup_check.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fi
3535

3636
# install clang-format
3737
brew update
38-
brew install clang-format@15
38+
brew install clang-format@16
3939

4040
# mint installs tools from Mintfile on demand.
4141
brew install mint

0 commit comments

Comments
 (0)