81 lines
3.1 KiB
Diff
81 lines
3.1 KiB
Diff
# UNDF: UNDF-2026-000000056
|
|
diff --git a/src/include/duckdb/planner/binder.hpp b/src/include/duckdb/planner/binder.hpp
|
|
index 31e7489..7b31df0 100644
|
|
--- a/src/include/duckdb/planner/binder.hpp
|
|
+++ b/src/include/duckdb/planner/binder.hpp
|
|
@@ -28,6 +28,7 @@
|
|
#include "duckdb/planner/bound_constraint.hpp"
|
|
#include "duckdb/planner/logical_operator.hpp"
|
|
#include "duckdb/common/enums/copy_option_mode.hpp"
|
|
+#include "duckdb/planner/column_binding_map.hpp"
|
|
|
|
//! fwd declare
|
|
namespace duckdb_re2 {
|
|
@@ -111,14 +112,21 @@ public:
|
|
|
|
void AddColumn(container_type::value_type info) {
|
|
// Add to beginning
|
|
+ correlated_binding_set.insert(info.binding);
|
|
correlated_columns.insert(correlated_columns.begin(), std::move(info));
|
|
delim_index++;
|
|
}
|
|
void AddColumnToBack(container_type::value_type info) {
|
|
// Add to end
|
|
+ correlated_binding_set.insert(info.binding);
|
|
correlated_columns.push_back(std::move(info));
|
|
}
|
|
|
|
+ //! CWE-407 fix: O(1) membership test replaces O(n) std::find over vector.
|
|
+ bool contains(const CorrelatedColumnInfo &info) const { // NOLINT: match stl case
|
|
+ return correlated_binding_set.count(info.binding) != 0;
|
|
+ }
|
|
+
|
|
void SetDelimIndexToZero() {
|
|
delim_index = 0;
|
|
}
|
|
@@ -141,6 +149,7 @@ public:
|
|
|
|
void clear() { // NOLINT: match stl case
|
|
correlated_columns.clear();
|
|
+ correlated_binding_set.clear();
|
|
}
|
|
|
|
container_type::iterator begin() { // NOLINT: match stl case
|
|
@@ -161,6 +170,8 @@ public:
|
|
|
|
private:
|
|
container_type correlated_columns;
|
|
+ //! CWE-407 fix: shadow set for O(1) membership tests in AddCorrelatedColumn / ExtractCorrelatedColumns.
|
|
+ column_binding_set_t correlated_binding_set;
|
|
idx_t delim_index;
|
|
};
|
|
|
|
diff --git a/src/planner/binder.cpp b/src/planner/binder.cpp
|
|
index bfbfdcb..bbd6fce 100644
|
|
--- a/src/planner/binder.cpp
|
|
+++ b/src/planner/binder.cpp
|
|
@@ -283,8 +283,8 @@ void Binder::MergeCorrelatedColumns(CorrelatedColumns &other) {
|
|
}
|
|
|
|
void Binder::AddCorrelatedColumn(const CorrelatedColumnInfo &info) {
|
|
- // we only add correlated columns to the list if they are not already there
|
|
- if (std::find(correlated_columns.begin(), correlated_columns.end(), info) == correlated_columns.end()) {
|
|
+ // CWE-407 fix: O(1) set membership check replaces O(n) std::find on vector.
|
|
+ if (!correlated_columns.contains(info)) {
|
|
correlated_columns.AddColumn(info);
|
|
}
|
|
}
|
|
diff --git a/src/planner/expression_binder/lateral_binder.cpp b/src/planner/expression_binder/lateral_binder.cpp
|
|
index e52eced..da3d623 100644
|
|
--- a/src/planner/expression_binder/lateral_binder.cpp
|
|
+++ b/src/planner/expression_binder/lateral_binder.cpp
|
|
@@ -16,7 +16,8 @@ void LateralBinder::ExtractCorrelatedColumns(Expression &expr) {
|
|
if (bound_colref.depth > 0) {
|
|
// add the correlated column info
|
|
CorrelatedColumnInfo info(bound_colref);
|
|
- if (std::find(correlated_columns.begin(), correlated_columns.end(), info) == correlated_columns.end()) {
|
|
+ // CWE-407 fix: O(1) set membership check replaces O(n) std::find on vector.
|
|
+ if (!correlated_columns.contains(info)) {
|
|
correlated_columns.AddColumn(std::move(info)); // TODO is adding to the front OK here?
|
|
}
|
|
}
|