Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: in progress

...

Code Block
bgColor#ccccff
langc
void f(int n, int * restrict p, int * restrict q) {
   while (n-- > 0)
     *p++ = *q++; 
}
 
void g(void) {
  extern int d[100];

  /* ... */
  f(50, d + 50, d); /* valid */
}

Noncompliant Code Example

In this noncompliant code example, the call h(100, a, a, a) has undefined behavior because the object modifed by p is accessed by q and r.

 

Code Block
bgColor#FFCCCC
langc
void h(size_t n, int * restrict p, int * restrict q, int * restrict r) {
  for (size_t i = 0; i < n; i++)
    p[i] = q[i] + r[i];
}
 
void j(void) {

  int a[100]; 
  h(100, a, a, a);
}

The function g() declares an array d consisting of 100 int values and then invokes f() to copy memory from one area of the array to another. This call has undefined behavior because each of d[1]  through d[49]  is accessed through both p  and q .

Compliant Solution

In this compliant solution, an unmodified object is aliased through two restricted pointers. Because a  and b are disjoint arrays, a call of the form h(100, a, b, b)  has defined behavior, because array b  is not modified within function h .

Code Block
bgColor#ccccff
langc
void h(size_t n, int * restrict p, int * restrict q, int * restrict r) {
  for (size_t i = 0; i < n; i++)
    p[i] = q[i] + r[i];
}
 
void j(void) {
   int a[100]; 
   int b[100];
   h(100, a, b, b); 
}

   

Invoking Library Functions with restrict-qualified Pointers

...

If the objects referenced by arguments to functions overlap (meaning the objects share some common memory addresses), the behavior is undefined. See also undefined behavior 68 in Appendix J of the C Standard. The result of the functions is unknown and data may be corrupted. As a result, these functions must never be passed pointers to overlapping objects. If data must be copied between objects that share common memory addresses, a copy function guaranteed to work on overlapping memory, such as memmove(), should be used.

Noncompliant Code Example

In this noncompliant code example, the values of objects referenced by ptr1 and ptr2 become unpredictable after the call to memcpy() because their memory areas overlap:

Code Block
bgColor#FFCCCC
langc
#include <string.h>
 
void func(void) {
  char c_str[]= "test string";
  char *ptr1 = c_str;
  char *ptr2;

  ptr2 = ptr1 + 3;
  memcpy(ptr2, ptr1, 6);

  /* ... */
}

Compliant Solution

In this compliant solution, the call to memcpy() is replaced with a call to memmove(). The memmove() function performs the same operation as memcpy(), but copying takes place as if the n characters from the object pointed to by the source (ptr1) are first copied into a temporary array of n characters that does not overlap the objects pointed to by the destination (ptr2) or the source. The n characters from the temporary array are then copied into the object pointed to by the destination.

...

For formatted output functions such as printf(), it is unlikely that a programmer would modify the format string.  However, an attacker may attempt this if a program violates FIO30-C. Exclude user input from format strings and passes tainted values as part of the format string. 

Noncompliant Code Example

In this noncompliant code example, the programmer is attempting to overwrite the format string with a string value read in from stdin, and to use the modified string to input subsequent values:

...

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
/* ...  */
char format[100] = "%s";
int i; 
float x;
int n = scanf(format, format + 2, &i, &x);

Compliant Solution

The same results can be achieved as shown in this compliant solutoin.

...