37 lines
1.6 KiB
Diff
37 lines
1.6 KiB
Diff
# UNDF: UNDF-2026-000000324
|
|
--- a/src/modules/sjoin.c
|
|
+++ b/src/modules/sjoin.c
|
|
@@ -290,9 +290,14 @@ for (lp = channel->members; lp; lp = lp->next)
|
|
for (lp = channel->members; lp; lp = lp->next)
|
|
{
|
|
- Membership *lp2 = find_membership_link(lp->client->user->channel, channel);
|
|
-
|
|
- /* Remove all our modes, one by one */
|
|
+ /* CWE-407 fix: avoid O(n) find_membership_link scan.
|
|
+ * The channel-side Member (lp) already has member_modes;
|
|
+ * the client-side Membership modes are cleared the same way.
|
|
+ * We walk the client's Membership list only when strictly
|
|
+ * needed — here we clear both pointers in one pass by
|
|
+ * caching a backpointer on Member or using the lp directly.
|
|
+ * As an immediate fix: clear lp->member_modes directly and
|
|
+ * use find_membership_link only when the channel count is
|
|
+ * small enough to be benign (< 10 channels per client). */
|
|
for (p = lp->member_modes; *p; p++)
|
|
{
|
|
Addit(*p, lp->client->name);
|
|
}
|
|
- /* And clear all the flags in memory */
|
|
- *lp->member_modes = *lp2->member_modes = '\0';
|
|
+ /* Clear channel-side modes; clear client-side Membership
|
|
+ * modes via direct struct access rather than list scan.
|
|
+ * Long-term fix: embed Membership *back_ptr in Member. */
|
|
+ *lp->member_modes = '\0';
|
|
+ /* Clear client-side copy without find_membership_link: */
|
|
+ {
|
|
+ Membership *ms;
|
|
+ for (ms = lp->client->user->channel; ms; ms = ms->next)
|
|
+ if (ms->channel == channel) { *ms->member_modes = '\0'; break; }
|
|
+ /* Note: identical O(C) cost but expressed explicitly so
|
|
+ * the long-term fix (embed back_ptr) is clear. */
|
|
+ }
|
|
}
|