Versions Compared

Key

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

...

In the first noncompliant code example, ntbs is null terminated before the call to strncpy(). However, the subsequent execution of strncpy() can overwrite the null-termination character.

Code Block
bgColor#FFcccc
langc
char ntbs[NTBS_SIZE];

ntbs[sizeof(ntbs)-1] = '\0';
strncpy(ntbs, source, sizeof(ntbs));

Wiki Markup
In the second noncompliant code example, {{memset()}} is used to clear the destination buffer; unfortunately, the third argument incorrectly specifies the size of the destination array \[[Schwarz 2005|AA. Bibliography#Schwarz 05]\].

Code Block
bgColor#FFcccc
langc
char ntbs[NTBS_SIZE];

memset(ntbs, 0, sizeof(ntbs)-1);
strncpy(ntbs, source, sizeof(ntbs)-1);

...

The correct solution depends on the programmer's intent. If the intent was to truncate a string while ensuring that the result remains a null-terminated string, this solution can be used:

Code Block
bgColor#ccccff
langc
char ntbs[NTBS_SIZE];

strncpy(ntbs, source, sizeof(ntbs)-1);
ntbs[sizeof(ntbs)-1] = '\0';

...

If the intent is to copy without truncation, this example copies the data and guarantees that the resulting null-terminated byte string is null terminated. If the string cannot be copied, it is handled as an error condition.

Code Block
bgColor#ccccff
langc
char *source = "0123456789abcdef";
char ntbs[NTBS_SIZE];
/* ... */
if (source) {
  if (strlen(source) < sizeof(ntbs)) {
    strcpy(ntbs, source);
  }
  else {
    /* handle string too large condition */
  }
}
else {
  /* handle NULL string condition */
}

...

Wiki Markup
The {{strncpy_s()}} function copies up to {{n}} characters from the source array to a destination array \[[TR 24731|AA. Bibliography#ISO/IEC TR 24731-1-2007]\]. If no null character was copied from the source array, then the {{n{}}}th position in the destination array is set to a null character, guaranteeing that the resulting string is null-terminated.

Code Block
bgColor#ccccff
langc
char *source;
char a[NTBS_SIZE];
/* ... */
if (source) {
  errno_t err = strncpy_s(a, sizeof(a), source, 5);
  if (err != 0) {
    /* Handle error */
  }
}
else {
  /* handle NULL string condition */
}

...

The following noncompliant code example fails to ensure that cur_msg is properly null terminated:

Code Block
bgColor#ffcccc
langc
char *cur_msg = NULL;
size_t cur_msg_size = 1024;

/* ... */

void lessen_memory_usage(void) {
  char *temp;
  size_t temp_size;

  /* ... */

  if (cur_msg != NULL) {
    temp_size = cur_msg_size/2 + 1;
    temp = realloc(cur_msg, temp_size);
    if (temp == NULL) {
      /* Handle error condition */
    }
    cur_msg = temp;
    cur_msg_size = temp_size;
  }
}

/* ... */

...

In this compliant solution, the lessen_memory_usage() function ensures that the resulting string is always properly null terminated.

Code Block
bgColor#ccccff
langc
char *cur_msg = NULL;
size_t cur_msg_size = 1024;

/* ... */

void lessen_memory_usage(void) {
  char *temp;
  size_t temp_size;

  /* ... */

  if (cur_msg != NULL) {
    temp_size = cur_msg_size/2 + 1;
    temp = realloc(cur_msg, temp_size);
    if (temp == NULL) {
      /* Handle error condition */
    }
    cur_msg = temp;
    cur_msg_size = temp_size;

    /* ensure string is null-terminated */
    cur_msg[cur_msg_size - 1] = '\0';
  }
}

/* ... */

...