4

As an exercise, I created the following program:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX 100

int main(void)
{
    char message[MAX];
    char *p = message;
    char *q = message;
    char c = ' ';
    printf("Enter a message: ");
    while((c = toupper(getchar())) != '\n' && (p < message + MAX)) {
        if(isalpha(c))
            *p++ = c;
    }

    p--;
    while(*p == *q) {
        if((p == q) || (p == q - 1) || (p - 1 == q)) {
            printf("Palindrome\n");
            exit(0);
        }
        q++;
        p--;
    }

    printf("Not a palindrome\n");
    return 0;
}

Is it a problem/vulnerability, the fact that in the first while loop, when entering for the last time, p is pointing outside of the message[100] array?

I decrement it below, but I am wondering if it is considered a bad practice to have it behave this way.

stukov
  • 45
  • 1
  • 5
  • 2
    I don't see a problem. It would be out-of-bounds only when dereferenced. – rslemos Nov 22 '18 at 15:17
  • 1
    It is not a problem, the compiler and the code will work fine. But I cringe a bit when I see it, and personally would spend some time thinking about alternatives to avoid it. – Aganju Nov 22 '18 at 15:19
  • Please note that passing negavive values to functions from `` has undefined behaviour. Since `char` might be `signed` better cast to `char unsigned` before passing it to `toupper()`, `isalpha()` ... – Swordfish Nov 22 '18 at 15:20
  • @Swordfish if not, then `*p` has the previous value and is not incremented at all. I dunno why is this wrong. Care to elab? – stukov Nov 22 '18 at 16:07
  • @stukov Haha, thanks ;) You are right of course. – Swordfish Nov 22 '18 at 16:13

2 Answers2

4

Is it a problem/vulnerability?

No.

As long as you do not dereference it before you decrement it after the while loop. Otherwise, it will get out of bounds.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
4

The setting of p to point one element beyond the message array is allowed and defined by the C standards (per text from the standard quoted below).

The behavior of p-- is not defined by the C standard when the user enters a blank line.

When the user enters a blank line, the first while loop will not execute any iterations, and p will keep its initial value, set from message.

Then p-- decrements p so that it points outside message.

Pointers in C are not just numbers that are addresses; the C standard does not define arbitrary arithmetic for them. The C specification for postfix -- (C 2018 6.5.2.4 3 and 1) refers to the additive operators. The specification for those (6.5.6) says (paragraph 8):

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

Since, in this case, the result of p-- does not point to an element of message or one beyond it, the behavior is not defined by the C standard.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312