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.
Noncompliant Code Example
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 */ }
Compliant Solution
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 */ }
Exceptions
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 */ }
Risk Assessment
Failure to include break statements leads to unexpected control flow.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
MSC17-C |
medium |
likely |
low |
P6 |
L2 |
Automated Detection
Compass/ROSE can detect violations of this recommendation.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
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.
References
MSC16-C. Consider encrypting function pointers 49. Miscellaneous (MSC)