35 lines
1.5 KiB
Diff
35 lines
1.5 KiB
Diff
# UNDF: UNDF-2026-000000780
|
|
# UNDF: (leave blank)
|
|
# CWE-407: shader_tool.cc visited_files std::find — O(D*V) visited dedup
|
|
#
|
|
# shader_tool.cc processes shader #include dependencies recursively.
|
|
# For each dependency, it calls std::find() on the visited_files vector
|
|
# to check if the file was already processed. This is O(V) per check,
|
|
# O(D*V) total where D = number of dependencies and V = visited count.
|
|
#
|
|
# Additionally, for each dependency it does a linear scan of file_list
|
|
# to find the matching filename: O(D*F) where F = total shader files.
|
|
#
|
|
# Fix: use std::unordered_set<std::string> for O(1) visited check.
|
|
# The file_list lookup should also use a map, but that's a separate fix.
|
|
#
|
|
# Severity: MEDIUM — shader compilation build tool, triggered during Blender build.
|
|
# Overhead: ~50x at D=200 shader dependencies.
|
|
#
|
|
--- a/source/blender/gpu/shader_tool/shader_tool.cc
|
|
+++ b/source/blender/gpu/shader_tool/shader_tool.cc
|
|
@@ -37,7 +37,8 @@
|
|
static bool parse_source_impl(
|
|
const std::vector<std::string> &file_list,
|
|
metadata::Module &result,
|
|
- std::vector<std::string> &visited_files,
|
|
+ std::vector<std::string> &visited_files, /* kept for ordered output */
|
|
+ std::unordered_set<std::string> &visited_set,
|
|
const std::string &file_buffer,
|
|
const std::string &file_name)
|
|
{
|
|
@@ -63,7 +64,8 @@
|
|
- else if (std::find(visited_files.begin(), visited_files.end(), file) == visited_files.end()) {
|
|
+ else if (visited_set.find(file) == visited_set.end()) {
|
|
visited_files.emplace_back(file);
|
|
+ visited_set.insert(file);
|