# UNDF: UNDF-2026-000000177 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -9376,8 +9376,12 @@ bool setup_fields(THD *thd, Access_bitmask want_privilege, bool allow_sum_func, Ref_item_array ref = ref_item_array; - for (auto it = fields->begin(); it != fields->end(); ++it) { - const size_t old_size = fields->size(); - Item *item = *it; + // CWE-407 fix (mysql-0003): use index-based loop so that iterator + // recovery after split_sum_func() does not require an O(F) std::find + // scan. split_sum_func() only ever appends new items to the END of + // `fields`, so the index of the current item is stable; the loop + // re-evaluates fields->size() each iteration to pick up appended items. + for (size_t field_idx = 0; field_idx < fields->size(); ++field_idx) { + Item *item = (*fields)[field_idx]; assert(!item->hidden); - Item **item_pos = &*it; + Item **item_pos = &(*fields)[field_idx]; if ((!item->fixed && item->fix_fields(thd, item_pos)) || (item = *item_pos)->check_cols(1)) { DBUG_PRINT("info", @@ -9460,9 +9464,7 @@ bool setup_fields(THD *thd, Access_bitmask want_privilege, bool allow_sum_func, } } - select->select_list_tables |= item->used_tables(); - - if (old_size != fields->size()) { - // Items have been added (either by fix_fields or by split_sum_func), so - // our iterator is invalidated. Reconstruct it. - it = std::find(fields->begin(), fields->end(), item); - } + select->select_list_tables |= item->used_tables(); + // No iterator recovery needed: index loop is stable under append-only + // growth of fields (split_sum_func only appends to the back). }