diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected index f2f201053d9..7deb5de7541 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/NoSpaceForZeroTerminator.expected @@ -2,3 +2,10 @@ | test.c:32:20:32:25 | call to malloc | This allocation does not include space to null-terminate the string. | | test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. | | test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. | +| test.cpp:45:28:45:33 | call to malloc | This allocation does not include space to null-terminate the string. | +| test.cpp:55:28:55:33 | call to malloc | This allocation does not include space to null-terminate the string. | +| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. | +| test.cpp:71:28:71:33 | call to malloc | This allocation does not include space to null-terminate the string. | +| test.cpp:79:28:79:33 | call to malloc | This allocation does not include space to null-terminate the string. | +| test.cpp:89:35:89:40 | call to malloc | This allocation does not include space to null-terminate the string. | +| test.cpp:99:28:99:33 | call to malloc | This allocation does not include space to null-terminate the string. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp index e240d391224..13196226d8d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-131/semmle/NoSpaceForZeroTerminator/test.cpp @@ -11,11 +11,11 @@ void *malloc(size_t size); void free(void *ptr); size_t wcslen(const wchar_t *s); wchar_t* wcscpy(wchar_t* s1, const wchar_t* s2); - - - - - +int sprintf(char *s, const char *format, ...); +int wprintf(const wchar_t *format, ...); +char *strcat(char *s1, const char *s2); +size_t strlen(const char *s); +int strcmp(const char *s1, const char *s2); //// Test code ///// @@ -39,3 +39,64 @@ void good1(wchar_t *wstr) { wcscpy(wbuffer, wstr); free(wbuffer); } + +void bad3(char *str) { + // BAD -- zero-termination proved by sprintf (as destination) + char *buffer = (char *)malloc(strlen(str)); + sprintf(buffer, "%s", str); + free(buffer); +} + +void decode(char *dest, char *src); +void wdecode(wchar_t *dest, wchar_t *src); + +void bad4(char *str) { + // BAD -- zero-termination proved by wprintf (as parameter) + char *buffer = (char *)malloc(strlen(str)); + decode(buffer, str); + wprintf(L"%s", buffer); + free(buffer); +} + +void bad5(char *str) { + // BAD -- zero-termination proved by strcat (as destination) + char *buffer = (char *)malloc(strlen(str)); + buffer[0] = 0; + strcat(buffer, str); + free(buffer); +} + +void bad6(char *str, char *dest) { + // BAD -- zero-termination proved by strcat (as source) + char *buffer = (char *)malloc(strlen(str)); + decode(buffer, str); + strcat(dest, buffer); + free(buffer); +} + +void bad7(char *str, char *str2) { + // BAD -- zero-termination proved by strcmp + char *buffer = (char *)malloc(strlen(str)); + decode(buffer, str); + if (strcmp(buffer, str2) == 0) { + // ... + } + free(buffer); +} + +void bad8(wchar_t *str) { + // BAD -- zero-termination proved by wcslen + wchar_t *wbuffer = (wchar_t *)malloc(wcslen(str)); + wdecode(wbuffer, str); + if (wcslen(wbuffer) == 0) { + // ... + } + free(wbuffer); +} + +void good2(char *str, char *dest) { + // GOOD -- zero-termination not proven [FALSE POSITIVE] + char *buffer = (char *)malloc(strlen(str)); + decode(buffer, str); + free(buffer); +}