Merge pull request #127 from rofl0r/master
sanitize the descriptive text displayed for "varFuncNullUB"
This commit is contained in:
commit
27eedcd0a3
|
@ -3793,11 +3793,12 @@ void CheckOther::varFuncNullUBError(const Token *tok)
|
||||||
reportError(tok,
|
reportError(tok,
|
||||||
Severity::portability,
|
Severity::portability,
|
||||||
"varFuncNullUB",
|
"varFuncNullUB",
|
||||||
"Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n"
|
"Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\n"
|
||||||
"Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n"
|
"Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\n"
|
||||||
"The behaviour is undefined when NULL is #defined as 0, sizeof(int)!=sizeof(void*) and the function expects a pointer. Otherwise the behaviour is defined.\n"
|
"The C99 standard, in section 7.15.1.1, states that if the type used by va_arg() is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined.\n"
|
||||||
"See section section 7.1.4 and section 7.15.1.1 in the C standard. Section 7.1.4 explains that the function call is UB. Section 7.15.1.1 explains that the va_arg macro has UB.\n"
|
"The value of the NULL macro is an implementation-defined null pointer constant (7.17), which can be any integer constant expression with the value 0, or such an expression casted to (void*) (6.3.2.3). This includes values like 0, 0L, or even 0LL.\n"
|
||||||
"To reproduce you might be able to use this little code example. Try it on a platform where sizeof(int)!=sizeof(void*), for instance on a x86_64 machine. If ERROR is written by the program on the screen it means that 0 is not converted to a NULL pointer. Changing the 0 to (void*)0 will fix the program.\n"
|
"In practice on common architectures, this will cause real crashes if sizeof(int) != sizeof(void*), and NULL is defined to 0 or any other null pointer constant that promotes to int.\n"
|
||||||
|
"To reproduce you might be able to use this little code example on 64bit platforms. If the output includes \"ERROR\", the sentinel had only 4 out of 8 bytes initialized to zero and was not detected as the final argument to stop argument processing via va_arg(). Changing the 0 to (void*)0 or 0L will make the \"ERROR\" output go away.\n"
|
||||||
"#include <stdarg.h>\n"
|
"#include <stdarg.h>\n"
|
||||||
"#include <stdio.h>\n"
|
"#include <stdio.h>\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -3816,7 +3817,7 @@ void CheckOther::varFuncNullUBError(const Token *tok)
|
||||||
" char *s2 = \"x\";\n"
|
" char *s2 = \"x\";\n"
|
||||||
" char *s3 = \"ERROR\";\n"
|
" char *s3 = \"ERROR\";\n"
|
||||||
"\n"
|
"\n"
|
||||||
" // changing 0 to 0L makes the error go away on x86_64\n"
|
" // changing 0 to 0L for the 7th argument (which is intended to act as sentinel) makes the error go away on x86_64\n"
|
||||||
" f(\"first\", s2, s2, s2, s2, s2, 0, s3, (char*)0);\n"
|
" f(\"first\", s2, s2, s2, s2, s2, 0, s3, (char*)0);\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
@ -6805,7 +6805,7 @@ private:
|
||||||
void varFuncNullUB() { // #4482
|
void varFuncNullUB() { // #4482
|
||||||
check("void a(...);\n"
|
check("void a(...);\n"
|
||||||
"void b() { a(NULL); }");
|
"void b() { a(NULL); }");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (portability) Passing NULL to a function with variable number of arguments leads to undefined behaviour on some platforms.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (portability) Passing NULL after the last typed argument to a variadic function leads to undefined behaviour.\n", errout.str());
|
||||||
|
|
||||||
check("void a(char *p, ...);\n"
|
check("void a(char *p, ...);\n"
|
||||||
"void b() { a(NULL, 2); }");
|
"void b() { a(NULL, 2); }");
|
||||||
|
|
Loading…
Reference in New Issue