Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Edited by NavBot (jp)

A switch statement consists of several case labels, 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 ends with a break; statement; if omitted, control flow falls through to the next case in the switch statement block. Because the break statement is not required, omitting it does not produce compiler diagnostics. If the omission was unintentional, this can result in an unexpected control flow.

Noncompliant Code Example

In this noncompliant code example, the case where widget_type is WE_W lacks a break statement. Consequently, statements that should only be executed when widget_type is WE_X are executed even when widget_type is WE_W.

Code Block
bgColor#FFCCCC
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

In this compliant solution, each sequence of statements following a case label ends with a break statement.

Code Block
bgColor#CCCCFF
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 */
}

A break statement is not required following the case where widget_type is WE_Y because there are no statements before the next case label, indicating that both WE_Y and WE_Z should be handled in the same fashion.

A break statement is not required following the default case because it would not effect the control flow.

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.

Code Block
bgColor#CCCCFF
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)