A switch statement consists of several case label, plus a default label. The default label is optional, but recommended (see MSC01-C. Strive for logical completeness). A series of statements following a case label conventionally end with a break; statement; if omitted, control flow falls through to the next case in the switch statement block. Since the break statement is not required, omitting the break statement does not produce compiler warnings, and thus can produce unexpected control flow.
In this noncompliant code example, the case for when widget_type is WE_W lacks a break statement. Consequently, the statementsfor when widget_type is WE_X get executed even when widget_type is WE_W.
enum WidgetEnum { WE_W, WE_X, WE_Y, WE_Z } widget_type;
widget_type = WE_X;
switch (widget_type) {
case WE_W:
/* ... */
case WE_X:
/* ... */
break;
case WE_Y: case WE_Z:
/* ... */
break;
default: /* can't happen */
/* handle error condition */
}
|
enum WidgetEnum { WE_W, WE_X, WE_Y, WE_Z } widget_type;
widget_type = WE_X;
switch (widget_type) {
case WE_W:
/* ... */
break;
case WE_X:
/* ... */
break;
case WE_Y: case WE_Z:
/* ... */
break;
default: /* can't happen */
/* handle error condition */
}
|
MSC17:EX1: The last label in a switch statement requires no final break. This will conventionally be the default label.
MSC17:EX2: When control flow is intended to cross statement labels, it is permissible to omit the break statement. In these instances, the unusual control flow must be explicitly documented.
enum WidgetEnum { WE_W, WE_X, WE_Y, WE_Z } widget_type;
widget_type = WE_X;
switch (widget_type) {
case WE_W:
/* ... */
/* no break, process case for WE_X as well */
case WE_X:
/* ... */
break;
case WE_Y: case WE_Z:
/* ... */
break;
default: /* can't happen */
/* handle error condition */
}
|
Failure to include break statements leads to unexpected control flow.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
MSC17-C |
medium |
likely |
low |
P6 |
L2 |
Compass/ROSE can detect violations of this recommendation.
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
This rule appears in the C++ Secure Coding Standard as MSC18-CPP. Finish every set of statements associated with a case label with a break statement.
MSC16-C. Consider encrypting function pointers 49. Miscellaneous (MSC)