Monday, August 20, 2007

MIDL_USER_ALLOCATE and strcpy_s

I recently converted one of our very critical applications from Visual Studio 2003 to Visual Studio 2005. The application is RPC based and written in C++. In doing the conversion, I inadvertantly introduced a bug (is there any other way to introduce a bug?).

The original code looked like the following

*szResponse = (unsigned char *) midl_user_allocate(sizeof(unsigned char *) * (strlen(szTempResp)+1));
strcpy((char *)*szResponse, szTempResp);

After my conversion, the code looked like the following

*szResponse = (unsigned char *) midl_user_allocate(sizeof(unsigned char *) * (strlen(szTempResp)+1));
strcpy_s((char *)*szResponse, sizeof(szResponse)-1, szTempResp);


What it should have looked like is the following (I hope)

*szResponse = (unsigned char *) midl_user_allocate(sizeof(unsigned char *) * (strlen(szTempResp)+1));
memset(*szResponse, '\0', sizeof(unsigned char *) * (strlen(szTempResp)+1));
strcpy_s((char *)*szResponse, sizeof(unsigned char *) * strlen(szTempResp), szTempResp);


The problem was with the sizeof command. The szResponse variable is just a pointer, and therefore only a long is allocated, not a array of longs.

This one had me baffled for a couple of months, mainly because it would never show up in debug mode on my PC, but hit at random intervals in production under release mode. To compound the problem, the try catch block the code was in was missing a catch (...) clause, which meant the error fell through to the application instead of the thread handler, and caused a fatal error in the application.

Just another reason to convert to managed code!

No comments: