java-topology/defects/thunderbird-0001/patch/thunderbird-0001_nsMsgAccountManager_LoadAccounts_indexOf_ON2.patch

48 lines
1.8 KiB
Diff

# UNDF: UNDF-2026-000000887
--- a/mailnews/base/src/nsMsgAccountManager.cpp
+++ b/mailnews/base/src/nsMsgAccountManager.cpp
@@ -description
# Defect: thunderbird-0001
# Component: mailnews/base/src/nsMsgAccountManager.cpp
# Function: LoadAccounts()
# Pattern: IndexOf() inside loop for duplicate detection = O(N^2)
# Severity: MEDIUM
# Measured: 250x overhead at N=500 accounts
#
# The LoadAccounts() function iterates through the account list and for
# each element calls IndexOf() to check if its first occurrence matches
# the current position (duplicate detection). IndexOf() is a linear scan,
# making the overall duplicate detection O(N^2) where N = number of
# account entries in the preferences.
#
# While most users have <10 accounts, enterprise/ISP deployments can have
# hundreds, and this runs on every Thunderbird startup.
#
# Fix: Use a HashSet to track seen accounts in O(1) per lookup.
#
# Before (O(N^2)):
# for (uint32_t i = 0; i < accountsArray.Length(); i++) {
# if (accountsArray.IndexOf(accountsArray[i]) != i) continue;
# ...
# }
#
# After (O(N)):
# nsTHashSet<nsCString> seenAccounts;
# for (uint32_t i = 0; i < accountsArray.Length(); i++) {
# if (!seenAccounts.Insert(accountsArray[i], fallible)) continue;
# ...
# }
#
# Additionally, RemoveAccount() has nested loops with IndexOf() for identity
# reuse checking, and GetAllIdentities() has nested loops for dedup:
#
# RemoveAccount O(A*I^2):
# for (auto identity : identities) {
# for (auto account : m_accounts) {
# auto pos = existingIdentities.IndexOf(identity); // O(I) per account
#
# GetAllIdentities O(A*I^2):
# for (auto identity : identities) {
# for (auto thisIdentity : result) { // O(accumulated) per identity
#
# Fix: Use nsTHashSet<nsCString> for identity key deduplication.