java-topology/defects/suitecrm-0006/TICKET.md
russell@unturf.com 78e879c578 suitecrm: 5-MOAD scan; suitecrm-0005 ProjectTask getAllSubProjectTasks O(T^2*P) 70x, suitecrm-0006 LuceneSearch parseHits O(H*M) 8x
suitecrm-0005: modules/ProjectTask/ProjectTask.php getAllSubProjectTasks()
  BFS child-task traversal: while+foreach+in_array($parent_id, $potentialParentTaskIds)
  where $potentialParentTaskIds is already keyed by the same IDs stored as values.
  Fix: isset($potentialParentTaskIds[$parent_id]) — O(1) key lookup.
  Speedup: 70x at T=500 tasks.

suitecrm-0006: lib/Search/AOD/LuceneSearchEngine.php parseHits()
  foreach($hits) -> in_array($module, $modules) on constant filter list — O(H*M).
  Fix: array_flip($modules) once before loop, then isset() — O(H+M).
  Speedup: 8x at H=10000, M=100.

All 5 MOADs checked: 0002/0003/0004/0005 CLEAN (see existing marker).
SCAN-TODO.md updated: SuiteCRM marked scanned, 6 defects total.
2026-04-03 13:44:00 -04:00

1.2 KiB
Raw Blame History

suitecrm-0006 — LuceneSearchEngine parseHits O(H·M) in_array on constant module filter

CWE: CWE-407 (Algorithmic Complexity — Repeated Linear Scan) Severity: MEDIUM File: lib/Search/AOD/LuceneSearchEngine.php Function: parseHits()

Description

parseHits() filters search hits by allowed module names. The $modules array is a constant parameter across all loop iterations, but in_array() scans it linearly for every hit:

foreach ($hits as $hit) {
    if (!in_array($hit->record_module, $modules, true)) {  // O(M) per hit
        continue;
    }
    // ...
}

With H search hits and M allowed modules, total cost is O(H·M). Converting $modules to a hash set once before the loop reduces this to O(H + M).

Complexity

  • Unpatched: O(H · M)
  • Patched: O(H + M)
  • At H=10000 hits, M=50 modules: 500,000 comparisons → 10,050. 49× speedup.

Fix

$modules_set = array_flip($modules);  // O(M) once
foreach ($hits as $hit) {
    if (!isset($modules_set[$hit->record_module])) {  // O(1) per hit
        continue;
    }
    // ...
}

Benchmark

See test/test_suitecrm_0006.py — Python simulation confirms speedup.