Search code examples
cstringint

Converting int to string still works even when causing buffer overflow


I'm trying to convert int to a C-string using this code:

static char* copyString(const char* str)  
{
    char* new_String = malloc(strlen(str) + 1);
    return strcpy(new_String, str);
}
static char* mallocIntToString(const int num)
{
    char s[10]; // *************
    sprintf(s, "%d", num);
    char* copy = copyString(s);

    return copy;
}

I was wandering what is the biggest number I should insert in the line char s[10];.

I used 10 because its the max digits for an integer. However, this code also works for me when I use char s[9];, trying to convert the number 2147483647 to string, how is it possible?


Solution

  • I was wandering what is the biggest number I should insert in the line char s[10];.

    You should insert the maximum length between INT_MAX and INT_MIN defined in <limits.h>. INT_MIN should be -2147483648, so you need 11 + 1 = 12 characters (the additional one is for the string terminator \0).

    A correct implementation would be:

    static char* mallocIntToString(const int num)
    {
        char *s;
    
        s = malloc(12);
        if (s == NULL)
            return NULL;
    
        sprintf(s, "%d", num);    
        // Should probably also check for error here.
    
        return s;
    }
    

    However, this code also works for me when I use char s[9];, trying to convert the number 2147483647 to string, how is it possible?

    You're invoking undefined behavior, since writing past the end of an array is undefined behavior. When doing so, anything can happen. The program is not guaranteed to work correctly, but out of pure coincidence, it could still seem to work. What is happening in your code is that since the variable is defined on the stack, and the stack is writable, writing one or two bytes more does not change much because the program is still writing to valid memory. With that being said, it's still undefined behavior and should be avoided at all costs!

    To be 100% clear, you would be invoking undefined behavior even with char s[10]; or char s[11];, because in the case of INT_MIN the terminator would be written out of the array bounds.