Skip to content

Commit 3dec50c

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 dd352c8 commit 3dec50c

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
@@ -121,6 +121,10 @@ int main(int argc, char **argv)
121121
std::cout << "error: could not open file '" << filename << "'" << std::endl;
122122
std::exit(1);
123123
}
124+
if (!simplecpp::isFile(filename)) {
125+
std::cout << "error: could not open file '" << filename << "' - not a regular file" << std::endl;
126+
std::exit(1);
127+
}
124128
rawtokens = new simplecpp::TokenList(f, files,filename,&outputList);
125129
} else {
126130
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

@@ -3833,3 +3840,21 @@ std::string simplecpp::getCppStdString(const std::string &std)
38333840
{
38343841
return getCppStdString(getCppStd(std));
38353842
}
3843+
3844+
static mode_t file_type(const std::string &path)
3845+
{
3846+
struct stat file_stat;
3847+
if (stat(path.c_str(), &file_stat) == -1)
3848+
return 0;
3849+
return file_stat.st_mode & S_IFMT;
3850+
}
3851+
3852+
bool simplecpp::isFile(const std::string &path)
3853+
{
3854+
return file_type(path) == S_IFREG;
3855+
}
3856+
3857+
bool simplecpp::isDirectory(const std::string &path)
3858+
{
3859+
return file_type(path) == S_IFDIR;
3860+
}

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

2066+
#ifndef _WIN32
2067+
static void missingHeader5()
2068+
{
2069+
// this is a directory
2070+
const char code[] = "#include \"/\"\n";
2071+
simplecpp::OutputList outputList;
2072+
ASSERT_EQUALS("", preprocess(code, &outputList));
2073+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/\"\n", toString(outputList));
2074+
}
2075+
2076+
static void missingHeader6()
2077+
{
2078+
// this is a directory
2079+
const char code[] = "#include \"/usr\"\n";
2080+
simplecpp::OutputList outputList;
2081+
ASSERT_EQUALS("", preprocess(code, &outputList));
2082+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/usr\"\n", toString(outputList));
2083+
}
2084+
2085+
static void missingHeader7()
2086+
{
2087+
// this is a directory
2088+
const char code[] = "#include </>\n";
2089+
simplecpp::OutputList outputList;
2090+
ASSERT_EQUALS("", preprocess(code, &outputList));
2091+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </>\n", toString(outputList));
2092+
}
2093+
2094+
static void missingHeader8()
2095+
{
2096+
// this is a directory
2097+
const char code[] = "#include </usr>\n";
2098+
simplecpp::OutputList outputList;
2099+
ASSERT_EQUALS("", preprocess(code, &outputList));
2100+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </usr>\n", toString(outputList));
2101+
}
2102+
#endif
2103+
20662104
static void nestedInclude()
20672105
{
20682106
const char code[] = "#include \"test.h\"\n";
@@ -3231,6 +3269,16 @@ static void fuzz_crash()
32313269
}
32323270
}
32333271

3272+
static void leak()
3273+
{
3274+
const char code[] = "#include</\\\\>\n"
3275+
"#include</\\\\>\n";
3276+
simplecpp::OutputList outputList;
3277+
ASSERT_EQUALS("", preprocess(code, &outputList));
3278+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3279+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3280+
}
3281+
32343282
int main(int argc, char **argv)
32353283
{
32363284
TEST_CASE(backslash);
@@ -3404,6 +3452,12 @@ int main(int argc, char **argv)
34043452
TEST_CASE(missingHeader2);
34053453
TEST_CASE(missingHeader3);
34063454
TEST_CASE(missingHeader4);
3455+
#ifndef _WIN32
3456+
TEST_CASE(missingHeader5);
3457+
TEST_CASE(missingHeader6);
3458+
TEST_CASE(missingHeader7);
3459+
TEST_CASE(missingHeader8);
3460+
#endif
34073461
TEST_CASE(nestedInclude);
34083462
TEST_CASE(systemInclude);
34093463
TEST_CASE(circularInclude);
@@ -3487,5 +3541,7 @@ int main(int argc, char **argv)
34873541

34883542
TEST_CASE(fuzz_crash);
34893543

3544+
TEST_CASE(leak);
3545+
34903546
return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
34913547
}

0 commit comments

Comments
 (0)