Skip to main content

IAR Embedded Workbench for Arm 9.70.x

CERT-ARR30-C_i

In this section:
Synopsis

Do not form or use out-of-bounds pointers or array subscripts.

Enabled by default

Yes

Severity/Certainty

High/High

highhigh.png
Full description

Invalid pointer operations could lead to undefined behavior. These include forming an out-of-bounds pointer or array index, dereferencing a past-the-end pointer or array index, accessing or generating a pointer past flexible array member, and null pointer arithmetic.

Coding standards
CERT ARR30-C

Do not form or use out of bounds pointers or array subscripts

CWE 119

Improper Restriction of Operations within the Bounds of a Memory Buffer

CWE 120

Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')

CWE 121

Stack-based Buffer Overflow

CWE 123

Write-what-where Condition

CWE 124

Buffer Underwrite ('Buffer Underflow')

CWE 126

Buffer Over-read

CWE 127

Buffer Under-read

CWE 129

Improper Validation of Array Index

CWE 786

Access of Memory Location Before Start of Buffer

Code examples

The following code example fails the check and will give a warning:

#include <stdlib.h>

struct S {
    size_t len;
    char buf[];  /* Flexible array member */
};

const char *find(const struct S *s, int c) {
    const char *first = s->buf;
    const char *last  = s->buf + s->len;

    while (first++ != last) { /* Undefined behavior */
        if (*first == (unsigned char)c) {
            return first;
        }
    }
    return NULL;
}

void g(void) {
    struct S *s = (struct S *)malloc(sizeof(struct S));
    if (s == NULL) {
        /* Handle error */
    }
    s->len = 0;
    find(s, 'a');
}

The following code example passes the check and will not give a warning about this issue:

#include <stdlib.h>

struct S {
    size_t len;
    char buf[];  /* Flexible array member */
};

const char *find(const struct S *s, int c) {
    const char *first = s->buf;
    const char *last  = s->buf + s->len;

    while (first != last) { /* Avoid incrementing here */
        if (*++first == (unsigned char)c) {
            return first;
        }
    }
    return NULL;
}

void g(void) {
    struct S *s = (struct S *)malloc(sizeof(struct S));
    if (s == NULL) {
        /* Handle error */
    }
    s->len = 0;
    find(s, 'a');
}