[MOD/WIP] Fix double-free on PL checks

This commit is contained in:
lda 2024-06-04 13:45:12 +02:00
parent 879e51c169
commit 21b015da2c
2 changed files with 50 additions and 28 deletions

View file

@ -23,12 +23,12 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include <Cytoplasm/HashMap.h>
#include <Cytoplasm/Array.h> #include <Cytoplasm/Array.h>
#include <Cytoplasm/Json.h> #include <Cytoplasm/Json.h>
/*#include "Cytoplasm/Stream.h"*/ #include <Parser.h>
#include "Cytoplasm/HashMap.h" #include <Config.h>
#include "Parser.h" #include <User.h>
#include "User.h"
#include <Room.h> #include <Room.h>
#include <Cytoplasm/Memory.h> #include <Cytoplasm/Memory.h>
@ -87,6 +87,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
HashMap *content, *event, *override, *pl_content; HashMap *content, *event, *override, *pl_content;
Array *initial_states; Array *initial_states;
JsonValue *val; JsonValue *val;
int64_t pl = 100;
size_t i; size_t i;
char *join_rules_preset = NULL; char *join_rules_preset = NULL;
@ -137,7 +138,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
content = HashMapCreate(); content = HashMapCreate();
JsonSet( JsonSet(
content, content,
JsonValueInteger(100), JsonValueInteger(pl),
2, "users", sender_str); 2, "users", sender_str);
override = req->power_level_content_override; override = req->power_level_content_override;
while (override && HashMapIterate(override, &key, (void **) &val)) while (override && HashMapIterate(override, &key, (void **) &val))
@ -150,7 +151,6 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
} }
HashMapSet(content, key, JsonValueDuplicate(val)); HashMapSet(content, key, JsonValueDuplicate(val));
} }
pl_content = JsonDuplicate(content);
event = RoomEventCreate(sender_str, "m.room.power_levels", "", content); event = RoomEventCreate(sender_str, "m.room.power_levels", "", content);
JsonFree(RoomEventSend(room, event)); JsonFree(RoomEventSend(room, event));
JsonFree(event); JsonFree(event);
@ -273,6 +273,8 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
Free(serverStr); Free(serverStr);
} }
/* Invites */ /* Invites */
pl_content = HashMapCreate();
JsonSet(pl_content, JsonValueInteger(pl), 2, "users", sender_str);
for (i = 0; i < ArraySize(req->invite); i++) for (i = 0; i < ArraySize(req->invite); i++)
{ {
char *user_id = ArrayGet(req->invite, i); char *user_id = ArrayGet(req->invite, i);
@ -283,33 +285,23 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
break; break;
} }
content = HashMapCreate(); RoomSendInvite(user, req->is_direct, user_id, room);
if (req->is_direct)
{
JsonSet(content, JsonValueBoolean(true), 1, "is_direct");
}
JsonSet(content, JsonValueString("invite"), 1, "membership");
event = RoomEventCreate(sender_str, "m.room.member", user_id, content);
JsonFree(RoomEventSend(room, event));
JsonFree(event);
if (trusted_room) if (trusted_room)
{ {
JsonValue *own = JsonGet(pl_content, 2, "users", sender_str); JsonValue *own = JsonValueInteger(pl);
JsonValueFree(JsonSet( JsonSet(pl_content, own, 2, "users", user_id);
pl_content, JsonValueDuplicate(own),
2, "users", user_id));
} }
} }
JsonValueFree(JsonSet(
DbJson(room->leaves_ref),
JsonValueBoolean(req->is_direct), 1, "is_direct"));
event = RoomEventCreate(sender_str, "m.room.power_levels", "", pl_content); event = RoomEventCreate(sender_str, "m.room.power_levels", "", pl_content);
JsonFree(RoomEventSend(room, event)); JsonFree(RoomEventSend(room, event));
JsonFree(event); JsonFree(event);
JsonValueFree(JsonSet(
DbJson(room->leaves_ref),
JsonValueBoolean(req->is_direct), 1, "is_direct"));
/* TODO: The rest of the events mandated by the specification on /* TODO: The rest of the events mandated by the specification on
* POST /createRoom, and error management. */ * POST /createRoom, and error management. */
@ -1293,8 +1285,8 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
\ \
new = JsonGet(pdu.content, 2, prop, ev_type); \ new = JsonGet(pdu.content, 2, prop, ev_type); \
old_pl = ParsePL(new, INT64_MAX); \ old_pl = ParsePL(new, INT64_MAX); \
if (((new_pl = ParsePL(new, INT64_MAX)) == INT64_MAX || \ if (((new_pl = ParsePL(new, INT64_MAX)) != INT64_MAX) && \
new_pl != old_pl) && old_pl > userpl) \ ((new_pl != old_pl) && old_pl > userpl)) \
{ \ { \
flag = false; \ flag = false; \
} \ } \
@ -1302,7 +1294,6 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
if (!flag) \ if (!flag) \
{ \ { \
JsonFree(prev_plevent); \ JsonFree(prev_plevent); \
StateFree(state); \
return false; \ return false; \
} \ } \
flag = true flag = true
@ -1322,7 +1313,7 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
\ \
old = JsonGet(prev_plevent, 3, "content", prop, ev_type); \ old = JsonGet(prev_plevent, 3, "content", prop, ev_type); \
new_pl = ParsePL(ev_obj, INT64_MAX); \ new_pl = ParsePL(ev_obj, INT64_MAX); \
if (((old_pl = ParsePL(old, INT64_MAX)) == INT64_MAX || \ if (((old_pl = ParsePL(old, INT64_MAX)) != INT64_MAX && \
new_pl != old_pl) && new_pl > userpl) \ new_pl != old_pl) && new_pl > userpl) \
{ \ { \
flag = false; \ flag = false; \
@ -1331,7 +1322,6 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
if (!flag) \ if (!flag) \
{ \ { \
JsonFree(prev_plevent); \ JsonFree(prev_plevent); \
StateFree(state); \
return false; \ return false; \
} \ } \
flag = true flag = true
@ -1645,7 +1635,7 @@ RoomEventSendV1(Room * room, HashMap * event)
finish: finish:
if (state) if (state)
{ {
JsonFree(state); StateFree(state);
} }
if (pdu_object) if (pdu_object)
{ {
@ -2005,3 +1995,29 @@ RoomFreeReverse(Array *arr)
} }
ArrayFree(arr); ArrayFree(arr);
} }
void
RoomSendInvite(User *sender, bool direct, char *user, Room *room)
{
HashMap *content, *event;
CommonID *senderID;
char *senderStr;
Config conf;
if (!sender || !user || !room)
{
return;
}
ConfigLock(room->db, &conf);
senderID = UserIdParse(UserGetName(sender), conf.serverName);
senderStr = ParserRecomposeCommonID(*senderID);
UserIdFree(senderID);
content = HashMapCreate();
JsonSet(content, JsonValueBoolean(direct), 1, "is_direct");
JsonSet(content, JsonValueString("invite"), 1, "membership");
event = RoomEventCreate(senderStr, "m.room.member", user, content);
JsonFree(RoomEventSend(room, event));
JsonFree(event);
ConfigUnlock(&conf);
Free(senderStr);
}

View file

@ -138,6 +138,12 @@ extern int RoomPrevEventsSet(Room *, Array *);
*/ */
extern HashMap * RoomEventSend(Room *, HashMap *); extern HashMap * RoomEventSend(Room *, HashMap *);
/**
* Sends an invite to a user in a room, and tries
* to notify such user of it.
*/
extern void RoomSendInvite(User *, bool, char *, Room *);
/** /**
* Fetch a single event's PDU in a room into an * Fetch a single event's PDU in a room into an
* hashmap, given an event ID, from the database * hashmap, given an event ID, from the database