# UNDF: UNDF-2026-000000031 diff --git a/src/Analyzer/ColumnTransformers.cpp b/src/Analyzer/ColumnTransformers.cpp index d5484e6c..5632ba67 100644 --- a/src/Analyzer/ColumnTransformers.cpp +++ b/src/Analyzer/ColumnTransformers.cpp @@ -264,20 +264,23 @@ ReplaceColumnTransformerNode::ReplaceColumnTransformerNode(const std::vectorsecond]; } void ReplaceColumnTransformerNode::dumpTreeImpl(WriteBuffer & buffer, FormatState & format_state, size_t indent) const @@ -329,6 +332,7 @@ QueryTreeNodePtr ReplaceColumnTransformerNode::cloneImpl() const result_replace_transformer->is_strict = is_strict; result_replace_transformer->replacements_names = replacements_names; + result_replace_transformer->replacements_index = replacements_index; return result_replace_transformer; } diff --git a/src/Analyzer/ColumnTransformers.h b/src/Analyzer/ColumnTransformers.h index 406f8ddd..68d37970 100644 --- a/src/Analyzer/ColumnTransformers.h +++ b/src/Analyzer/ColumnTransformers.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace re2 { @@ -304,6 +305,10 @@ private: } Names replacements_names; + // CWE-407 fix: shadow map for O(1) name→index lookup in findReplacementExpression(), + // replacing the O(n) std::find scan over replacements_names that was called in the + // O(columns × transformers) nested loop in QueryAnalyzer::resolveColumnsTransformers(). + std::unordered_map replacements_index; bool is_strict = false; static constexpr size_t replacements_child_index = 0;