The vulnerability as described in ISO/IEC TR 24772-1:2019 clause 6.29 exists in C++.
C++ allows the modification of loop control variables within non range-based loops. This is usually not considered good programming practice as it can cause unexpected problems. The flexibility of C++ expects the programmer to use this capability responsibly.
Since the modification of a loop control variable within a loop is infrequently encountered, reviewers of C++ code may not expect it and hence miss noticing the modification. Modifying the loop control variable can cause unexpected results if not carefully done. In C++, the following is semantically correct, but is error-prone:
int a;
for (int i = 1; i < 10; i++){
...if (a > 7)
10;
i =
... }
which will cause the for loop to exit once a
is greater than 7
regardless of the number of iterations that have occurred.
for (int i : std::ranges::iota_view{1,10})
{if (a > 7) {
10; // This changes the local variable for this loop iteration's execution
i = // but subsequent iterations are not affected
}
}
for (int const i : std::ranges::iota_view{1,10})
{if (a > 7) {
10; // This is now illegal since the 'const int' prevents assign
i =
} }
The range for example immediately above does not have the vulnerability of the C-like for loop above.
for (int i=1; i < 10; ++i) ...
In a range-based for loop, the control variable is not available.
std::array a {3, 1, 4, 1, 5};
for (auto const x : a) {
std::cout << x << '\n';
}
To avoid the vulnerability or mitigate its ill effects, C++ software developers can:
Use the avoidance mechanisms of ISO/IEC 24772-1 clause 6.29.5.
Do not modify a loop control variable within a loop.
Use a range-for loop in preference to general loops.
Alternatively, use standard library generic algorithm functions like copy
, reduce
, transform
, inner_product
, etc. in preference to general loops.
Note: See also the C++ Core Guidelines ES.71, ES.86.