diff --git a/CHANGELOG.md b/CHANGELOG.md index b0e79bc3e52..4fb5d0addb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,7 @@ * None. ### Fixed -* ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?) -* None. +* Application may crash with `incoming_changesets.size() != 0` when a download message is mistaken for a bootstrap message (PR [#7238](https://github.com/realm/realm-core/pull/7238), since v11.8.0) ### Breaking changes * `App::get_uncached_app(...)` and `App::get_shared_app(...)` have been replaced by `App::get_app(App::CacheMode, ...)`. The App constructor is now enforced to be unusable, use `App::get_app()` instead. ([#7237](https://github.com/realm/realm-core/issues/7237)) diff --git a/src/realm/sync/client.cpp b/src/realm/sync/client.cpp index a3a3bb61d3d..b0fd90b7002 100644 --- a/src/realm/sync/client.cpp +++ b/src/realm/sync/client.cpp @@ -1149,8 +1149,6 @@ SessionWrapper::SessionWrapper(ClientImpl& client, DBRef db, std::shared_ptrcurrent_user(), harness.schema(), SyncConfig::FLXSyncEnabled{}); + auto [interrupted_promise, interrupted] = util::make_promise_future(); + std::mutex download_message_mutex; + int download_message_integrated_count = 0; + triggered_config.sync_config->on_sync_client_event_hook = + [promise = util::CopyablePromiseHolder(std::move(interrupted_promise)), &download_message_integrated_count, + &download_message_mutex](std::weak_ptr weak_sess, const SyncClientHookData& data) mutable { + auto sess = weak_sess.lock(); + if (!sess || data.event != SyncClientHookEvent::DownloadMessageIntegrated) { + return SyncClientHookAction::NoAction; + } + + std::lock_guard lk(download_message_mutex); + // Pause and resume the first session after the bootstrap message is integrated. + if (download_message_integrated_count == 0) { + sess->pause(); + sess->resume(); + } + // Complete the test when the second session integrates the empty download + // message it receives. + else { + promise.get_promise().emplace_value(); + } + ++download_message_integrated_count; + return SyncClientHookAction::NoAction; + }; + auto realm = Realm::get_shared_realm(triggered_config); + interrupted.get(); + std::lock_guard lk(download_message_mutex); + CHECK(download_message_integrated_count == 2); + auto active_sub_set = realm->sync_session()->get_flx_subscription_store()->get_active(); + REQUIRE(active_sub_set.version() == 0); + REQUIRE(active_sub_set.state() == sync::SubscriptionSet::State::Complete); +} + } // namespace realm::app #endif // REALM_ENABLE_AUTH_TESTS