java-topology/defects/strawberry/patch/strawberry-0001-collectionwatcher-files-on-disk.patch

70 lines
2.5 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000839
# UNDF: (leave blank)
# CWE-407: CollectionWatcher::ScanSubdirectory QStringList files_on_disk O(S×F + F²)
#
# In ScanSubdirectory(), `files_on_disk` is a QStringList (linear container).
# Two O(N²) patterns exist:
#
# 1. The "deleted songs" detection loop (line ~826) iterates songs_in_db (S items)
# and calls files_on_disk.contains(file) for each — O(S×F) where F = files on disk.
# For a directory with 5,000 songs, this is ~25,000,000 string comparisons.
#
# 2. Multiple calls to files_on_disk.removeAll(file) inside the main scan loop
# (lines 662, 734, 793, 805) — each removeAll is O(F), called up to F times
# total → O(F²) aggregate.
#
# Additionally, t->files_changed_path_ (QStringList) is checked via .contains()
# in both the inner scan loop and the deleted-songs loop.
#
# Fix: convert files_on_disk to QSet<QString> for O(1) contains/remove.
# Convert files_changed_path_ to QSet<QString>.
#
# Severity: HIGH (collection scanner, runs on every library rescan)
# Speedup: ~250x at F=5000
--- a/src/collection/collectionwatcher.h
+++ b/src/collection/collectionwatcher.h
@@ -138,1 +138,1 @@
- QStringList files_changed_path_;
+ QSet<QString> files_changed_path_;
--- a/src/collection/collectionwatcher.cpp
+++ b/src/collection/collectionwatcher.cpp
@@ -577,1 +577,1 @@
- QStringList files_on_disk;
+ QSet<QString> files_on_disk;
@@ -629,1 +629,1 @@
- files_on_disk << child_filepath;
+ files_on_disk.insert(child_filepath);
@@ -643,2 +643,2 @@
- const QStringList files_on_disk_copy = files_on_disk;
- for (const QString &file : files_on_disk_copy) {
+ const QSet<QString> files_on_disk_copy = files_on_disk;
+ for (const QString &file : files_on_disk_copy) {
@@ -662,1 +662,1 @@
- files_on_disk.removeAll(file);
+ files_on_disk.remove(file);
@@ -734,1 +734,1 @@
- files_on_disk.removeAll(file);
+ files_on_disk.remove(file);
@@ -761,1 +761,1 @@
- files_on_disk.removeAll(file);
+ files_on_disk.remove(file);
@@ -770,2 +770,1 @@
- if (!t->files_changed_path_.contains(matching_filename)) {
- t->files_changed_path_ << matching_filename;
+ if (!t->files_changed_path_.contains(matching_filename)) {
+ t->files_changed_path_.insert(matching_filename);
@@ -793,1 +793,1 @@
- files_on_disk.removeAll(file);
+ files_on_disk.remove(file);
@@ -805,1 +805,1 @@
- files_on_disk.removeAll(file);
+ files_on_disk.remove(file);