[MOD] Cleanup code a bit, more status hjinks!
Some checks are pending
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Waiting to run

More work!
This commit is contained in:
LDA 2024-08-23 21:03:55 +02:00
parent d07880b24b
commit fde6f092b4
2 changed files with 41 additions and 26 deletions

View file

@ -1677,7 +1677,7 @@ RoomEventSendV1(Room * room, HashMap * event)
pdu.hashes.sha256 = RoomHashEventV1(pdu);
#undef AddState
}
/* TODO: It seems like we need to behave differently in terms of
/* It seems like we need to behave differently in terms of
* verifying PDUs from the client/federation.
* - In the client, we just do not care about any events that
* are incorrect. We simply drop them, as if they never existed.
@ -1703,16 +1703,17 @@ RoomEventSendV1(Room * room, HashMap * event)
/* TODO: For PDU events, we should verify their hashes. */
status = RoomGetEventStatusV1(room, &pdu, state, client_event);
Log(LOG_INFO, "status='%s'", PduV1StatusToStr(status));
Log(LOG_DEBUG, "status='%s'", PduV1StatusToStr(status));
if (status == PDUV1_STATUS_DROPPED)
{
goto finish;
}
StateFree(state);
state = NULL;
pdu._unsigned.pdu_status = status;
StateFree(state);
RoomAddEventV1(room, pdu);
state = NULL;
valid = true;
/* If it is a client event, we should make sure that we shout at
@ -1838,18 +1839,31 @@ RoomAddEventV1(Room *room, PduV1 pdu)
char *safe_id;
size_t i;
if (!room || room->version >= 3)
if (!room || room->version >= 3 ||
pdu._unsigned.pdu_status == PDUV1_STATUS_DROPPED)
{
return false;
}
/* Insert our PDU into the event table, regardless of status */
safe_id = CreateSafeID(pdu.event_id);
event_ref = DbCreate(room->db, 4, "rooms", room->id, "events", safe_id);
pdu_json = PduV1ToJson(&pdu);
DbJsonSet(event_ref, pdu_json);
DbUnlock(room->db, event_ref);
JsonFree(pdu_json);
Free(safe_id);
/* Only accepted PDUs get to do the news */
if (pdu._unsigned.pdu_status == PDUV1_STATUS_ACCEPTED)
{
/* Remove managed leaves here. */
leaves_json = DbJson(room->leaves_ref);
leaves_val = JsonValueDuplicate(JsonGet(leaves_json, 1, "leaves"));
leaves = JsonValueAsArray(leaves_val);
Free(leaves_val);
Free(leaves_val); /* We do not care about the array's JSON shell. */
prev_events = pdu.prev_events;
for (i = 0; i < ArraySize(prev_events); i++)
@ -1878,19 +1892,9 @@ RoomAddEventV1(Room *room, PduV1 pdu)
}
JsonValueFree(ArrayDelete(leaves, delete_index));
}
}
safe_id = CreateSafeID(pdu.event_id);
event_ref = DbCreate(room->db, 4, "rooms", room->id, "events", safe_id);
Free(safe_id);
pdu_json = PduV1ToJson(&pdu);
DbJsonSet(event_ref, pdu_json);
/* Only accepted PDUs get to do the news */
if (pdu._unsigned.pdu_status == PDUV1_STATUS_ACCEPTED)
{
ArrayAdd(leaves, JsonValueObject(pdu_json));
/* Add our current PDU to the leaves. */
ArrayAdd(leaves, JsonValueObject(PduV1ToJson(&pdu)));
leaves_json = JsonDuplicate(leaves_json);
JsonValueFree(HashMapDelete(leaves_json, "leaves"));
JsonSet(leaves_json, JsonValueArray(leaves), 1, "leaves");
@ -1898,8 +1902,6 @@ RoomAddEventV1(Room *room, PduV1 pdu)
JsonFree(leaves_json);
}
DbUnlock(room->db, event_ref);
for (i = 0; i < ArraySize(prev_events); i++)
{
JsonValue *event_val = ArrayGet(prev_events, i);
@ -1911,6 +1913,8 @@ RoomAddEventV1(Room *room, PduV1 pdu)
event_ref = DbLock(room->db, 4, "rooms", room->id, "events", id);
PduV1FromJson(DbJson(event_ref), &prev_pdu, &error);
/* Update the next events view. Note that this works even if
* the event is soft-failed/rejected. */
if (!prev_pdu._unsigned.next_events)
{
prev_pdu._unsigned.next_events = ArrayCreate();
@ -1927,12 +1931,17 @@ RoomAddEventV1(Room *room, PduV1 pdu)
DbUnlock(room->db, event_ref);
}
/* Accepted PDUs should be the only one that users should be
* notified about. */
if (pdu._unsigned.pdu_status == PDUV1_STATUS_ACCEPTED)
{
State *state;
char *type, *state_key, *event_id;
pdu_json = PduV1ToJson(&pdu);
/* If we have a membership change, then add it to the
* proper table. */
if (StrEquals(pdu.type, "m.room.member"))
{
CommonID *id = UserIdParse(pdu.state_key, NULL);
@ -1961,6 +1970,8 @@ RoomAddEventV1(Room *room, PduV1 pdu)
UserIdFree(id);
UserUnlock(user);
}
/* Notify the user by pushing out the user */
state = StateCurrent(room);
while (StateIterate(state, &type, &state_key, (void **) &event_id))
{
@ -1978,7 +1989,6 @@ RoomAddEventV1(Room *room, PduV1 pdu)
Free(state_key);
}
StateFree(state);
JsonFree(pdu_json);
}
@ -2038,8 +2048,6 @@ RoomGetDepth(Room *room)
max = depth;
}
}
(void) i;
(void) pdu;
return max;
}

View file

@ -335,6 +335,14 @@ StateFromPrevs(Room *room, Array *states)
}
}
static bool
IsRejected(HashMap *pdu)
{
JsonValue *val = JsonGet(pdu, 2, "unsigned", "status");
return StrEquals(JsonValueAsString(val), "rejected");
}
State *
StateResolve(Room * room, HashMap * event)
{
@ -354,7 +362,6 @@ StateResolve(Room * room, HashMap * event)
return NULL;
}
/* TODO: Return cached state if it exists */
db = RoomGetDB(room);
room_id = JsonValueAsString(HashMapGet(event, "room_id"));
event_id = JsonValueAsString(HashMapGet(event, "event_id"));
@ -388,7 +395,7 @@ StateResolve(Room * room, HashMap * event)
RoomEventFetch(room, JsonValueAsString(ArrayGet(prevEvents, i)));
State *state = StateResolve(room, prevEvent);
if (HashMapGet(prevEvent, "state_key"))
if (HashMapGet(prevEvent, "state_key") && !IsRejected(prevEvent))
{
StateSet(
state,
@ -442,7 +449,7 @@ StateCurrent(Room *room)
JsonValueAsObject(ArrayGet(prevEvents, i));
State *state = StateResolve(room, event);
if (HashMapGet(event, "state_key"))
if (HashMapGet(event, "state_key") && !IsRejected(event))
{
StateSet(
state,