[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); pdu.hashes.sha256 = RoomHashEventV1(pdu);
#undef AddState #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. * verifying PDUs from the client/federation.
* - In the client, we just do not care about any events that * - In the client, we just do not care about any events that
* are incorrect. We simply drop them, as if they never existed. * 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. */ /* TODO: For PDU events, we should verify their hashes. */
status = RoomGetEventStatusV1(room, &pdu, state, client_event); 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) if (status == PDUV1_STATUS_DROPPED)
{ {
goto finish; goto finish;
} }
StateFree(state);
state = NULL;
pdu._unsigned.pdu_status = status; pdu._unsigned.pdu_status = status;
StateFree(state);
RoomAddEventV1(room, pdu); RoomAddEventV1(room, pdu);
state = NULL;
valid = true; valid = true;
/* If it is a client event, we should make sure that we shout at /* 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; char *safe_id;
size_t i; size_t i;
if (!room || room->version >= 3) if (!room || room->version >= 3 ||
pdu._unsigned.pdu_status == PDUV1_STATUS_DROPPED)
{ {
return false; 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 */ /* Only accepted PDUs get to do the news */
if (pdu._unsigned.pdu_status == PDUV1_STATUS_ACCEPTED) if (pdu._unsigned.pdu_status == PDUV1_STATUS_ACCEPTED)
{ {
/* Remove managed leaves here. */
leaves_json = DbJson(room->leaves_ref); leaves_json = DbJson(room->leaves_ref);
leaves_val = JsonValueDuplicate(JsonGet(leaves_json, 1, "leaves")); leaves_val = JsonValueDuplicate(JsonGet(leaves_json, 1, "leaves"));
leaves = JsonValueAsArray(leaves_val); 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; prev_events = pdu.prev_events;
for (i = 0; i < ArraySize(prev_events); i++) for (i = 0; i < ArraySize(prev_events); i++)
@ -1878,19 +1892,9 @@ RoomAddEventV1(Room *room, PduV1 pdu)
} }
JsonValueFree(ArrayDelete(leaves, delete_index)); JsonValueFree(ArrayDelete(leaves, delete_index));
} }
}
safe_id = CreateSafeID(pdu.event_id); /* Add our current PDU to the leaves. */
event_ref = DbCreate(room->db, 4, "rooms", room->id, "events", safe_id); ArrayAdd(leaves, JsonValueObject(PduV1ToJson(&pdu)));
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));
leaves_json = JsonDuplicate(leaves_json); leaves_json = JsonDuplicate(leaves_json);
JsonValueFree(HashMapDelete(leaves_json, "leaves")); JsonValueFree(HashMapDelete(leaves_json, "leaves"));
JsonSet(leaves_json, JsonValueArray(leaves), 1, "leaves"); JsonSet(leaves_json, JsonValueArray(leaves), 1, "leaves");
@ -1898,8 +1902,6 @@ RoomAddEventV1(Room *room, PduV1 pdu)
JsonFree(leaves_json); JsonFree(leaves_json);
} }
DbUnlock(room->db, event_ref);
for (i = 0; i < ArraySize(prev_events); i++) for (i = 0; i < ArraySize(prev_events); i++)
{ {
JsonValue *event_val = ArrayGet(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); event_ref = DbLock(room->db, 4, "rooms", room->id, "events", id);
PduV1FromJson(DbJson(event_ref), &prev_pdu, &error); 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) if (!prev_pdu._unsigned.next_events)
{ {
prev_pdu._unsigned.next_events = ArrayCreate(); prev_pdu._unsigned.next_events = ArrayCreate();
@ -1927,12 +1931,17 @@ RoomAddEventV1(Room *room, PduV1 pdu)
DbUnlock(room->db, event_ref); 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; State *state;
char *type, *state_key, *event_id; char *type, *state_key, *event_id;
pdu_json = PduV1ToJson(&pdu); pdu_json = PduV1ToJson(&pdu);
/* If we have a membership change, then add it to the
* proper table. */
if (StrEquals(pdu.type, "m.room.member")) if (StrEquals(pdu.type, "m.room.member"))
{ {
CommonID *id = UserIdParse(pdu.state_key, NULL); CommonID *id = UserIdParse(pdu.state_key, NULL);
@ -1961,6 +1970,8 @@ RoomAddEventV1(Room *room, PduV1 pdu)
UserIdFree(id); UserIdFree(id);
UserUnlock(user); UserUnlock(user);
} }
/* Notify the user by pushing out the user */
state = StateCurrent(room); state = StateCurrent(room);
while (StateIterate(state, &type, &state_key, (void **) &event_id)) while (StateIterate(state, &type, &state_key, (void **) &event_id))
{ {
@ -1978,7 +1989,6 @@ RoomAddEventV1(Room *room, PduV1 pdu)
Free(state_key); Free(state_key);
} }
StateFree(state); StateFree(state);
JsonFree(pdu_json); JsonFree(pdu_json);
} }
@ -2038,8 +2048,6 @@ RoomGetDepth(Room *room)
max = depth; max = depth;
} }
} }
(void) i;
(void) pdu;
return max; 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 * State *
StateResolve(Room * room, HashMap * event) StateResolve(Room * room, HashMap * event)
{ {
@ -354,7 +362,6 @@ StateResolve(Room * room, HashMap * event)
return NULL; return NULL;
} }
/* TODO: Return cached state if it exists */
db = RoomGetDB(room); db = RoomGetDB(room);
room_id = JsonValueAsString(HashMapGet(event, "room_id")); room_id = JsonValueAsString(HashMapGet(event, "room_id"));
event_id = JsonValueAsString(HashMapGet(event, "event_id")); event_id = JsonValueAsString(HashMapGet(event, "event_id"));
@ -388,7 +395,7 @@ StateResolve(Room * room, HashMap * event)
RoomEventFetch(room, JsonValueAsString(ArrayGet(prevEvents, i))); RoomEventFetch(room, JsonValueAsString(ArrayGet(prevEvents, i)));
State *state = StateResolve(room, prevEvent); State *state = StateResolve(room, prevEvent);
if (HashMapGet(prevEvent, "state_key")) if (HashMapGet(prevEvent, "state_key") && !IsRejected(prevEvent))
{ {
StateSet( StateSet(
state, state,
@ -442,7 +449,7 @@ StateCurrent(Room *room)
JsonValueAsObject(ArrayGet(prevEvents, i)); JsonValueAsObject(ArrayGet(prevEvents, i));
State *state = StateResolve(room, event); State *state = StateResolve(room, event);
if (HashMapGet(event, "state_key")) if (HashMapGet(event, "state_key") && !IsRejected(event))
{ {
StateSet( StateSet(
state, state,