39 lines
1.8 KiB
Diff
39 lines
1.8 KiB
Diff
# UNDF: UNDF-2026-000000894
|
||
# proton-0002: merge_user_dir extant_dirs list explosion O(D×P)
|
||
#
|
||
# File: proton (Python launch script)
|
||
# Function: merge_user_dir
|
||
# Line: 148
|
||
# Defect: `extant_dirs += dst_dir` on a list with a string iterates the string,
|
||
# adding each CHARACTER as a separate list element instead of the whole path.
|
||
# This is both a correctness defect (substring check `if dir_ in dst_dir` on
|
||
# single chars always matches any char present in the path) AND a CWE-407 defect:
|
||
# the list grows by O(P) elements per extant directory (P=path length ~60 chars),
|
||
# and each subsequent directory scans all accumulated characters.
|
||
# Impact: MEDIUM — Prefix migration during game launch. With D directories and P avg
|
||
# path length: O(D × D × P) total character comparisons instead of O(D²) path
|
||
# comparisons. Also causes premature directory skipping (correctness defect).
|
||
# Fix: Use `extant_dirs.append(dst_dir)` to add the whole path as one list element.
|
||
# Additionally convert extant_dirs to a set for O(1) prefix checking.
|
||
#
|
||
--- a/proton
|
||
+++ b/proton
|
||
@@ -119,13 +119,13 @@ def merge_user_dir(src, dst):
|
||
- extant_dirs = []
|
||
+ extant_dirs = set()
|
||
for src_dir, dirs, files in os.walk(src):
|
||
dst_dir = src_dir.replace(src, dst, 1)
|
||
|
||
#as described below, avoid merging game save subdirs, too
|
||
child_of_extant_dir = False
|
||
- for dir_ in extant_dirs:
|
||
- if dir_ in dst_dir:
|
||
+ for extant in extant_dirs:
|
||
+ if dst_dir.startswith(extant):
|
||
child_of_extant_dir = True
|
||
break
|
||
if child_of_extant_dir:
|
||
@@ -148,4 +148,4 @@ def merge_user_dir(src, dst):
|
||
else:
|
||
- extant_dirs += dst_dir
|
||
+ extant_dirs.add(dst_dir)
|