Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This rule is a generalization of STR37-C. Arguments to character-handling functions must be representable as an unsigned char.

Noncompliant Code Example

...

In this noncompliant example, the cast of *s to unsigned int may result in a value in excess of UCHAR_MAX because of integer promotions, consequently causing the function to violate ARR30-C. Do not form or use out of bounds pointers or array subscripts, leading to undefined behavior:

Code Block
bgColor#ffcccc
langc
#include <limits.h>
#include <stddef.h>
 
static const char table[UCHAR_MAX] = { 'a' /* ... */ };

ptrdiff_t first_not_in_table(const char *c_str) {
  for (const char *s = c_str; *s; ++s) {
    if (table[(unsigned)*s] != *s) {
      return s - c_str;
    }
  }
  return -1;
}

...

This compliant solution casts the value of type char value to unsigned char before allowing it to be implicitly promoted the implicit promotion to a larger unsigned type:

Code Block
bgColor#ccccff
langc
#include <limits.h>
#include <stddef.h>
 
static const char table[UCHAR_MAX] = { 'a' /* ... */ };

ptrdiff_t first_not_in_table(const char *c_str) {
  for (const char *s = c_str; *s; ++s) {
    if (table[(unsigned char)*s] != *s) {
      return s - c_str;
    }
  }
  return -1;
}

Risk Assessment

This Conversion of character data resulting in a value in excess of UCHAR_MAX is a subtle often missed error that results can result in a disturbingly broad range of potentially severe vulnerabilities.

...

...