Fixes for strnlen() in CStringChecker

[originally to Lenny and Ted]

So I started cleaning up strLengthCommon() in CStringChecker and ran into a problem concerning strnlen(). The code that's in there now handles the case where the limit argument is less than the string length, and works when it's greater. But when you can't say either with certainty, it's returning the string length by default right now. That then allows mistaken assumptions about the length of the string from then on.

Basically, this test fails:

void strnlen_is_not_strlen(char *x) {
if (strnlen(x, 10) != strlen(x))
   (void)*(char*)0; // expected-warning{{null}}

The problem is, fixing this breaks a number of other tests, like this one:

void strnlen_liveness(const char *x) {
if (strnlen(x, 10) < 5)
if (strnlen(x, 10) < 5)
   (void)*(char*)0; // no-warning

This is because this tells us nothing about the actual length of x, and we get two independent conjured values here. I don't know how we'd want to go about fixing this, or if we should at all.

Attached: the patch, including the new tests but without removing the now-broken ones. What's the best thing to do here?


strnlen.patch (7.99 KB)


I feel your pain. I was trying to fix this strnlen() issue and it just comes down to the fact that it is going to require some rework and I think that your approach looks like it is a good way to go.