cpputest/cpputest — pull request #298 by arstrube (2014-05-29 07:46:51+00:00)
Title: strncpy_s(target, size+1, source, size).

I put this up for discussion.

Why and how does this work?

strncpy(target, size, source, size) will raise an exception, because strncpy_s() recognizes there is no space for an _extra_ '\0'.

Therefore, we need strncpy_s(target, size+1, source, size). But then of course, size must not include the terminating '\0' as it used to do in SimpleString. It must be strlen(source).

I believe doing something like:

size_t len = strlen(source);
char * target = malloc(len+1);
strncpy(target, source, len);
target[len] = '\0';

could be seen as general best practice for using strncpy(), no?

1. The Good: This is relatively safe on all platforms. There will be no run-away strings.

2. The Bad: It is possible to write code that will compile fine but break when compiled for Microsoft, as in: PlatformSpecificStrncpy(target, source, strlen(target)+1).

3. The Ugly: It is not possible to prevent writing beyond the end of the target buffer (but unlikely that this would happen, given the actual implementation of SimpleString.

I would probably favor putting the zero-termination into SimpleString, in order to keep PlatformSpecificStrncpy() compatible with strncpy(), even though this means a bit of code duplication and could, potentially, be forgotten.