[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.
*/
#include <Cytoplasm/HashMap.h>
#include <Cytoplasm/Array.h>
#include <Cytoplasm/Json.h>
/*#include "Cytoplasm/Stream.h"*/
#include "Cytoplasm/HashMap.h"
#include "Parser.h"
#include "User.h"
#include <Parser.h>
#include <Config.h>
#include <User.h>
#include <Room.h>
#include <Cytoplasm/Memory.h>
@ -87,6 +87,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
HashMap *content, *event, *override, *pl_content;
Array *initial_states;
JsonValue *val;
int64_t pl = 100;
size_t i;
char *join_rules_preset = NULL;
@ -137,7 +138,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
content = HashMapCreate();
JsonSet(
content,
JsonValueInteger(100),
JsonValueInteger(pl),
2, "users", sender_str);
override = req->power_level_content_override;
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));
}
pl_content = JsonDuplicate(content);
event = RoomEventCreate(sender_str, "m.room.power_levels", "", content);
JsonFree(RoomEventSend(room, event));
JsonFree(event);
@ -273,6 +273,8 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
Free(serverStr);
}
/* Invites */
pl_content = HashMapCreate();
JsonSet(pl_content, JsonValueInteger(pl), 2, "users", sender_str);
for (i = 0; i < ArraySize(req->invite); i++)
{
char *user_id = ArrayGet(req->invite, i);
@ -283,33 +285,23 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
break;
}
content = HashMapCreate();
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);
RoomSendInvite(user, req->is_direct, user_id, room);
if (trusted_room)
{
JsonValue *own = JsonGet(pl_content, 2, "users", sender_str);
JsonValueFree(JsonSet(
pl_content, JsonValueDuplicate(own),
2, "users", user_id));
JsonValue *own = JsonValueInteger(pl);
JsonSet(pl_content, 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);
JsonFree(RoomEventSend(room, 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
* POST /createRoom, and error management. */
@ -1293,8 +1285,8 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
\
new = JsonGet(pdu.content, 2, prop, ev_type); \
old_pl = ParsePL(new, INT64_MAX); \
if (((new_pl = ParsePL(new, INT64_MAX)) == INT64_MAX || \
new_pl != old_pl) && old_pl > userpl) \
if (((new_pl = ParsePL(new, INT64_MAX)) != INT64_MAX) && \
((new_pl != old_pl) && old_pl > userpl)) \
{ \
flag = false; \
} \
@ -1302,7 +1294,6 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
if (!flag) \
{ \
JsonFree(prev_plevent); \
StateFree(state); \
return false; \
} \
flag = true
@ -1322,7 +1313,7 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
\
old = JsonGet(prev_plevent, 3, "content", prop, ev_type); \
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) \
{ \
flag = false; \
@ -1331,7 +1322,6 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
if (!flag) \
{ \
JsonFree(prev_plevent); \
StateFree(state); \
return false; \
} \
flag = true
@ -1645,7 +1635,7 @@ RoomEventSendV1(Room * room, HashMap * event)
finish:
if (state)
{
JsonFree(state);
StateFree(state);
}
if (pdu_object)
{
@ -2005,3 +1995,29 @@ RoomFreeReverse(Array *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 *);
/**
* 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
* hashmap, given an event ID, from the database