The vulnerability as described in ISO/IEC TR 24772-1:2019 clause 6.27 exists in C++.
Because of the way in which the switch-case statement in C++ is structured, it can be relatively easy to unintentionally omit the break statement between cases causing unintended execution of statements for some cases.
The switch statement has the form:
int abc = someExpression();
/* … */
switch (abc) {
case 1:
sval = “a”;break;
case 2:
sval = “b”;break;
case 3:
sval = “c”;break;
default:
throw SomeException();
}
If there isn’t a default case and the switched expression doesn’t match any of the cases, then control simply shifts to the next statement after the switch statement block. Unintentionally omitting a break statement between two cases will cause subsequent cases to be executed until a break or the end of the switch block is reached. This could cause unexpected results.
The attribute [[fallthrough]]
expresses the programmer’s intent that the code where it is placed is intended to fall through. If this attribute is not used, compilers typically diagnose the absence of a break statement.
To avoid the vulnerability or mitigate its ill effects, C++ software developers can:
Use the avoidance mechanisms of ISO/IEC 24772-1 clause 6.27.5
Use [[fallthrough]]
wherever fall-through is intended.
Terminate every case with either a flow control transfer or [[fallthrough]]
as illustrated in the following example:
```{.cpp}
int i;
. . .
switch (i) {
case 1:
[[fallthrough]]; // documents the intended fallthrough.
case 2:
i++;
break;
case 3:
j++;
[[fallthrough]]; // documents the intended fallthrough.
case 4: //other code
return 42;
default: throw CaseNotFound();
}
```
Adopt a style that permits your language processor and analysis tools to verify that all cases are covered. Where this is not possible, use a default clause that diagnoses the error.
See also the C++ Core Guidelines ES.78