Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does strcat_s crash if writing over the bound of a char array?

Tags:

c++

I know, there are already many posts about this topic, but I didn't find anything satisfiying. Even google was not my friend.

So, first my code:

    void secureCat() {
        const int BUFFERSIZE = 5;
        char buffer[BUFFERSIZE];

        strcpy_s (buffer, BUFFERSIZE, "01");
        cout << "1, buffer=" << buffer << endl;

        errno_t rc = 0;

        // still works
        rc = strcat_s(buffer, BUFFERSIZE, "2"); 

        cout << (rc == 0 ? "yippee" : "oh noooo") << endl;
        cout << "2, buffer=" << buffer << endl;

        // and now the crashing line
        rc = strcat_s(buffer, BUFFERSIZE, "345"); 

        cout << (rc == 0 ? "yippee" : "oh noooo") << endl;
        cout << "3, buffer=" << buffer << endl;
    }

I played with this code on Windows with MS VS 2010 and experienced the following:

The first call of strcat_s works fine, which is clear for me because the size of the new string ("01" + "2" + NUL character) is smaller then the buffer size.

But why does the second call crash, when the buffer size is exceeded? As far as I understand the MSDN, I should get an error code back and the buffer should only have the NUL character. The behavior in the example is more like that of strcat: I overwrite my own code, so it crashes.

BTW: I know, that there are other ways to concatenate strings and that it's a better style to do checks before it. So this is more for a pure interest to look behind the scenes.

Thanks, Robert

like image 606
Zostran Avatar asked Mar 19 '23 23:03

Zostran


1 Answers

The MSDN documentation for strcat_s() reads:

[...] if the destination string is too small, the invalid parameter handler is invoked, as described in Parameter Validation.

If you follow the Parameter Validation link, you can read (emphasis mine):

Invalid Parameter Handler Routine

[...] The default invalid parameter invokes Watson crash reporting, which causes the application to crash and asks the user if they want to load the crash dump to Microsoft for analysis. In Debug mode, an invalid parameter also results in a failed assertion.

This behavior can be changed by using the function _set_invalid_parameter_handler to set the invalid parameter handler to your own function. [...]


As an alternative, you may want to consider the StringCchCat() function, which returns an HRESULT equal to STRSAFE_E_INSUFFICIENT_BUFFER in case of destination buffer too small.

like image 86
Mr.C64 Avatar answered Apr 07 '23 14:04

Mr.C64