Skip to content

Commit e5bcc56

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 ecd6d8e commit e5bcc56

File tree

3 files changed

+94
-3
lines changed

3 files changed

+94
-3
lines changed

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
@@ -2181,6 +2181,44 @@ static void missingHeader4()
21812181
ASSERT_EQUALS("file0,1,syntax_error,No header in #include\n", toString(outputList));
21822182
}
21832183

2184+
#ifndef _WIN32
2185+
static void missingHeader5()
2186+
{
2187+
// this is a directory
2188+
const char code[] = "#include \"/\"\n";
2189+
simplecpp::OutputList outputList;
2190+
ASSERT_EQUALS("", preprocess(code, &outputList));
2191+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/\"\n", toString(outputList));
2192+
}
2193+
2194+
static void missingHeader6()
2195+
{
2196+
// this is a directory
2197+
const char code[] = "#include \"/usr\"\n";
2198+
simplecpp::OutputList outputList;
2199+
ASSERT_EQUALS("", preprocess(code, &outputList));
2200+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/usr\"\n", toString(outputList));
2201+
}
2202+
2203+
static void missingHeader7()
2204+
{
2205+
// this is a directory
2206+
const char code[] = "#include </>\n";
2207+
simplecpp::OutputList outputList;
2208+
ASSERT_EQUALS("", preprocess(code, &outputList));
2209+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </>\n", toString(outputList));
2210+
}
2211+
2212+
static void missingHeader8()
2213+
{
2214+
// this is a directory
2215+
const char code[] = "#include </usr>\n";
2216+
simplecpp::OutputList outputList;
2217+
ASSERT_EQUALS("", preprocess(code, &outputList));
2218+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </usr>\n", toString(outputList));
2219+
}
2220+
#endif
2221+
21842222
static void nestedInclude()
21852223
{
21862224
const char code[] = "#include \"test.h\"\n";
@@ -3475,6 +3513,14 @@ static void leak()
34753513
"#define e\n";
34763514
(void)preprocess(code, simplecpp::DUI());
34773515
}
3516+
{
3517+
const char code[] = "#include</\\\\>\n"
3518+
"#include</\\\\>\n";
3519+
simplecpp::OutputList outputList;
3520+
ASSERT_EQUALS("", preprocess(code, &outputList));
3521+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3522+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3523+
}
34783524
}
34793525

34803526
int main(int argc, char **argv)
@@ -3657,6 +3703,12 @@ int main(int argc, char **argv)
36573703
TEST_CASE(missingHeader2);
36583704
TEST_CASE(missingHeader3);
36593705
TEST_CASE(missingHeader4);
3706+
#ifndef _WIN32
3707+
TEST_CASE(missingHeader5);
3708+
TEST_CASE(missingHeader6);
3709+
TEST_CASE(missingHeader7);
3710+
TEST_CASE(missingHeader8);
3711+
#endif
36603712
TEST_CASE(nestedInclude);
36613713
TEST_CASE(systemInclude);
36623714
TEST_CASE(circularInclude);

0 commit comments

Comments
 (0)