java-topology/defects/element-web/patch/element-web-0004-arraydiff-set.patch
russell@unturf.com ec186e286c element-web-0003/0004 + conduit-0001: CWE-407 deep scan — 3 new defects, 6/6 PASS
element-web-0003: TextForEvent.tsx textForCanonicalAliasEvent alt_aliases
  .filter(x => !arr.includes(x)) O(A*B) MEDIUM 19.5x — fix: Set.has()

element-web-0004: utils/arrays.ts arrayDiff + arrayIntersection
  .filter(i => !arr.includes(i)) O(A*B) MEDIUM 18x — fix: Set.has()
  Used by 15+ callsites: room-list, notifications, spaces, beacons, maps

conduit-0001: server_server.rs get_missing_events_route
  earliest_events.contains() (Vec) in growing BFS loop O(Q*E) MEDIUM-HIGH 7.4x
  Federation endpoint — remote server controls input size

matrix-rust-sdk: could not clone (GitHub HTTPS unreachable)
2026-03-30 15:16:54 -04:00

26 lines
1 KiB
Diff

--- a/apps/web/src/utils/arrays.ts
+++ b/apps/web/src/utils/arrays.ts
@@ -189,8 +189,12 @@ export function arrayHasOrderChange(a: any[], b: any[]): boolean {
export function arrayDiff<T>(a: T[], b: T[]): Diff<T> {
+ // CWE-407 fix: use Set for O(1) membership test instead of O(A*B)
+ // includes() inside filter(). Build Sets once, then filter.
+ const setA = new Set(a);
+ const setB = new Set(b);
return {
- added: b.filter((i) => !a.includes(i)),
- removed: a.filter((i) => !b.includes(i)),
+ added: b.filter((i) => !setA.has(i)),
+ removed: a.filter((i) => !setB.has(i)),
};
}
@@ -202,7 +206,10 @@ export function arrayDiff<T>(a: T[], b: T[]): Diff<T> {
* @returns The intersection of the arrays.
*/
export function arrayIntersection<T>(a: T[], b: T[]): T[] {
- return a.filter((i) => b.includes(i));
+ // CWE-407 fix: use Set for O(1) membership test instead of O(A*B)
+ // includes() inside filter().
+ const setB = new Set(b);
+ return a.filter((i) => setB.has(i));
}