...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <iostream> int GlobIglobI; double GlobDglobD; struct S { int Ii; S() : Ii(GlobIglobI++) {} }; struct T : S { double Dd; T() : S(), Dd(GlobDglobD++) {} }; void f(const S *SomeSessomeSes, std::size_t Countcount) { for (const S *Endend = SomeSessomeSes + Countcount; SomeSessomeSes != Endend; ++SomeSessomeSes) { std::cout << SomeSessomeSes->I>i << std::endl; } } int main() { T Testtest[5]; f(Testtest, 5); } |
This example would still be noncompliant if the for loop had instead been written to use array subscripting, as in the following:
| Code Block |
|---|
for (std::size_t i = 0; i < Countcount; ++i) { std::cout << SomeSessomeSes[i].Ii << std::endl; } |
Compliant Solution (Array)
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <iostream> int GlobIglobI; double GlobDglobD; struct S { int Ii; S() : Ii(GlobIglobI++) {} }; struct T : S { double Dd; T() : S(), Dd(GlobDglobD++) {} }; void f(const S * const *SomeSessomeSes, std::size_t Countcount) { for (const S * const *Endend = SomeSessomeSes + Countcount; SomeSessomeSes != Endend; ++SomeSessomeSes) { std::cout << (*SomeSessomeSes)->I>i << std::endl; } } int main() { S *Testtest[] = {new T, new T, new T, new T, new T}; f(Testtest, 5); for (auto Vv : Testtest) { delete Vv; } } |
The elements in the arrays are no longer polymorphic objects (instead, they are pointers to polymorphic objects), and so there is no undefined behavior with the pointer arithmetic.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <iostream> #include <vector> int GlobIglobI; double GlobDglobD; struct S { int Ii; S() : Ii(GlobIglobI++) {} }; struct T : S { double Dd; T() : S(), Dd(GlobDglobD++) {} }; template <typename Iter> void f(Iter Ii, Iter Ee) { for (; Ii != Ee; ++Ii) { std::cout << (*Ii)->I>i << std::endl; } } int main() { std::vector<S *> Testtest{new T, new T, new T, new T, new T}; f(Testtest.cbegin(), Testtest.cend()); for (auto Vv : Testtest) { delete Vv; } } |
Risk Assessment
Using arrays polymorphically can result in memory corruption, which could lead to an attacker being able to execute arbitrary code.
...