configfile.c:63:14: warning: array subscript is above array [-Warray-bounds]

Jason A. Donenfeld Jason at zx2c4.com
Tue Jun 4 12:34:49 CEST 2013


Here is the function in question:

static int read_config_line(FILE *f, char *line, const char **value,
int bufsize)
{
        int i = 0, isname = 0;

        *value = NULL;
        while (i < bufsize - 1) {
                int c = next_char(f);
                if (!isname && (c == '#' || c == ';')) {
                        skip_line(f);
                        continue;
                }
                if (!isname && isspace(c))
                        continue;

                if (c == '=' && !*value) {
                        line[i] = 0;
                        *value = &line[i + 1];
                } else if (c == '\n' && !isname) {
                        i = 0;
                        continue;
                } else if (c == '\n' || c == EOF) {
                        line[i] = 0;
                        break;
                } else {
                        line[i] = c;
                }
                isname = 1;
                i++;
        }
        line[i + 1] = 0;
        return i;
}

The ways out of this loop are when it encounters a \n or EOF after
finding a name, or when i == bufsize - 1. In the former case, an extra
null terminator is needlessly added. In the latter, we write a null
into line[bufsize], which, as you've pointed out, is out of bounds.

I'll adjust it to this:

static int read_config_line(FILE *f, char *line, const char **value,
int bufsize)
{
        int i = 0, isname = 0;

        *value = NULL;
        while (i < bufsize - 1) {
                int c = next_char(f);
                if (!isname && (c == '#' || c == ';')) {
                        skip_line(f);
                        continue;
                }
                if (!isname && isspace(c))
                        continue;

                if (c == '=' && !*value) {
                        line[i] = 0;
                        *value = &line[i + 1];
                } else if (c == '\n' && !isname) {
                        i = 0;
                        continue;
                } else if (c == '\n' || c == EOF) {
                        break;
                } else {
                        line[i] = c;
                }
                isname = 1;
                i++;
        }
        line[i] = 0;
        return i;
}

Look good?

Thanks Kent.


More information about the CGit mailing list