aboutsummaryrefslogtreecommitdiff
path: root/lib/room.cpp
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2019-03-29 13:26:36 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2019-03-30 16:19:32 +0900
commita28892ca3b40a32556ee7615116c322f6b2a4ae5 (patch)
tree2e666bb9e997a77b0dee03a315181420f0a61048 /lib/room.cpp
parent01c5a35398a55dfc4a30e466aeb13419387555d3 (diff)
downloadlibquotient-a28892ca3b40a32556ee7615116c322f6b2a4ae5.tar.gz
libquotient-a28892ca3b40a32556ee7615116c322f6b2a4ae5.zip
Room::processStateEvent, User: take the previous membership state from oldStateEvent
memberJoinState() just happens to return the not-yet-updated state, making its use around state changes very sensitive to moving things around. The event's own prevContent is unsigned, therefore untrusted.
Diffstat (limited to 'lib/room.cpp')
-rw-r--r--lib/room.cpp24
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/room.cpp b/lib/room.cpp
index 19658be0..789800c6 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -1184,7 +1184,11 @@ void Room::Private::insertMemberIntoMap(User *u)
const auto userName = u->name(q);
// If there is exactly one namesake of the added user, signal member renaming
// for that other one because the two should be disambiguated now.
- auto namesakes = membersMap.values(userName);
+ const auto namesakes = membersMap.values(userName);
+
+ // Callers should check they are not adding an existing user once more.
+ Q_ASSERT(!namesakes.contains(u));
+
if (namesakes.size() == 1)
emit q->memberAboutToRename(namesakes.front(),
namesakes.front()->fullName(q));
@@ -2196,16 +2200,20 @@ Room::Changes Room::processStateEvent(const RoomEvent& e)
emit avatarChanged();
return AvatarChange;
}
- , [this] (const RoomMemberEvent& evt) {
+ , [this,oldStateEvent] (const RoomMemberEvent& evt) {
auto* u = user(evt.userId());
- u->processEvent(evt, this);
- if (u == localUser() && memberJoinState(u) == JoinState::Invite
+ const auto* oldMemberEvent =
+ static_cast<const RoomMemberEvent*>(oldStateEvent);
+ u->processEvent(evt, this, oldMemberEvent == nullptr);
+ const auto prevMembership = oldMemberEvent
+ ? oldMemberEvent->membership() : MembershipType::Leave;
+ if (u == localUser() && evt.membership() == MembershipType::Invite
&& evt.isDirect())
connection()->addToDirectChats(this, user(evt.senderId()));
- if( evt.membership() == MembershipType::Join )
+ if (evt.membership() == MembershipType::Join)
{
- if (memberJoinState(u) != JoinState::Join)
+ if (prevMembership != MembershipType::Join)
{
d->insertMemberIntoMap(u);
connect(u, &User::nameAboutToChange, this,
@@ -2221,9 +2229,9 @@ Room::Changes Room::processStateEvent(const RoomEvent& e)
emit userAdded(u);
}
}
- else if( evt.membership() != MembershipType::Join )
+ else if (evt.membership() != MembershipType::Join)
{
- if (memberJoinState(u) == JoinState::Join)
+ if (prevMembership == MembershipType::Join)
{
if (evt.membership() == MembershipType::Invite)
qCWarning(MAIN) << "Invalid membership change:" << evt;