Skip to content

Commit 28dbd15

Browse files
committed
test.cpp: added test to make sure the leak with empty headers no longer occurs
do not treat directories like regular files in existence checks added the file/directory existence functions from Cppcheck
1 parent f3cb133 commit 28dbd15

3 files changed

Lines changed: 94 additions & 3 deletions

File tree

simplecpp.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@
5353

5454
#ifdef _WIN32
5555
# include <direct.h>
56+
using mode_t = unsigned short;
5657
#else
5758
# include <sys/stat.h>
59+
# include <sys/types.h>
5860
#endif
5961

6062
static bool isHex(const std::string &s)
@@ -3014,9 +3016,11 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path)
30143016
if (nonExistingFilesCache.contains(path))
30153017
return ""; // file is known not to exist, skip expensive file open call
30163018
#endif
3017-
f.open(path.c_str());
3018-
if (f.is_open())
3019-
return path;
3019+
if (simplecpp::isFile(path)) {
3020+
f.open(path.c_str());
3021+
if (f.is_open())
3022+
return path;
3023+
}
30203024
#ifdef SIMPLECPP_WINDOWS
30213025
nonExistingFilesCache.add(path);
30223026
#endif
@@ -3150,6 +3154,9 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
31503154
if (stat(path.c_str(), &statbuf) != 0)
31513155
return false;
31523156

3157+
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
3158+
return false;
3159+
31533160
id.dev = statbuf.st_dev;
31543161
id.ino = statbuf.st_ino;
31553162

@@ -3912,3 +3919,21 @@ std::string simplecpp::getCppStdString(const std::string &std)
39123919
{
39133920
return getCppStdString(getCppStd(std));
39143921
}
3922+
3923+
static mode_t file_type(const std::string &path)
3924+
{
3925+
struct stat file_stat;
3926+
if (stat(path.c_str(), &file_stat) == -1)
3927+
return 0;
3928+
return file_stat.st_mode & S_IFMT;
3929+
}
3930+
3931+
bool simplecpp::isFile(const std::string &path)
3932+
{
3933+
return file_type(path) == S_IFREG;
3934+
}
3935+
3936+
bool simplecpp::isDirectory(const std::string &path)
3937+
{
3938+
return file_type(path) == S_IFDIR;
3939+
}

simplecpp.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,20 @@ namespace simplecpp {
434434
bool removeComments{}; /** remove comment tokens from included files */
435435
};
436436

437+
/**
438+
* @brief Checks if given path is a file
439+
* @param path Path to be checked
440+
* @return true if given path is a file
441+
*/
442+
SIMPLECPP_LIB bool isFile(const std::string &path);
443+
444+
/**
445+
* @brief Checks if a given path is a directory
446+
* @param path Path to be checked
447+
* @return true if given path is a directory
448+
*/
449+
SIMPLECPP_LIB bool isDirectory(const std::string &path);
450+
437451
struct SIMPLECPP_LIB FileData {
438452
/** The canonical filename associated with this data */
439453
std::string filename;

test.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,6 +2210,44 @@ static void missingHeader4()
22102210
ASSERT_EQUALS("file0,1,syntax_error,No header in #include\n", toString(outputList));
22112211
}
22122212

2213+
#ifndef _WIN32
2214+
static void missingHeader5()
2215+
{
2216+
// this is a directory
2217+
const char code[] = "#include \"/\"\n";
2218+
simplecpp::OutputList outputList;
2219+
ASSERT_EQUALS("", preprocess(code, &outputList));
2220+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/\"\n", toString(outputList));
2221+
}
2222+
2223+
static void missingHeader6()
2224+
{
2225+
// this is a directory
2226+
const char code[] = "#include \"/usr\"\n";
2227+
simplecpp::OutputList outputList;
2228+
ASSERT_EQUALS("", preprocess(code, &outputList));
2229+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/usr\"\n", toString(outputList));
2230+
}
2231+
2232+
static void missingHeader7()
2233+
{
2234+
// this is a directory
2235+
const char code[] = "#include </>\n";
2236+
simplecpp::OutputList outputList;
2237+
ASSERT_EQUALS("", preprocess(code, &outputList));
2238+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </>\n", toString(outputList));
2239+
}
2240+
2241+
static void missingHeader8()
2242+
{
2243+
// this is a directory
2244+
const char code[] = "#include </usr>\n";
2245+
simplecpp::OutputList outputList;
2246+
ASSERT_EQUALS("", preprocess(code, &outputList));
2247+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </usr>\n", toString(outputList));
2248+
}
2249+
#endif
2250+
22132251
static void nestedInclude()
22142252
{
22152253
const char code[] = "#include \"test.h\"\n";
@@ -3504,6 +3542,14 @@ static void leak()
35043542
"#define e\n";
35053543
(void)preprocess(code, simplecpp::DUI());
35063544
}
3545+
{
3546+
const char code[] = "#include</\\\\>\n"
3547+
"#include</\\\\>\n";
3548+
simplecpp::OutputList outputList;
3549+
ASSERT_EQUALS("", preprocess(code, &outputList));
3550+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3551+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3552+
}
35073553
}
35083554

35093555
int main(int argc, char **argv)
@@ -3686,6 +3732,12 @@ int main(int argc, char **argv)
36863732
TEST_CASE(missingHeader2);
36873733
TEST_CASE(missingHeader3);
36883734
TEST_CASE(missingHeader4);
3735+
#ifndef _WIN32
3736+
TEST_CASE(missingHeader5);
3737+
TEST_CASE(missingHeader6);
3738+
TEST_CASE(missingHeader7);
3739+
TEST_CASE(missingHeader8);
3740+
#endif
36893741
TEST_CASE(nestedInclude);
36903742
TEST_CASE(systemInclude);
36913743
TEST_CASE(circularInclude);

0 commit comments

Comments
 (0)