2008-12-18 22:28:57 +01:00
/*
2009-01-21 21:04:20 +01:00
* Cppcheck - A tool for static C / C + + code analysis
2009-05-30 07:48:12 +02:00
* Copyright ( C ) 2007 - 2009 Daniel Marjamäki and Cppcheck team .
2008-12-18 22:28:57 +01:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2009-09-27 17:08:31 +02:00
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2008-12-18 22:28:57 +01:00
*/
2009-01-06 15:18:36 +01:00
# include "../src/tokenize.h"
# include "../src/checkbufferoverrun.h"
2008-12-18 22:28:57 +01:00
# include "testsuite.h"
# include <sstream>
extern std : : ostringstream errout ;
class TestBufferOverrun : public TestFixture
{
public :
TestBufferOverrun ( ) : TestFixture ( " TestBufferOverrun " )
{ }
private :
2009-01-05 16:49:57 +01:00
void check ( const char code [ ] )
2008-12-18 22:28:57 +01:00
{
// Tokenize..
Tokenizer tokenizer ;
std : : istringstream istr ( code ) ;
2009-01-05 16:49:57 +01:00
tokenizer . tokenize ( istr , " test.cpp " ) ;
2008-12-18 22:28:57 +01:00
// Assign variable ids
tokenizer . setVarId ( ) ;
2009-02-02 18:27:34 +01:00
tokenizer . simplifyTokenList ( ) ;
2008-12-18 22:28:57 +01:00
// Fill function list
tokenizer . fillFunctionList ( ) ;
// Clear the error buffer..
errout . str ( " " ) ;
// Check for buffer overruns..
Settings settings ;
settings . _showAll = true ;
2009-07-13 16:00:15 +02:00
CheckBufferOverrun checkBufferOverrun ( & tokenizer , & settings , this ) ;
2008-12-20 09:53:42 +01:00
checkBufferOverrun . bufferOverrun ( ) ;
2008-12-18 22:28:57 +01:00
}
void run ( )
{
2009-01-05 16:49:57 +01:00
TEST_CASE ( noerr1 ) ;
TEST_CASE ( noerr2 ) ;
TEST_CASE ( noerr3 ) ;
TEST_CASE ( noerr4 ) ;
2009-01-28 18:38:32 +01:00
2009-01-28 06:31:26 +01:00
TEST_CASE ( sizeof1 ) ;
2009-01-30 07:11:31 +01:00
TEST_CASE ( sizeof2 ) ;
2009-06-05 04:50:06 +02:00
TEST_CASE ( sizeof3 ) ;
2009-01-05 16:49:57 +01:00
TEST_CASE ( array_index_1 ) ;
TEST_CASE ( array_index_2 ) ;
TEST_CASE ( array_index_3 ) ;
TEST_CASE ( array_index_4 ) ;
TEST_CASE ( array_index_5 ) ;
TEST_CASE ( array_index_6 ) ;
TEST_CASE ( array_index_7 ) ;
TEST_CASE ( array_index_8 ) ;
TEST_CASE ( array_index_9 ) ;
TEST_CASE ( array_index_10 ) ;
TEST_CASE ( array_index_11 ) ;
TEST_CASE ( array_index_12 ) ;
2009-06-29 23:42:46 +02:00
TEST_CASE ( array_index_13 ) ;
2009-08-02 09:55:42 +02:00
TEST_CASE ( array_index_14 ) ;
TEST_CASE ( array_index_15 ) ;
TEST_CASE ( array_index_16 ) ;
TEST_CASE ( array_index_17 ) ;
2009-01-05 16:49:57 +01:00
TEST_CASE ( buffer_overrun_1 ) ;
TEST_CASE ( buffer_overrun_2 ) ;
2009-02-11 17:12:29 +01:00
TEST_CASE ( buffer_overrun_3 ) ;
2009-06-01 19:21:08 +02:00
TEST_CASE ( buffer_overrun_4 ) ;
2009-08-26 19:17:32 +02:00
TEST_CASE ( buffer_overrun_5 ) ;
2009-08-30 13:44:23 +02:00
TEST_CASE ( buffer_overrun_6 ) ;
2009-09-26 17:58:14 +02:00
TEST_CASE ( buffer_overrun_7 ) ;
2009-09-27 16:09:41 +02:00
TEST_CASE ( buffer_overrun_8 ) ;
2009-09-27 17:07:54 +02:00
TEST_CASE ( buffer_overrun_9 ) ;
2009-09-27 17:50:59 +02:00
TEST_CASE ( buffer_overrun_10 ) ;
2009-01-05 16:49:57 +01:00
2009-01-14 07:29:35 +01:00
TEST_CASE ( sprintf1 ) ;
2009-08-08 16:03:10 +02:00
TEST_CASE ( sprintf2 ) ;
2009-08-08 16:52:35 +02:00
TEST_CASE ( sprintf3 ) ;
2009-09-20 12:54:19 +02:00
TEST_CASE ( sprintf4 ) ;
2009-09-26 19:06:54 +02:00
TEST_CASE ( sprintf5 ) ;
2009-09-26 19:40:58 +02:00
TEST_CASE ( sprintf6 ) ;
2009-08-08 16:03:10 +02:00
2009-01-17 14:09:02 +01:00
TEST_CASE ( snprintf1 ) ;
2009-01-24 19:55:07 +01:00
TEST_CASE ( snprintf2 ) ;
TEST_CASE ( snprintf3 ) ;
2009-03-24 18:43:39 +01:00
TEST_CASE ( snprintf4 ) ;
2009-02-20 22:16:07 +01:00
TEST_CASE ( strncat1 ) ;
2009-02-20 22:00:59 +01:00
TEST_CASE ( strncat2 ) ;
2009-01-14 07:29:35 +01:00
2009-02-21 13:22:04 +01:00
TEST_CASE ( cin1 ) ;
2009-01-05 16:49:57 +01:00
TEST_CASE ( varid1 ) ;
TEST_CASE ( varid2 ) ;
2009-02-12 20:11:52 +01:00
TEST_CASE ( assign1 ) ;
2009-03-16 18:11:09 +01:00
TEST_CASE ( alloc ) ; // Buffer allocated with new
2009-03-25 07:25:10 +01:00
TEST_CASE ( memset1 ) ;
2009-09-25 18:23:44 +02:00
TEST_CASE ( counter_test ) ;
2009-09-25 22:32:18 +02:00
TEST_CASE ( strncpy1 ) ;
2008-12-18 22:28:57 +01:00
}
void noerr1 ( )
{
2009-01-05 16:49:57 +01:00
check ( " void f() \n "
" { \n "
" if (ab) \n "
" { \n "
" char str[50]; \n "
" } \n "
" if (ab) \n "
" { \n "
" char str[50]; \n "
" } \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void noerr2 ( )
{
2009-01-05 16:49:57 +01:00
check ( " void f1(char *str) \n "
" { \n "
" strcpy(buf,str); \n "
" } \n "
" void f2(char *str) \n "
" { \n "
" strcat(buf,str); \n "
" } \n "
" void f3(char *str) \n "
" { \n "
" sprintf(buf, \" %s \" ,str); \n "
" } \n "
" void f4(const char str[]) \n "
" { \n "
" strcpy(buf, str); \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void noerr3 ( )
{
2009-01-05 16:49:57 +01:00
check ( " static void f() \n "
" { \n "
" char data[1]; \n "
" return abc.data[1]; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void noerr4 ( )
{
// The memory isn't read or written and therefore there is no error.
2009-01-05 16:49:57 +01:00
check ( " static void f() \n "
" { \n "
" char data[100]; \n "
" const char *p = &data[100]; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-01-28 06:31:26 +01:00
void sizeof1 ( )
{
check ( " static void f() \n "
" { \n "
" char data[10]; \n "
" data[ sizeof(*data) ] = 0; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-28 06:31:26 +01:00
}
2009-01-30 07:11:31 +01:00
void sizeof2 ( )
{
check ( " static void f() \n "
" { \n "
" char data[10]; \n "
" data[ sizeof(data[0]) ] = 0; \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-30 07:11:31 +01:00
check ( " static void f() \n "
" { \n "
" int data[2]; \n "
" data[ sizeof(data[0]) ] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2009-01-30 07:11:31 +01:00
}
2009-06-05 04:50:06 +02:00
void sizeof3 ( )
{
check ( " void f() \n "
" { \n "
" char group[32]; \n "
" snprintf(group, sizeof(group), \" %u \" , 0); \n "
" struct group *gr; \n "
" snprintf(group, sizeof(group), \" %u \" , gr->gr_gid); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-01-28 06:31:26 +01:00
2008-12-18 22:28:57 +01:00
void array_index_1 ( )
{
check ( " void f() \n "
2009-01-05 16:49:57 +01:00
" { \n "
" char str[0x10]; \n "
" str[15] = 0; \n "
" str[16] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_2 ( )
{
check ( " void f() \n "
2009-01-05 16:49:57 +01:00
" { \n "
" char *str = new char[0x10]; \n "
" str[15] = 0; \n "
" str[16] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_3 ( )
{
2009-04-04 20:05:48 +02:00
{
check ( " void f() \n "
" { \n "
" int val[50]; \n "
2009-08-02 14:24:54 +02:00
" int i; \n "
2009-04-04 20:05:48 +02:00
" for (i = 0; i < 100; i++) \n "
" sum += val[i]; \n "
" } \n " ) ;
2009-08-02 14:24:54 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-04-04 20:05:48 +02:00
}
{
check ( " void f() \n "
" { \n "
" int val[50]; \n "
2009-08-02 14:24:54 +02:00
" int i; \n "
2009-04-04 20:05:48 +02:00
" for (i = 1; i < 100; i++) \n "
" sum += val[i]; \n "
" } \n " ) ;
2009-08-02 14:24:54 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-04-04 20:05:48 +02:00
}
{
check ( " void f(int a) \n "
" { \n "
" int val[50]; \n "
2009-08-02 14:24:54 +02:00
" int i; \n "
2009-04-04 20:05:48 +02:00
" for (i = a; i < 100; i++) \n "
" sum += val[i]; \n "
" } \n " ) ;
2009-08-02 14:24:54 +02:00
ASSERT_EQUALS ( " [test.cpp:6]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-04-04 20:05:48 +02:00
}
2008-12-18 22:28:57 +01:00
}
void array_index_4 ( )
{
2009-01-05 16:49:57 +01:00
check ( " const int SIZE = 10; \n "
" void f() \n "
" { \n "
" int i[SIZE]; \n "
" i[SIZE] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_5 ( )
{
2009-01-05 16:49:57 +01:00
check ( " void f() \n "
" { \n "
" int i[10]; \n "
" i[ sizeof(i) - 1 ] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_6 ( )
{
2009-01-05 16:49:57 +01:00
check ( " struct ABC \n "
" { \n "
" char str[10]; \n "
" }; \n "
" \n "
" static void f() \n "
" { \n "
" struct ABC abc; \n "
" abc.str[10] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:9]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_7 ( )
{
2009-01-05 16:49:57 +01:00
check ( " struct ABC \n "
" { \n "
" char str[10]; \n "
" }; \n "
" \n "
" static void f(ABC *abc) \n "
" { \n "
" abc->str[10] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_8 ( )
{
2009-01-05 16:49:57 +01:00
check ( " const int SIZE = 10; \n "
" \n "
" struct ABC \n "
" { \n "
" char str[SIZE]; \n "
" }; \n "
" \n "
" static void f() \n "
" { \n "
" struct ABC abc; \n "
" abc.str[SIZE] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:11]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_9 ( )
{
2009-01-05 16:49:57 +01:00
check ( " static void memclr( char *data ) \n "
" { \n "
" data[10] = 0; \n "
" } \n "
" \n "
" static void f() \n "
" { \n "
" char str[5]; \n "
" memclr( str ); // ERROR \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:9] -> [test.cpp:3]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_10 ( )
{
2009-01-05 16:49:57 +01:00
check ( " struct ABC \n "
" { \n "
" char str[10]; \n "
" }; \n "
" \n "
" static void memclr( char *data ) \n "
" { \n "
" data[10] = 0; \n "
" } \n "
" \n "
" static void f(ABC *abc) \n "
" { \n "
" memclr(abc->str); \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:13] -> [test.cpp:8]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_11 ( )
{
2009-01-05 16:49:57 +01:00
check ( " class ABC \n "
" { \n "
" public: \n "
" ABC(); \n "
" char *str[10]; \n "
" struct ABC *next; "
" }; \n "
" \n "
" static void f() \n "
" { \n "
" for ( ABC *abc = abc1; abc; abc = abc->next() ) \n "
" { \n "
" abc->str[10] = 0; \n "
" } \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:12]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void array_index_12 ( )
{
2009-01-05 16:49:57 +01:00
check ( " class Fred \n "
" { \n "
" private: \n "
" char str[10]; \n "
" public: \n "
" Fred(); \n "
" }; \n "
" Fred::Fred() \n "
" { \n "
" str[10] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:10]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-06-29 23:42:46 +02:00
void array_index_13 ( )
{
check ( " void f() \n "
" { \n "
" char buf[10]; \n "
" for (int i = 0; i < 100; i++) \n "
" { \n "
" if (i < 10) \n "
" int x = buf[i]; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-08-02 09:55:42 +02:00
}
void array_index_14 ( )
{
check ( " void f() \n "
" { \n "
" int a[10]; \n "
" for (int i = 0; i < 10; i++) \n "
" a[i+10] = i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
}
void array_index_15 ( )
{
check ( " void f() \n "
" { \n "
" int a[10]; \n "
" for (int i = 0; i < 10; i++) \n "
" a[10+i] = i; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
}
void array_index_16 ( )
{
check ( " void f() \n "
" { \n "
" int a[10]; \n "
" for (int i = 0; i < 10; i++) \n "
" a[i+1] = i; \n "
" } \n " ) ;
2009-08-02 14:26:26 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2009-08-02 09:55:42 +02:00
}
void array_index_17 ( )
{
check ( " void f() \n "
" { \n "
" int a[10]; \n "
" for (int i = 0; i < 10; i++) \n "
" a[i*2] = i; \n "
" } \n " ) ;
2009-08-02 14:26:26 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2009-06-29 23:42:46 +02:00
}
2009-06-01 19:21:08 +02:00
2008-12-18 22:28:57 +01:00
void buffer_overrun_1 ( )
{
2009-01-05 16:49:57 +01:00
check ( " void f() \n "
" { \n "
" char str[3]; \n "
" strcpy(str, \" abc \" ); \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void buffer_overrun_2 ( )
{
2009-01-05 16:49:57 +01:00
check ( " struct ABC \n "
" { \n "
" char str[5]; \n "
" }; \n "
" \n "
" static void f(ABC *abc) \n "
" { \n "
" strcpy( abc->str, \" abcdef \" ); \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:8]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-02-11 17:12:29 +01:00
void buffer_overrun_3 ( )
{
check ( " int a[10]; \n "
" \n "
" void foo() \n "
" { \n "
" int i; \n "
" for (i = 0; i <= 10; ++i) \n "
" a[i] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:7]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-02-11 17:12:29 +01:00
}
2009-06-01 19:21:08 +02:00
void buffer_overrun_4 ( )
{
check ( " void foo() \n "
" { \n "
" const char *p[2]; \n "
" for (int i = 0; i < 8; ++i) \n "
" p[i] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-06-02 18:56:53 +02:00
// No false positive
check ( " void foo(int x, int y) \n "
" { \n "
" const char *p[2]; \n "
" x = y * p[1]; \n "
" p[1] = 0; \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-06-01 19:21:08 +02:00
}
2009-02-11 17:12:29 +01:00
2009-08-26 19:17:32 +02:00
void buffer_overrun_5 ( )
{
check ( " void f() \n "
" { \n "
" char n[5]; \n "
" sprintf(n, \" d \" ); \n "
" printf( \" hello! \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-02-11 17:12:29 +01:00
2009-08-30 13:44:23 +02:00
void buffer_overrun_6 ( )
{
check ( " void f() \n "
" { \n "
" char n[5]; \n "
" strcat(n, \" abc \" ); \n "
" strcat(n, \" def \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-09-05 18:46:27 +02:00
check ( " void f() \n "
" { \n "
" char n[5]; \n "
" strcat(strcat(n, \" abc \" ), \" def \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-08-30 13:44:23 +02:00
}
2009-02-11 17:12:29 +01:00
2009-09-26 17:58:14 +02:00
void buffer_overrun_7 ( )
{
// ticket #731
check ( " void f() \n "
" { \n "
" char a[2]; \n "
" strcpy(a, \" a \\ 0 \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-27 16:09:41 +02:00
void buffer_overrun_8 ( )
{
// ticket #714
check ( " void f() \n "
" { \n "
" char a[5]; \n "
" for (int i = 0; i < 20; i+= 100) \n "
" { \n "
" a[i] = 0; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char a[5]; \n "
" for (int i = 0; i < 20; i = i + 100) \n "
" { \n "
" a[i] = 0; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char a[5]; \n "
" for (int i = 0; i < 20; i = 100 + i) \n "
" { \n "
" a[i] = 0; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-27 17:07:54 +02:00
void buffer_overrun_9 ( )
{
// ticket #738
check ( " void f() \n "
" { \n "
" char a[5]; \n "
" for (int i = 0; i < 20; ) \n "
" { \n "
" a[i] = 0; \n "
" i += 100; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-27 17:50:59 +02:00
void buffer_overrun_10 ( )
{
// ticket #740
check ( " void f() \n "
" { \n "
" char a[4]; \n "
" for (int i = 0; i < 4; i++) \n "
" { \n "
" char b = a[i]; \n "
" } \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-27 16:09:41 +02:00
2009-01-14 07:29:35 +01:00
void sprintf1 ( )
{
check ( " void f() \n "
" { \n "
" char str[3]; \n "
" sprintf(str, \" %s \" , \" abc \" ); \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-07-26 14:29:46 +02:00
check ( " void f() \n "
" { \n "
" char * c = new char[10]; \n "
" sprintf(c, \" %s \" , \" /usr/LongLongLongLongUserName/bin/LongLongApplicationName \" ); \n "
" delete [] c; \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-01-14 07:29:35 +01:00
}
2009-08-08 16:03:10 +02:00
void sprintf2 ( )
{
check ( " void f() \n "
" { \n "
" char str[5]; \n "
" sprintf(str, \" %d: %s \" , getnumber(), \" abcde \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-08-08 16:52:35 +02:00
}
2009-08-08 16:03:10 +02:00
2009-08-08 16:52:35 +02:00
void sprintf3 ( )
{
check ( " void f() \n "
" { \n "
" char str[3]; \n "
" sprintf(str, \" test \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char str[5]; \n "
" sprintf(str, \" test%s \" , " " ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-08-08 16:03:10 +02:00
}
2009-09-20 12:54:19 +02:00
void sprintf4 ( )
{
// ticket #690
check ( " void f() \n "
" { \n "
" char a[3]; \n "
" sprintf(a, \" %02ld \" , 99); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-26 19:06:54 +02:00
void sprintf5 ( )
{
// ticket #729
check ( " void f(bool condition) \n "
" { \n "
" char buf[3]; \n "
" sprintf(buf, \" %s \" , condition ? \" 11 \" : \" 22 \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2009-09-26 19:40:58 +02:00
void sprintf6 ( )
{
check ( " void f(bool condition) \n "
" { \n "
" char buf[3]; \n "
" sprintf(buf, \" %s \" , condition ? \" 11 \" : \" 222 \" ); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
}
2009-01-17 14:09:02 +01:00
void snprintf1 ( )
{
check ( " void f() \n "
" { \n "
" char str[5]; \n "
" snprintf(str, 10, \" %s \" , \" abc \" ); \n "
" } \n " ) ;
2009-05-31 21:48:55 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (error) snprintf size is out of bounds \n " , errout . str ( ) ) ;
2009-01-17 14:09:02 +01:00
}
2009-01-24 19:55:07 +01:00
void snprintf2 ( )
{
check ( " void f() \n "
" { \n "
" char str[5]; \n "
" snprintf(str, 5, \" %s \" , \" abc \" ); \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-24 19:55:07 +01:00
}
void snprintf3 ( )
{
check ( " void f() \n "
" { \n "
" char str[5]; \n "
" snprintf(str, sizeof str, \" %s \" , \" abc \" ); \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-01-24 19:55:07 +01:00
}
2009-03-24 18:43:39 +01:00
void snprintf4 ( )
{
check ( " void f(int x) \n "
" { \n "
" char str[5]; \n "
" snprintf(str, 8 - x, \" abcdefghijkl \" ); \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2009-03-24 18:43:39 +01:00
}
2009-01-17 14:09:02 +01:00
2009-01-14 07:29:35 +01:00
2008-12-18 22:28:57 +01:00
2009-02-20 21:00:49 +01:00
void strncat1 ( )
{
check ( " void f() \n "
" { \n "
2009-02-20 22:16:07 +01:00
" char str[16]; \n "
" strncpy(str, a, 10); \n "
" strncat(str, b, 10); \n "
2009-02-20 21:00:49 +01:00
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Dangerous usage of strncat. Tip: the 3rd parameter means maximum number of characters to append \n " , errout . str ( ) ) ;
2009-02-20 21:00:49 +01:00
}
void strncat2 ( )
{
check ( " void f() \n "
" { \n "
" char str[5]; \n "
" strncat(str, a, 5); \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Dangerous usage of strncat. Tip: the 3rd parameter means maximum number of characters to append \n " , errout . str ( ) ) ;
2009-02-20 21:00:49 +01:00
}
2009-02-21 13:22:04 +01:00
void cin1 ( )
{
check ( " void f() \n "
" { \n "
" char str[10]; \n "
" cin >> str; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
2009-02-21 13:22:04 +01:00
}
2009-02-20 21:00:49 +01:00
2008-12-18 22:28:57 +01:00
void varid1 ( )
{
2009-01-05 16:49:57 +01:00
check ( " void foo() \n "
" { \n "
" char str[10]; \n "
" if (str[0]) \n "
" { \n "
" char str[50]; \n "
" str[30] = 0; \n "
" } \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
void varid2 ( )
{
2009-01-05 16:49:57 +01:00
check ( " void foo() \n "
" { \n "
" char str[10]; \n "
" if (str[0]) \n "
" { \n "
" char str[50]; \n "
" memset(str,0,50); \n "
" } \n "
" } \n " ) ;
2009-06-05 02:39:36 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
2008-12-18 22:28:57 +01:00
}
2009-02-12 20:11:52 +01:00
void assign1 ( )
{
check ( " char str[3] = {'a', 'b', 'c'}; \n "
" \n "
" void foo() \n "
" { \n "
" str[3] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2009-02-12 20:11:52 +01:00
}
2009-03-16 18:11:09 +01:00
void alloc ( )
{
check ( " void foo() \n "
" { \n "
" char *s = new char[10]; \n "
" s[10] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2009-03-16 18:11:09 +01:00
check ( " void foo() \n "
" { \n "
" char *s = malloc(10); \n "
" s[10] = 0; \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Array index out of bounds \n " , errout . str ( ) ) ;
2009-03-16 18:11:09 +01:00
}
2009-03-25 07:25:10 +01:00
void memset1 ( )
{
check ( " void foo() \n "
" { \n "
" char s[10]; \n "
" memset(s, 5, '*'); \n "
" } \n " ) ;
2009-07-13 10:16:31 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) The size argument is given as a char constant \n " , errout . str ( ) ) ;
2009-03-25 07:25:10 +01:00
}
2009-09-25 18:23:44 +02:00
void counter_test ( )
{
2009-09-27 22:13:15 +02:00
ASSERT_EQUALS ( 6 , CheckBufferOverrun : : count ( " Hello " ) ) ;
ASSERT_EQUALS ( 2 , CheckBufferOverrun : : count ( " s " ) ) ;
ASSERT_EQUALS ( 2 , CheckBufferOverrun : : count ( " i " ) ) ;
ASSERT_EQUALS ( 2 , CheckBufferOverrun : : count ( " %d " ) ) ;
ASSERT_EQUALS ( 2 , CheckBufferOverrun : : count ( " %1d " ) ) ;
ASSERT_EQUALS ( 3 , CheckBufferOverrun : : count ( " %2.2d " ) ) ;
ASSERT_EQUALS ( 1 , CheckBufferOverrun : : count ( " %s " ) ) ;
ASSERT_EQUALS ( 6 , CheckBufferOverrun : : count ( " %-5s " ) ) ;
2009-09-29 17:02:19 +02:00
ASSERT_EQUALS ( 2 , CheckBufferOverrun : : count ( " \\ \" " ) ) ;
2009-09-29 17:51:29 +02:00
TODO_ASSERT_EQUALS ( 6 , CheckBufferOverrun : : count ( " Hello \\ 0Text " ) ) ;
2009-09-29 20:50:22 +02:00
TODO_ASSERT_EQUALS ( 2 , CheckBufferOverrun : : count ( " %% " ) ) ;
2009-09-25 18:23:44 +02:00
}
2009-09-25 22:32:18 +02:00
void strncpy1 ( )
{
check ( " void f() \n "
" { \n "
" char a[6]; \n "
" char c[7]; \n "
" strcpy(a, \" hello \" ); \n "
" strncpy(c,a,sizeof(c)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char a[6]; \n "
" char c[6]; \n "
" strcpy(a, \" hello \" ); \n "
" strncpy(c,a,sizeof(c)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char a[6]; \n "
" char c[5]; \n "
" strcpy(a, \" hello \" ); \n "
" strncpy(c,a,sizeof(c)+1); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:6]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char c[6]; \n "
" strncpy(c, \" hello! \" ,sizeof(c)); \n "
" } \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char c[6]; \n "
" strncpy(c, \" hello! \" ,sizeof(c)+1); \n "
" } \n " ) ;
ASSERT_EQUALS ( " [test.cpp:4]: (possible error) Buffer overrun \n " , errout . str ( ) ) ;
}
2008-12-18 22:28:57 +01:00
} ;
2009-01-05 16:49:57 +01:00
REGISTER_TEST ( TestBufferOverrun )
2008-12-18 22:28:57 +01:00