Main Content

AUTOSAR C++14 Rule A27-0-2

A C-style string shall guarantee sufficient space for data and the null terminator

Since R2020b

Description

Rule Definition

A C-style string shall guarantee sufficient space for data and the null terminator.

Rationale

C-style strings not only require space for the character data written but require one explicit character at the end for the additional null terminator. Failure to accommodate for the space required causes buffer overflow, leading to memory corruption, security vulnerabilities, and other issues.

Polyspace Implementation

The checker looks for these issues:

  • Use of a dangerous standard function.

    This issue occurs when you use C functions such as gets and strcpy, which write data to a buffer but do not inherently provide controls on the length of data written.

    For a more complete list of functions and their safer alternatives, see Use of dangerous standard function.

  • Buffer overflow from incorrect string format specifier.

    This issue occurs when the format specifier argument for C functions such as sscanf leads to an overflow or underflow in the memory buffer argument.

  • Destination buffer overflow in string manipulation.

    This issue occurs when certain C string manipulation functions write to their destination buffer argument at an offset greater than the buffer size.

    For instance, when calling the function sprintf(char* buffer, const char* format), you use a constant string format of greater size than buffer.

  • Insufficient destination buffer size

    This occurs when the destination buffer in a strcpy operation cannot accommodate the source buffer and a null terminator. The issue is reported if the size of the source buffer is unknown.

Troubleshooting

If you expect a rule violation but Polyspace® does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <cstdio>
#include <cstring>

#define BUFF_SIZE 128


int noncompliant_func(char *str) {
    char dst[BUFF_SIZE];
    int r = 0;

    if (sprintf(dst, "%s", str) == 1) { //Noncompliant
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}

int compliant_func(char *str) {
    char dst[BUFF_SIZE];
    int r = 0;

    if (snprintf(dst, sizeof(dst), "%s", str) == 1) { //Compliant
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}

In this example, the rule is violated when you use the sprintf function, which does not allow control on the length of data written. To avoid the possible buffer overflow, use the safer alternative function snprintf.

#include <cstdio>

void noncompliant_func (char *str[]) {
    char buf[32];
    sscanf(str[1], "%33c", buf); //Noncompliant
}

void compliant_func (char *str[]) {
    char buf[32];
    sscanf(str[1], "%32c", buf); //Compliant
}

In this example, the buffer buf can contain 32 char elements. Therefore, the format specifier %33c causes a buffer overflow and violates the rule. To avoid the rule violation, read a smaller number of elements into the buffer.

#include <cstdio>

void noncompliant_func(void) {
    char buf[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";

    sprintf(buf, fmt_string); //Noncompliant
}

void compliant_func(void) {
    char buf[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";

    snprintf(buf, 20, fmt_string); //Compliant
}

In this example, the buffer buf can contain 20 char elements. Therefore, the greater size of fmt_string causes a buffer overflow and violates the rule. To avoid the rule violation, use snprintf to enforce length control and read fewer than 20 elements into the buffer.

In this example, the size of the source buffer is unknown, while the size of the destination buffer is fixed at 128. The size of the destination buffer might not be sufficient to accommodate the characters from the source buffer and terminate the buffer with a null. Polyspace reports a violation of the rule.

#include <string.h>
  
int main(int argc, char *argv[]) {
  const char *const source = (argc && argv[0]) ? argv[0] : "";
  char destination[128];
  strcpy(const_cast<char*>(source), destination);//Noncompliant
  
  return 0;
}
Correction — Allocate Sufficient Memory for Destination

This violation is resolved by allocating sufficient memory for the destination buffer. For instance, use the function strlen() to calculate the size of the source buffer and allocate sufficient memory for the destination buffer so that it can accommodate all characters from the source buffer and the null terminator ('\0' ).

#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
  const char *const source = (argc && argv[0]) ? argv[0] : "";
  char* destination = (char *)malloc(strlen(source)+ 1);
  if(destination!=NULL){
      strcpy(const_cast<char*>(source), destination);//Compliant
  }else{
      /*Handle Error*/
  }
  //...
  free(destination);
  return 0;
}

Check Information

Group: Input/output library
Category: Advisory, Automated

Version History

Introduced in R2020b

expand all