Skip to content

Commit d57947d

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

File tree

4 files changed

+102
-3
lines changed

4 files changed

+102
-3
lines changed

main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ int main(int argc, char **argv)
122122
std::cout << "error: could not open file '" << filename << "'" << std::endl;
123123
std::exit(1);
124124
}
125+
if (!simplecpp::isFile(filename)) {
126+
std::cout << "error: could not open file '" << filename << "' - not a regular file" << std::endl;
127+
std::exit(1);
128+
}
125129
rawtokens = new simplecpp::TokenList(f, files,filename,&outputList);
126130
} else {
127131
rawtokens = new simplecpp::TokenList(filename,files,&outputList);

simplecpp.cpp

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

4343
#ifdef _WIN32
4444
# include <direct.h>
45+
using mode_t = unsigned short;
4546
#else
4647
# include <sys/stat.h>
48+
# include <sys/types.h>
4749
#endif
4850

4951
static bool isHex(const std::string &s)
@@ -2975,9 +2977,11 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path)
29752977
if (nonExistingFilesCache.contains(path))
29762978
return ""; // file is known not to exist, skip expensive file open call
29772979
#endif
2978-
f.open(path.c_str());
2979-
if (f.is_open())
2980-
return path;
2980+
if (simplecpp::isFile(path)) {
2981+
f.open(path.c_str());
2982+
if (f.is_open())
2983+
return path;
2984+
}
29812985
#ifdef SIMPLECPP_WINDOWS
29822986
nonExistingFilesCache.add(path);
29832987
#endif
@@ -3097,6 +3101,9 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
30973101
if (stat(path.c_str(), &statbuf) != 0)
30983102
return false;
30993103

3104+
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
3105+
return false;
3106+
31003107
id.dev = statbuf.st_dev;
31013108
id.ino = statbuf.st_ino;
31023109

@@ -3839,3 +3846,21 @@ std::string simplecpp::getCppStdString(const std::string &std)
38393846
{
38403847
return getCppStdString(getCppStd(std));
38413848
}
3849+
3850+
static mode_t file_type(const std::string &path)
3851+
{
3852+
struct stat file_stat;
3853+
if (stat(path.c_str(), &file_stat) == -1)
3854+
return 0;
3855+
return file_stat.st_mode & S_IFMT;
3856+
}
3857+
3858+
bool simplecpp::isFile(const std::string &path)
3859+
{
3860+
return file_type(path) == S_IFREG;
3861+
}
3862+
3863+
bool simplecpp::isDirectory(const std::string &path)
3864+
{
3865+
return file_type(path) == S_IFDIR;
3866+
}

simplecpp.h

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

410+
/**
411+
* @brief Checks if given path is a file
412+
* @param path Path to be checked
413+
* @return true if given path is a file
414+
*/
415+
SIMPLECPP_LIB bool isFile(const std::string &path);
416+
417+
/**
418+
* @brief Checks if a given path is a directory
419+
* @param path Path to be checked
420+
* @return true if given path is a directory
421+
*/
422+
SIMPLECPP_LIB bool isDirectory(const std::string &path);
423+
410424
struct SIMPLECPP_LIB FileData {
411425
/** The canonical filename associated with this data */
412426
std::string filename;

test.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,6 +2090,44 @@ static void missingHeader4()
20902090
ASSERT_EQUALS("file0,1,syntax_error,No header in #include\n", toString(outputList));
20912091
}
20922092

2093+
#ifndef _WIN32
2094+
static void missingHeader5()
2095+
{
2096+
// this is a directory
2097+
const char code[] = "#include \"/\"\n";
2098+
simplecpp::OutputList outputList;
2099+
ASSERT_EQUALS("", preprocess(code, &outputList));
2100+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/\"\n", toString(outputList));
2101+
}
2102+
2103+
static void missingHeader6()
2104+
{
2105+
// this is a directory
2106+
const char code[] = "#include \"/usr\"\n";
2107+
simplecpp::OutputList outputList;
2108+
ASSERT_EQUALS("", preprocess(code, &outputList));
2109+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/usr\"\n", toString(outputList));
2110+
}
2111+
2112+
static void missingHeader7()
2113+
{
2114+
// this is a directory
2115+
const char code[] = "#include </>\n";
2116+
simplecpp::OutputList outputList;
2117+
ASSERT_EQUALS("", preprocess(code, &outputList));
2118+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </>\n", toString(outputList));
2119+
}
2120+
2121+
static void missingHeader8()
2122+
{
2123+
// this is a directory
2124+
const char code[] = "#include </usr>\n";
2125+
simplecpp::OutputList outputList;
2126+
ASSERT_EQUALS("", preprocess(code, &outputList));
2127+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </usr>\n", toString(outputList));
2128+
}
2129+
#endif
2130+
20932131
static void nestedInclude()
20942132
{
20952133
const char code[] = "#include \"test.h\"\n";
@@ -3260,6 +3298,16 @@ static void fuzz_crash()
32603298
}
32613299
}
32623300

3301+
static void leak()
3302+
{
3303+
const char code[] = "#include</\\\\>\n"
3304+
"#include</\\\\>\n";
3305+
simplecpp::OutputList outputList;
3306+
ASSERT_EQUALS("", preprocess(code, &outputList));
3307+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3308+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3309+
}
3310+
32633311
int main(int argc, char **argv)
32643312
{
32653313
TEST_CASE(backslash);
@@ -3433,6 +3481,12 @@ int main(int argc, char **argv)
34333481
TEST_CASE(missingHeader2);
34343482
TEST_CASE(missingHeader3);
34353483
TEST_CASE(missingHeader4);
3484+
#ifndef _WIN32
3485+
TEST_CASE(missingHeader5);
3486+
TEST_CASE(missingHeader6);
3487+
TEST_CASE(missingHeader7);
3488+
TEST_CASE(missingHeader8);
3489+
#endif
34363490
TEST_CASE(nestedInclude);
34373491
TEST_CASE(systemInclude);
34383492
TEST_CASE(circularInclude);
@@ -3516,5 +3570,7 @@ int main(int argc, char **argv)
35163570

35173571
TEST_CASE(fuzz_crash);
35183572

3573+
TEST_CASE(leak);
3574+
35193575
return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
35203576
}

0 commit comments

Comments
 (0)