2010-08-14 20:13:46 +02:00
/*
* Cppcheck - A tool for static C / C + + code analysis
2013-01-01 17:29:08 +01:00
* Copyright ( C ) 2007 - 2013 Daniel Marjamäki and Cppcheck team .
2010-08-14 20:13:46 +02: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
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "tokenize.h"
# include "checkobsoletefunctions.h"
# include "testsuite.h"
# include <sstream>
extern std : : ostringstream errout ;
2011-10-13 20:53:06 +02:00
class TestObsoleteFunctions : public TestFixture {
2010-08-14 20:13:46 +02:00
public :
2013-08-07 16:27:37 +02:00
TestObsoleteFunctions ( ) : TestFixture ( " TestObsoleteFunctions " ) {
}
2010-08-14 20:13:46 +02:00
private :
2011-10-13 20:53:06 +02:00
void run ( ) {
2010-08-29 12:01:32 +02:00
TEST_CASE ( testbsd_signal ) ;
TEST_CASE ( testgethostbyname ) ;
TEST_CASE ( testgethostbyaddr ) ;
TEST_CASE ( testusleep ) ;
TEST_CASE ( testindex ) ;
2011-12-09 21:00:57 +01:00
TEST_CASE ( test_qt_index ) ; // FP when using the Qt function 'index'?
2010-08-29 12:01:32 +02:00
TEST_CASE ( testrindex ) ;
// no false positives for variables
2010-08-31 18:58:01 +02:00
TEST_CASE ( testvar ) ;
2010-08-31 19:48:04 +02:00
2010-08-31 18:58:01 +02:00
// dangerous function
TEST_CASE ( testgets ) ;
2011-09-24 10:54:58 +02:00
2011-10-06 08:10:51 +02:00
TEST_CASE ( testalloca ) ;
2011-09-24 10:54:58 +02:00
// declared function ticket #3121
TEST_CASE ( test_declared_function ) ;
2011-10-09 10:31:21 +02:00
// test std::gets
TEST_CASE ( test_std_gets ) ;
// multiple use of obsolete functions
TEST_CASE ( test_multiple ) ;
// c declared function
TEST_CASE ( test_c_declaration ) ;
2011-10-19 20:21:50 +02:00
// function with body
TEST_CASE ( test_function_with_body ) ;
2011-10-22 12:36:45 +02:00
// null pointer dereference in obsoleteFunctions
TEST_CASE ( ticket3238 ) ;
2010-08-29 12:01:32 +02:00
}
2010-08-14 20:13:46 +02:00
2012-12-02 11:39:26 +01:00
void check ( const char code [ ] , const char filename [ ] = " test.cpp " ) {
2010-12-01 18:00:55 +01:00
// Clear the error buffer..
errout . str ( " " ) ;
Settings settings ;
2011-08-07 09:28:08 +02:00
settings . addEnabled ( " style " ) ;
2011-10-22 09:45:48 +02:00
settings . standards . posix = true ;
2012-08-25 21:57:45 +02:00
settings . standards . c = Standards : : C11 ;
2010-12-01 18:00:55 +01:00
2010-08-14 20:13:46 +02:00
// Tokenize..
2010-12-01 18:00:55 +01:00
Tokenizer tokenizer ( & settings , this ) ;
2010-08-14 20:13:46 +02:00
std : : istringstream istr ( code ) ;
2012-12-02 11:39:26 +01:00
tokenizer . tokenize ( istr , filename ) ;
2013-12-30 17:45:28 +01:00
tokenizer . simplifyTokenList2 ( ) ;
2010-08-14 20:13:46 +02:00
// Check for obsolete functions..
CheckObsoleteFunctions checkObsoleteFunctions ( & tokenizer , & settings , this ) ;
checkObsoleteFunctions . obsoleteFunctions ( ) ;
}
2011-10-13 20:53:06 +02:00
void testbsd_signal ( ) {
2010-08-14 20:13:46 +02:00
check ( " void f() \n "
" { \n "
" bsd_signal(SIGABRT, SIG_IGN); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Obsolete function 'bsd_signal' called. It is recommended to use the function 'sigaction' instead. \n " , errout . str ( ) ) ;
2010-08-14 20:13:46 +02:00
check ( " int f() \n "
" { \n "
" int bsd_signal(0); \n "
" return bsd_signal; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-08-14 20:13:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-13 20:53:06 +02:00
void testgethostbyname ( ) {
2010-08-14 20:13:46 +02:00
check ( " void f() \n "
" { \n "
" struct hostent *hp; \n "
" if(!hp = gethostbyname('127.0.0.1')) { \n "
" exit(1); \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) Obsolete function 'gethostbyname' called. It is recommended to use the function 'getaddrinfo' instead. \n " , errout . str ( ) ) ;
2010-08-14 20:13:46 +02:00
}
2011-10-13 20:53:06 +02:00
void testgethostbyaddr ( ) {
2010-08-14 20:13:46 +02:00
check ( " void f() \n "
" { \n "
" long addr; \n "
" addr = inet_addr('127.0.0.1'); \n "
" if(!hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET)) { \n "
" exit(1); \n "
" } \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style) Obsolete function 'gethostbyaddr' called. It is recommended to use the function 'getnameinfo' instead. \n " , errout . str ( ) ) ;
2010-08-14 20:13:46 +02:00
}
2011-10-13 20:53:06 +02:00
void testusleep ( ) {
2010-08-14 20:13:46 +02:00
check ( " void f() \n "
" { \n "
" usleep( 1000 ); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Obsolete function 'usleep' called. It is recommended to use the 'nanosleep' or 'setitimer' function instead. \n " , errout . str ( ) ) ;
2010-08-14 20:13:46 +02:00
}
2011-10-13 20:53:06 +02:00
void testindex ( ) {
2010-08-14 20:13:46 +02:00
check ( " namespace n1 { \n "
" int index(){}; \n "
" } \n "
" int main() \n "
" { \n "
" n1::index(); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-08-14 20:13:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " std::size_t f() \n "
" { \n "
" std::size_t index(0); \n "
" index++; \n "
" return index; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-08-14 20:13:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " int f() \n "
" { \n "
" return this->index(); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-08-14 20:13:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" int index( 0 ); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-08-14 20:13:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " const char f() \n "
" { \n "
" const char var[6] = 'index'; \n "
" const char i = index(var, 0); \n "
" return i; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) Obsolete function 'index' called. It is recommended to use the function 'strchr' instead. \n " ,
2011-08-03 16:10:43 +02:00
errout . str ( ) ) ;
2010-12-20 18:13:26 +01:00
}
2011-10-13 20:53:06 +02:00
void test_qt_index ( ) {
2010-12-20 18:13:26 +01:00
check ( " void TDataModel::forceRowRefresh(int row) { \n "
" emit dataChanged(index(row, 0), index(row, columnCount() - 1)); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:2]: (style) Obsolete function 'index' called. It is recommended to use the function 'strchr' instead. \n " , errout . str ( ) ) ;
2010-08-14 20:13:46 +02:00
}
2011-10-13 20:53:06 +02:00
void testrindex ( ) {
2010-08-14 20:13:46 +02:00
check ( " void f() \n "
" { \n "
" int rindex( 0 ); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2010-08-14 20:13:46 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" const char var[7] = 'rindex'; \n "
" print(rindex(var, 0)); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) Obsolete function 'rindex' called. It is recommended to use the function 'strrchr' instead. \n " , errout . str ( ) ) ;
2010-08-14 20:13:46 +02:00
}
2011-10-13 20:53:06 +02:00
void testvar ( ) {
2010-08-29 12:01:32 +02:00
check ( " class Fred { \n "
" public: \n "
" Fred() : index(0) { } \n "
" int index; \n "
2013-03-20 15:36:16 +01:00
" }; " ) ;
2010-08-29 12:01:32 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2010-08-14 20:13:46 +02:00
2011-10-13 20:53:06 +02:00
void testgets ( ) {
2010-08-31 18:58:01 +02:00
check ( " void f() \n "
" { \n "
" char *x = gets(); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead. \n " , errout . str ( ) ) ;
2012-12-08 11:46:30 +01:00
check ( " void f() \n "
" { \n "
" foo(x, gets()); \n "
" } " ) ;
ASSERT_EQUALS ( " [test.cpp:3]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead. \n " , errout . str ( ) ) ;
2010-08-31 18:58:01 +02:00
}
2011-10-13 20:53:06 +02:00
void testalloca ( ) {
2011-10-06 08:10:51 +02:00
check ( " void f() \n "
" { \n "
" char *x = alloca(10); \n "
2012-12-02 11:39:26 +01:00
" } \n " , " test.cpp " ) ; // #4382 - there are no VLAs in C++
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
check ( " void f() \n "
" { \n "
" char *x = alloca(10); \n "
" } \n " , " test.c " ) ;
ASSERT_EQUALS ( " [test.c:3]: (style) Obsolete function 'alloca' called. In C99 and later it is recommended to use a variable length array instead. \n " , errout . str ( ) ) ;
2011-10-06 08:10:51 +02:00
}
2011-09-24 10:54:58 +02:00
// ticket #3121
2011-10-13 20:53:06 +02:00
void test_declared_function ( ) {
2012-02-11 12:26:48 +01:00
check ( " int ftime ( int a ) \n "
2011-09-24 10:54:58 +02:00
" { \n "
" return a; \n "
" } \n "
" int main () \n "
" { \n "
" int b ; b = ftime ( 1 ) ; \n "
" return 0 ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-09-24 10:54:58 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-09 10:31:21 +02:00
// test std::gets
2011-10-13 20:53:06 +02:00
void test_std_gets ( ) {
2011-10-09 10:31:21 +02:00
check ( " void f(char * str) \n "
" { \n "
" char *x = std::gets(str); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead. \n " , errout . str ( ) ) ;
2011-10-09 10:31:21 +02:00
}
// multiple use
2011-10-13 20:53:06 +02:00
void test_multiple ( ) {
2011-10-09 10:31:21 +02:00
check ( " void f(char * str) \n "
" { \n "
" char *x = std::gets(str); \n "
" usleep( 1000 ); \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:3]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead. \n "
" [test.cpp:4]: (style) Obsolete function 'usleep' called. It is recommended to use the 'nanosleep' or 'setitimer' function instead. \n " , errout . str ( ) ) ;
2011-10-09 10:31:21 +02:00
}
2011-10-13 20:53:06 +02:00
void test_c_declaration ( ) {
2011-10-09 10:31:21 +02:00
check ( " char * gets ( char * c ) ; \n "
" int main () \n "
" { \n "
" char s [ 10 ] ; \n "
" gets ( s ) ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:5]: (style) Obsolete function 'gets' called. It is recommended to use the function 'fgets' instead. \n " , errout . str ( ) ) ;
2011-10-09 10:31:21 +02:00
check ( " int getcontext(ucontext_t *ucp); \n "
" int f (ucontext_t *ucp) \n "
" { \n "
" getcontext ( ucp ) ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2012-07-29 11:30:03 +02:00
ASSERT_EQUALS ( " [test.cpp:4]: (style) Obsolete function 'getcontext' called. Due to portability issues, applications are recommended to be rewritten to use POSIX threads. \n " , errout . str ( ) ) ;
2011-10-19 20:21:50 +02:00
}
void test_function_with_body ( ) {
check ( " char * gets ( char * c ) { return c; } \n "
" int main () \n "
" { \n "
" char s [ 10 ] ; \n "
" gets ( s ) ; \n "
2013-03-20 15:36:16 +01:00
" } " ) ;
2011-10-09 10:31:21 +02:00
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-22 12:36:45 +02:00
void ticket3238 ( ) {
check ( " __FBSDID( \" ... \" ); \n " ) ;
ASSERT_EQUALS ( " " , errout . str ( ) ) ;
}
2011-10-19 20:21:50 +02:00
2010-08-14 20:13:46 +02:00
} ;
REGISTER_TEST ( TestObsoleteFunctions )