An off-by-one error (OBOE), also commonly known as an OBOB (off-by-one bug), is a logic error involving the discrete equivalent of a boundary condition. It often occurs in computer programming when an iterative loop iterates one time too many or too few. This problem could arise when a programmer makes mistakes such as using "is less than or equal to" where "is less than" should have been used in a comparison or fails to take into account that a sequence starts at zero rather than one (as with array indices in many languages). This can also occur in a mathematical context.

Blow are some examples of off-by-one error:

Numeric Overflow

Wrong use of size_t parameter of strncpy() causes off-by-one error

Incorrect initiation and continuation condition causes off-by-one error


Check size or range of integer values to avoid numeric overflows

What You Should Not Do

Not checking the size or range of integer values input or stored in a program. This can cause indeterminate behavior or program failure.

unsigned short j = 65535;
...
j++;
...
if (j < 500)
{
    grant access to file X;
}

The range of an unsigned short int is 0 to 65,535. What happens if j is somehow changed to a value greater than 65,535? It loops back around beginning at 0 which may result in an incorrect file acesss.

What You Should Do

Checking or verifying integer values that can be set beyond the intended range or the range of the type. The key to this error is where and how j is set. If it is not possible to incorrectly set j, then the code will be safe. However, it is still a good programming practice to verify that a given value is in the intended range.

unsigned short j;
...
j++;
...
if(j < 65535) j++; else error!
if (j < 500)
{
  grant access to file X;
}

Concept Map

This example refers to the point MBad Code and 2 in the Concept Map.

 

Improper use of sizeof() function in strncpy() causes overflow

Definitions:

Off-by-one error Incorrect calculation of maximum and minimum value that is 1 more, or 1 less, than the correct value

What You Should Not Do

The main method uses the string copy method, strncpy(), to copy the command line user input file name and pattern to the Filename and Pattern character arrays respectively.

int main(int argc, char **argv)
{
  char Filename[256];
  char Pattern[32];

  /* Validate number of parameters and ensure valid content */
  ...

  /* copy filename parameter to variable, may cause off-by-one overflow */
  strncpy(Filename, argv[1], sizeof(Filename));

  /* copy pattern parameter to variable, may cause off-by-one overflow */
  strncpy(Pattern, argv[2], sizeof(Pattern));

  printf("Searching file: %s for the pattern: %s\n", Filename, Pattern);
  Scan_File(Filename, Pattern);
}

The sizeof() method call for the size parameter that does not take into account that the strncpy() will add a null terminator to each character array.Therefore, if the user enters a filename or pattern that are the same size as (or larger than) their respective character arrays a null terminator will be added beyond the end of the buffer for the character arrays creating an off-by-one buffer overflow. Also, memory address can be overwritten, if the character arrays are output to the user through the printf method the memory addresses at the overflow location may be output to the user.

What You Should Do

Subtract 1 from the sizeof() call to allow room for the null byte to be added.

/* copy filename parameter to variable, no off-by-one overflow */
strncpy(Filename, argv[2], sizeof(Filename)-1);

/* copy pattern parameter to variable, no off-by-one overflow */
strncpy(Pattern, argv[3], sizeof(Pattern)-1);

Concept Map

This example refers to the point M, Bad Code and 8 in the Concept Map. 

 Improper initialization and check condition of counter variable in a loop causes overflow errors

Definitions:

Off-by-one error Incorrect calculation of maximum and minimum value that is 1 more, or 1 less, than the correct value

What You Should Not Do

The code below wrong assignment of initial value of a counter variable for off-by-one errors. 

int arr[10]

int arr[10]
for (int i=0;i<=10;i++){
    arr[i]=i;
}

What You Should Do

The counter variable should be initialised to 0, since array indexing starts from 0.Also the continuation condition should be less than 10, since the array has been declared to be size of 10 and count starts from 0.

int arr[10]
for (int i=0;i<10;i++){
    arr[i]=i;
}
 

Concept Map

This example refers to the point M, Bad Code and 1 in the Concept Map.

 

JSN Teki template designed by JoomlaShine.com