1.3 KiB
1.3 KiB
rocketchat-0002: userIds.includes() O(n) per subscription in unread-counter update loop
Target: RocketChat/Rocket.Chat
Severity: MEDIUM
CWE: CWE-407 (Inefficient Algorithmic Complexity)
File: apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
Line: 129
Status: PATCHED
Description
updateUsersSubscriptions() loads all subscriptions that need updating for a
room, then iterates them with subs.forEach. Inside that loop (line 128–142)
it calls userIds.includes(sub.u._id) where userIds is a string[] built
from the union of mentionIds and highlightIds. For a room with S subscribers
and U mentioned/highlighted users the work is O(S × U).
This is called on every non-edited, non-threaded message save via the
afterSaveMessage callback.
// notifyUsersOnMessage.ts:128-142
subs.forEach((sub) => {
const hasUserMention = userIds.includes(sub.u._id); // O(U) per subscriber
...
});
Fix
const userIdSet = new Set(userIds);
subs.forEach((sub) => {
const hasUserMention = userIdSet.has(sub.u._id); // O(1)
...
});
Complexity
| Before | After | |
|---|---|---|
| Per message | O(S × U) | O(S + U) |
For a 5 000-member channel with 20 mentioned users: 100 000 → 5 020 comparisons.