Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent strncpy_s from padding destination buffer in debug build?

I maintain a fairly large piece of legacy code that still uses strncpy a lot. I have now started the process of replacing the usage of strncpy with its safe counterpart strncpy_s. I noticed that strncpy_s is padding the destination buffer with -2 values - but only in debug builds! In release builds no padding occurs.

For instance:

char buffer[3];
// buffer becomes 00000000  00000000  00000000
memset(buffer, 0, sizeof(buffer));
// buffer becomes 01100001  00000000  11111110
//                97 ('a')  0        -2
strncpy_s(buffer, sizeof(buffer), "a", _TRUNCATE);
// i is -2
int i = buffer[2];

The MSDN docs do not mention this padding behaviour, and in my case it's really something I don't want because my legacy code relies on the fact that the zeroed parts of the buffer remain zeroed and are not overwritten during string copying.

Is there a way how I can prevent strncpy_s from padding the destination string in debug builds?

Note that I have tested this with both Visual Studio 2010 and Visual Studio 2013.

like image 559
herzbube Avatar asked Dec 15 '22 19:12

herzbube


2 Answers

The definition of strncpy_s is that elements beyond the null terminator take unspecified values. The definition of strncpy is that those elements are set to 0. If you don't want this behaviour, don't use strncpy_s.

Also, strncpy_s has different behaviour to strncpy in the case that the input is too big for the buffer.

There are few valid use cases for strncpy or strncpy_s. It's almost always better to either use strcpy, snprintf, or memcpy. My preference would strongly be to use whichever of those three functions is best suited to the task.

Calling it a "safe counterpart" is rather an exaggeration, IMO. The "non-safe" versions are actually all perfectly safe if you pass the correct arguments to them; and if you do not pass correct arguments then neither variety is safe.

If your code that uses strncpy is actually not bugged, and you rely on the zero-padding feature, then there is no reason to change it.

like image 66
M.M Avatar answered Dec 28 '22 23:12

M.M


strcpy_s() will fill in the buffer with 'FE' in debug mode only.

You can turn this off explicitly by calling _CrtSetDebugFillThreshold(0)

like image 37
Leo Chapiro Avatar answered Dec 28 '22 22:12

Leo Chapiro