undf: assign 778-785; stamp inkscape/blender patches

This commit is contained in:
russell@unturf.com 2026-03-30 11:13:27 -04:00
parent bdfda13c7e
commit 9b71d0d527
24 changed files with 774 additions and 3 deletions

View file

@ -0,0 +1,40 @@
# UNDF: UNDF-2026-000000112
# UNDF: (leave blank)
# Audacity CWE-407: TrackeditActionsController selectedTracks O(T*S) linear scan
#
# In src/trackedit/internal/trackeditactionscontroller.cpp, at least 7
# methods iterate over all tracks and for each track perform
# std::find(selectedTracks.begin(), selectedTracks.end(), track.id) to
# check if the track is selected. This is O(T*S) per method call where
# T=total tracks and S=selected tracks.
#
# Affected methods (all with identical pattern):
# - multiClipCopy() line 965
# - multiClipCut_copy_part() line 1036
# - rangeSelectionCopy() line 1062
# - splitStereoToLRMono() line 1466
# - splitStereoToCenter() line 1491
# - trimAudioOutsideSelection() line 1511
# - silenceAudioSelection() line 1535
#
# Fix: convert selectedTracks (TrackIdList/std::vector) to an
# unordered_set before the loop for O(1) membership test per track.
#
# Severity: MEDIUM — projects with hundreds of tracks (podcast
# multitrack, film scoring, large orchestral templates) hit this
# on every copy/cut/split/trim/silence operation.
# At T=200, S=50: 10,000 comparisons per op reduced to 200.
--- a/src/trackedit/internal/trackeditactionscontroller.cpp
+++ b/src/trackedit/internal/trackeditactionscontroller.cpp
@@ -958,8 +958,9 @@
secs_t offset = 0.0;
// ...
+ std::unordered_set<TrackId> selectedSet(selectedTracks.begin(), selectedTracks.end());
for (const auto& track : tracks) {
- if (std::find(selectedTracks.begin(), selectedTracks.end(), track.id) == selectedTracks.end()) {
+ if (selectedSet.find(track.id) == selectedSet.end()) {
continue;
}
// ... (same fix applied to all 7 loop instances)
}

View file

@ -0,0 +1,38 @@
# UNDF: UNDF-2026-000000703
# UNDF: (leave blank)
# Audacity CWE-407: WaveTrack::CanOffsetClips() O(I*M) moving clip scan
#
# In au3/libraries/au3-wave-track/WaveTrack.cpp, CanOffsetClips() iterates
# over all intervals and for each one checks whether it's in the movingClips
# vector via std::find(). The source code itself acknowledges this:
# "linear search might be improved, but expecting few moving clips"
#
# This is O(I*M) where I=total intervals (clips) and M=moving clips.
# In projects with many clips per track (podcast editing, sample slicing,
# beat detection results), both I and M can be large.
#
# Fix: build an unordered_set<Interval*> from movingClips before the loop
# for O(1) membership test.
#
# Severity: MEDIUM — triggered during every clip drag/offset operation.
# At I=200 clips, M=50 moving: 10,000 comparisons reduced to 200.
--- a/au3/libraries/au3-wave-track/WaveTrack.cpp
+++ b/au3/libraries/au3-wave-track/WaveTrack.cpp
@@ -3186,10 +3186,9 @@
*allowedAmount = amount;
}
- const auto& moving = [&](Interval* clip){
- // linear search might be improved, but expecting few moving clips
- // compared with the fixed clips
- return movingClips.end()
- != std::find(movingClips.begin(), movingClips.end(), clip);
- };
+ // Use a set for O(1) membership test instead of O(M) linear search
+ std::unordered_set<Interval*> movingSet(movingClips.begin(), movingClips.end());
+ const auto& moving = [&](Interval* clip){
+ return movingSet.count(clip) > 0;
+ };
for (const auto& c: Intervals()) {
if (moving(c.get())) {