Skip to content

Commit 7d0128c

Browse files
authored
Fix/dave segfault (#1306)
1 parent fd170de commit 7d0128c

File tree

1 file changed

+63
-42
lines changed

1 file changed

+63
-42
lines changed

src/dpp/voice/enabled/handle_frame.cpp

+63-42
Original file line numberDiff line numberDiff line change
@@ -395,28 +395,18 @@ bool discord_voice_client::handle_frame(const std::string &data, ws_opcode opcod
395395

396396
if (dave_version != dave_version_none) {
397397
/* DAVE ready later */
398-
if (j["d"]["dave_protocol_version"] != static_cast<uint32_t>(dave_version)) {
398+
399+
bool dave_incapable = j["d"]["dave_protocol_version"] != static_cast<uint32_t>(dave_version);
400+
if (dave_incapable) {
399401
log(ll_error, "We requested DAVE E2EE but didn't receive it from the server, downgrading...");
400402
dave_version = dave_version_none;
401-
ready_now = true;
402-
} else {
403-
if (mls_state == nullptr) {
404-
mls_state = std::make_unique<dave_state>();
405-
}
406-
if (mls_state->dave_session == nullptr) {
407-
mls_state->dave_session = std::make_unique<dave::mls::session>(
408-
*creator,
409-
nullptr, "", [this](std::string const &s1, std::string const &s2) {
410-
log(ll_debug, "DAVE: " + s1 + ", " + s2);
411-
});
412-
}
413-
this->reinit_dave_mls_group();
414-
415-
/* Ready now if there's no DAVE user waiting in the vc */
416-
if (dave_mls_user_list.empty()) {
417-
ready_now = true;
418-
}
419403
}
404+
405+
/* We told gateway that we got DAVE, stay true to ourselves! */
406+
this->reinit_dave_mls_group();
407+
408+
/* Ready now when no upgrade or no DAVE user waiting in the vc */
409+
ready_now = dave_incapable || dave_mls_user_list.empty();
420410
} else {
421411
/* Non-DAVE ready immediately */
422412
ready_now = true;
@@ -501,27 +491,32 @@ bool discord_voice_client::handle_frame(const std::string &data, ws_opcode opcod
501491
*/
502492

503493
void discord_voice_client::ready_for_transition(const std::string &data) {
504-
log(ll_debug, "Ready to execute transition " + std::to_string(this->mls_state->transition_id));
494+
if (mls_state == nullptr) {
495+
/* Impossible! */
496+
return;
497+
}
498+
499+
log(ll_debug, "Ready to execute transition " + std::to_string(mls_state->transition_id));
505500
json obj = {
506501
{ "op", voice_client_dave_transition_ready },
507502
{
508503
"d",
509504
{
510-
{ "transition_id", this->mls_state->transition_id },
505+
{ "transition_id", mls_state->transition_id },
511506
}
512507
}
513508
};
514509
this->write(obj.dump(-1, ' ', false, json::error_handler_t::replace), OP_TEXT);
515-
this->mls_state->pending_transition.id = this->mls_state->transition_id;
510+
mls_state->pending_transition.id = mls_state->transition_id;
516511

517512
/* When the included transition ID is 0, the transition is for (re)initialization, and it can be executed immediately. */
518-
if (this->mls_state->transition_id == 0) {
513+
if (mls_state->transition_id == 0) {
519514
/* Mark state ready and update ratchets the first time */
520515
update_ratchets();
521516
}
522517

523-
if (!this->mls_state->done_ready) {
524-
this->mls_state->done_ready = true;
518+
if (!mls_state->done_ready) {
519+
mls_state->done_ready = true;
525520

526521
if (!creator->on_voice_ready.empty()) {
527522
voice_ready_t rdy(nullptr, data);
@@ -537,47 +532,68 @@ void discord_voice_client::recover_from_invalid_commit_welcome() {
537532
{"op", voice_client_dave_mls_invalid_commit_welcome},
538533
{
539534
"d", {
540-
"transition_id", this->mls_state->transition_id
535+
"transition_id", mls_state->transition_id
541536
}
542537
}
543538
};
544539
this->write(obj.dump(-1, ' ', false, json::error_handler_t::replace), OP_TEXT);
545-
this->reinit_dave_mls_group();
540+
reinit_dave_mls_group();
546541
}
547542

548543
bool discord_voice_client::execute_pending_upgrade_downgrade() {
544+
if (mls_state == nullptr) {
545+
/* Who called?? */
546+
return false;
547+
}
548+
549549
bool did_upgrade_downgrade = false;
550550

551-
if (this->mls_state->transition_id != this->mls_state->pending_transition.id) {
552-
log(ll_debug, "execute_pending_upgrade_downgrade unexpected transition_id, we never received voice_client_dave_prepare_transition event with this id: " + std::to_string(this->mls_state->transition_id));
553-
} else if (dave_version != this->mls_state->pending_transition.protocol_version) {
554-
dave_version = this->mls_state->pending_transition.protocol_version == 1 ? dave_version_1 : dave_version_none;
551+
if (mls_state->transition_id != mls_state->pending_transition.id) {
552+
log(ll_debug, "execute_pending_upgrade_downgrade unexpected transition_id, we never received voice_client_dave_prepare_transition event with this id: " + std::to_string(mls_state->transition_id));
553+
} else if (dave_version != mls_state->pending_transition.protocol_version) {
554+
dave_version = mls_state->pending_transition.protocol_version == 1 ? dave_version_1 : dave_version_none;
555555

556-
if (this->mls_state->pending_transition.protocol_version != 0 && dave_version == dave_version_none) {
557-
log(ll_debug, "execute_pending_upgrade_downgrade unexpected protocol version: " + std::to_string(this->mls_state->pending_transition.protocol_version)+ " in transition " + std::to_string(this->mls_state->transition_id));
556+
if (mls_state->pending_transition.protocol_version != 0 && dave_version == dave_version_none) {
557+
log(ll_debug, "execute_pending_upgrade_downgrade unexpected protocol version: " + std::to_string(mls_state->pending_transition.protocol_version)+ " in transition " + std::to_string(mls_state->transition_id));
558558
} else {
559559
log(ll_debug, "execute_pending_upgrade_downgrade upgrade/downgrade successful");
560560
did_upgrade_downgrade = true;
561561
}
562562
}
563563

564-
this->mls_state->pending_transition.is_pending = false;
564+
mls_state->pending_transition.is_pending = false;
565565
return did_upgrade_downgrade;
566566
}
567567

568568
void discord_voice_client::reinit_dave_mls_group() {
569-
mls_state->dave_session->init(dave::max_protocol_version(), channel_id, creator->me.id.str(), mls_state->mls_key);
569+
/* This method is the beginning of a dave session, do the basics */
570+
if (dave_version != dave_version_none) {
571+
if (mls_state == nullptr) {
572+
mls_state = std::make_unique<dave_state>();
573+
}
574+
575+
if (mls_state->dave_session == nullptr) {
576+
mls_state->dave_session = std::make_unique<dave::mls::session>(
577+
*creator,
578+
nullptr, "", [this](std::string const &s1, std::string const &s2) {
579+
log(ll_debug, "DAVE: " + s1 + ", " + s2);
580+
});
581+
}
570582

571-
auto key_response = mls_state->dave_session->get_marshalled_key_package();
572-
key_response.insert(key_response.begin(), voice_client_dave_mls_key_package);
573-
this->write(std::string_view(reinterpret_cast<const char*>(key_response.data()), key_response.size()), OP_BINARY);
583+
mls_state->dave_session->init(dave::max_protocol_version(), channel_id, creator->me.id.str(), mls_state->mls_key);
574584

575-
mls_state->encryptor = std::make_unique<dave::encryptor>(*creator);
576-
mls_state->decryptors.clear();
585+
auto key_response = mls_state->dave_session->get_marshalled_key_package();
586+
key_response.insert(key_response.begin(), voice_client_dave_mls_key_package);
587+
this->write(std::string_view(reinterpret_cast<const char*>(key_response.data()), key_response.size()), OP_BINARY);
577588

578-
mls_state->cached_roster_map.clear();
589+
mls_state->encryptor = std::make_unique<dave::encryptor>(*creator);
590+
}
579591

580-
mls_state->privacy_code.clear();
592+
if (mls_state) {
593+
mls_state->decryptors.clear();
594+
mls_state->cached_roster_map.clear();
595+
mls_state->privacy_code.clear();
596+
}
581597

582598
/* Remove any user in pending remove from MLS member list */
583599
for (const auto &user : dave_mls_pending_remove_list) {
@@ -587,6 +603,11 @@ void discord_voice_client::reinit_dave_mls_group() {
587603
}
588604

589605
void discord_voice_client::process_mls_group_rosters(const dave::roster_map &rmap) {
606+
if (mls_state == nullptr) {
607+
/* What??? */
608+
return;
609+
}
610+
590611
log(ll_debug, "process_mls_group_rosters of size: " + std::to_string(rmap.size()));
591612

592613
for (const auto &[k, v] : rmap) {

0 commit comments

Comments
 (0)