Batch 6 (9): dolibarr, jitsi-videobridge, zed, tryton, suricata, strawberry, zulip, zesarux, zephyr Batch 7 (15): xonotic (4), xash3d (3), xenia, xtuple, zabbix (2), zathura, zebra, yabause, zephyr-0001 Batch 8 (15): woodpecker (2), wine (4), widelands (3), wesnoth (3), wekan (3) Mix of CWE-407 and CWE-312.
3.1 KiB
Battle for Wesnoth — CWE-407 Disclosure Brief (wesnoth-0003)
2026-04-13 · Patch available — awaiting upstream merge
Finding
One O(n²) defect in Wesnoth's unit type system. combine_special_notes() and its helper append_special_note() use utils::contains() (linear scan) on a std::vector<t_string> to deduplicate special notes when building unit type descriptions. Each note insertion scans the full list, producing O(N²) where N = total notes from all sources.
The Defect
wesnoth-0003 (PATCHED — LOW): src/units/types.cpp:458
// append_special_note — called per note from abilities, attacks, movement:
static void append_special_note(std::vector<t_string>& notes, const t_string& new_note) {
if (new_note.empty()) return;
if (utils::contains(notes, new_note)) return; // O(N) linear scan
notes.push_back(new_note);
}
// combine_special_notes — aggregates from 4+ sources:
for (const auto& note : direct) { append_special_note(notes, note); }
for (const auto [key, cfg] : abilities.all_children_view()) { ... append_special_note(...) }
for (const auto& attack : attacks) { ... append_special_note(...) }
for (const auto& move_note : mt.special_notes()) { append_special_note(notes, move_note); }
Units with many abilities, attack types, and movement specials accumulate notes from multiple sources. Each note insertion scans all previously added notes.
Complexity Proof
At N=50 special notes (complex unit with many abilities and attacks):
- Defective: 1 + 2 + ... + 50 = 1,275 string comparisons
- Fixed: 50 set lookups
- ~25× op reduction. Fires during unit type initialization and display.
Impact
Wesnoth loads unit type data on game start and when displaying unit information panels. Modded games with complex unit types (many abilities, weapon specials, movement properties) accumulate dozens of special notes. While the absolute cost is moderate for vanilla units, heavily modded scenarios with custom unit types amplify the quadratic path.
The Fix
Use std::set<std::string> for O(log N) dedup lookups instead of O(N) vector scan:
// Before
if (utils::contains(notes, new_note)) return;
// After
// CWE-407 fix: set for O(log N) dedup instead of O(N) vector scan.
std::set<std::string> seen;
std::string key(note.c_str());
if (!key.empty() && seen.insert(key).second) {
notes.push_back(note);
}
Patch
Fix available: defects/wesnoth-0003/patch/wesnoth-0003.patch
Single-file patch in src/units/types.cpp. Inlines dedup logic with std::set<std::string>, eliminates append_special_note dependency on utils::contains. ~25× speedup at N=50.
What We Ask
A patch is ready for review.
- Confirm receipt and assign a GitHub issue reference (wesnoth/wesnoth).
- Assess severity — fires during unit type initialization and info display.
- Coordinate a disclosure date — we target 90 days from first contact.
- We will credit the Wesnoth team in the public disclosure. Preferred acknowledgment format welcome.
Contact: see cover email. This brief is confidential until coordinated disclosure.