java-topology/docs/tickets/rocketchat-0002-notify-users-user-ids-array-scan-per-subscription.md

1.3 KiB
Raw Permalink Blame History

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 128142) 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.