주요 콘텐츠

CWE Rule 193

Off-by-one Error

Since R2026a

Description

Off-by-one Error

Polyspace Implementation

The rule checker checks for these issues:

  • Use of dangerous standard function

  • Array access out of bounds

Examples

expand all

Issue

The Use of dangerous standard function check highlights uses of functions that are inherently dangerous or potentially dangerous given certain circumstances. The following table lists possibly dangerous functions, the risks of using each function, and what function to use instead.

Dangerous FunctionRisk LevelSafer Function
gets Inherently dangerous — You cannot control the length of input from the console. fgets
std::cin::operator>> and std::wcin::operator>>Inherently dangerous — You cannot control the length of input from the console.

Preface calls to cin by cin.width to control the input length. This method can result in truncated input.

To avoid potential buffer overflow and truncated input, use std::string objects as destinations for >> operator.

strcpy Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. strncpy
stpcpy Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. stpncpy
lstrcpy or StrCpyPossibly dangerous — If the source length is greater than the destination, buffer overflow can occur. StringCbCopy, StringCchCopy, strncpy, strcpy_s, or strlcpy
strcat Possibly dangerous — If the concatenated result is greater than the destination, buffer overflow can occur. strncat, strlcat, or strcat_s
lstrcat or StrCatPossibly dangerous — If the concatenated result is greater than the destination, buffer overflow can occur. StringCbCat, StringCchCat, strncay, strcat_s, or strlcat
wcpcpy Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. wcpncpy
wcscat Possibly dangerous — If the concatenated result is greater than the destination, buffer overflow can occur. wcsncat, wcslcat, or wcncat_s
wcscpy Possibly dangerous — If the source length is greater than the destination, buffer overflow can occur. wcsncpy
sprintf Possibly dangerous — If the output length depends on unknown lengths or values, buffer overflow can occur. snprintf
vsprintf Possibly dangerous — If the output length depends on unknown lengths or values, buffer overflow can occur. vsnprintf
Risk

These functions can cause buffer overflow, which attackers can use to infiltrate your program.

Fix

The fix depends on the root cause of the defect. Often the result details show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show the event history, you can trace back using right-click options in the source code and see previous related events. See also Interpret Polyspace Bug Finder Results in Polyspace Platform User Interface.

See examples of fixes below.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Example - Using sprintf
#include <stdio.h>
#include <string.h>
#include <iostream>

#define BUFF_SIZE 128


int dangerous_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;
}

This example function uses sprintf to copy the string str to dst. However, if str is larger than the buffer, sprintf can cause buffer overflow.

Correction — Use snprintf with Buffer Size

One possible correction is to use snprintf instead and specify a buffer size.

#include <stdio.h>
#include <string.h>
#include <iostream>

#define BUFF_SIZE 128


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

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

Array access out of bounds occurs when an array index falls outside the range [0...array_size-1] during array access.

Risk

Accessing an array outside its bounds is undefined behavior. You can read an unpredictable value or try to access a location that is not allowed and encounter a segmentation fault.

Fix

The fix depends on the root cause of the defect. For instance, you accessed an array inside a loop and one of these situations happened:

  • The upper bound of the loop is too large.

  • You used an array index that is the same as the loop index instead of being one less than the loop index.

To fix the issue, you have to modify the loop bound or the array index.

Another reason why an array index can exceed array bounds is a prior conversion from signed to unsigned integers. The conversion can result in a wrap around of the index value, eventually causing the array index to exceed the array bounds.

Often the result details show a sequence of events that led to the defect. You can implement the fix on any event in the sequence. If the result details do not show the event history, you can trace back using right-click options in the source code and see previous related events. See also Interpret Polyspace Bug Finder Results in Polyspace Platform User Interface.

See examples of fixes below.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Example - Array Access Out of Bounds Error
#include <stdio.h>

void fibonacci(void)
{
    int i;
    int fib[10];
 
    for (i = 0; i < 10; i++) 
       {
        if (i < 2) 
            fib[i] = 1;
         else 
            fib[i] = fib[i-1] + fib[i-2];
       }

    printf("The 10-th Fibonacci number is %i .\n", fib[i]);  //Noncompliant
}

The array fib is assigned a size of 10. An array index for fib has allowed values of [0,1,2,...,9]. The variable i has a value 10 when it comes out of the for-loop. Therefore, the printf statement attempts to access fib[10] through i.

Correction — Keep Array Index Within Array Bounds

One possible correction is to print fib[i-1] instead of fib[i] after the for-loop.

#include <stdio.h>

void fibonacci(void)
{
   int i;
   int fib[10];

   for (i = 0; i < 10; i++) 
    {
        if (i < 2) 
            fib[i] = 1;
        else 
            fib[i] = fib[i-1] + fib[i-2];
    }

    /* Fix: Print fib[9] instead of fib[10] */
    printf("The 10-th Fibonacci number is %i .\n", fib[i-1]); 
}

The printf statement accesses fib[9] instead of fib[10].

Check Information

Category: Numeric Errors
PQL Name: std.cwe_native.R193

Version History

Introduced in R2026a