Skip to content

Commit e5c27ad

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 8336c7d commit e5c27ad

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)
@@ -2979,9 +2981,11 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path)
29792981
if (nonExistingFilesCache.contains(path))
29802982
return ""; // file is known not to exist, skip expensive file open call
29812983
#endif
2982-
f.open(path.c_str());
2983-
if (f.is_open())
2984-
return path;
2984+
if (simplecpp::isFile(path)) {
2985+
f.open(path.c_str());
2986+
if (f.is_open())
2987+
return path;
2988+
}
29852989
#ifdef SIMPLECPP_WINDOWS
29862990
nonExistingFilesCache.add(path);
29872991
#endif
@@ -3102,6 +3106,9 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
31023106
if (stat(path.c_str(), &statbuf) != 0)
31033107
return false;
31043108

3109+
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
3110+
return false;
3111+
31053112
id.dev = statbuf.st_dev;
31063113
id.ino = statbuf.st_ino;
31073114

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

simplecpp.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,20 @@ namespace simplecpp {
396396
SIMPLECPP_LIB std::string getCppStdString(const std::string &std);
397397
SIMPLECPP_LIB std::string getCppStdString(cppstd_t std);
398398

399+
/**
400+
* @brief Checks if given path is a file
401+
* @param path Path to be checked
402+
* @return true if given path is a file
403+
*/
404+
SIMPLECPP_LIB bool isFile(const std::string &path);
405+
406+
/**
407+
* @brief Checks if a given path is a directory
408+
* @param path Path to be checked
409+
* @return true if given path is a directory
410+
*/
411+
SIMPLECPP_LIB bool isDirectory(const std::string &path);
412+
399413
struct SIMPLECPP_LIB FileData {
400414
/** The canonical filename associated with this data */
401415
std::string filename;

test.cpp

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

2055+
#ifndef _WIN32
2056+
static void missingHeader5()
2057+
{
2058+
// this is a directory
2059+
const char code[] = "#include \"/\"\n";
2060+
simplecpp::OutputList outputList;
2061+
ASSERT_EQUALS("", preprocess(code, &outputList));
2062+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/\"\n", toString(outputList));
2063+
}
2064+
2065+
static void missingHeader6()
2066+
{
2067+
// this is a directory
2068+
const char code[] = "#include \"/usr\"\n";
2069+
simplecpp::OutputList outputList;
2070+
ASSERT_EQUALS("", preprocess(code, &outputList));
2071+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/usr\"\n", toString(outputList));
2072+
}
2073+
2074+
static void missingHeader7()
2075+
{
2076+
// this is a directory
2077+
const char code[] = "#include </>\n";
2078+
simplecpp::OutputList outputList;
2079+
ASSERT_EQUALS("", preprocess(code, &outputList));
2080+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </>\n", toString(outputList));
2081+
}
2082+
2083+
static void missingHeader8()
2084+
{
2085+
// this is a directory
2086+
const char code[] = "#include </usr>\n";
2087+
simplecpp::OutputList outputList;
2088+
ASSERT_EQUALS("", preprocess(code, &outputList));
2089+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </usr>\n", toString(outputList));
2090+
}
2091+
#endif
2092+
20552093
static void nestedInclude()
20562094
{
20572095
const char code[] = "#include \"test.h\"\n";
@@ -3139,6 +3177,16 @@ static void fuzz_crash()
31393177
}
31403178
}
31413179

3180+
static void leak()
3181+
{
3182+
const char code[] = "#include</\\\\>\n"
3183+
"#include</\\\\>\n";
3184+
simplecpp::OutputList outputList;
3185+
ASSERT_EQUALS("", preprocess(code, &outputList));
3186+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3187+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3188+
}
3189+
31423190
int main(int argc, char **argv)
31433191
{
31443192
TEST_CASE(backslash);
@@ -3312,6 +3360,12 @@ int main(int argc, char **argv)
33123360
TEST_CASE(missingHeader2);
33133361
TEST_CASE(missingHeader3);
33143362
TEST_CASE(missingHeader4);
3363+
#ifndef _WIN32
3364+
TEST_CASE(missingHeader5);
3365+
TEST_CASE(missingHeader6);
3366+
TEST_CASE(missingHeader7);
3367+
TEST_CASE(missingHeader8);
3368+
#endif
33153369
TEST_CASE(nestedInclude);
33163370
TEST_CASE(systemInclude);
33173371

@@ -3392,5 +3446,7 @@ int main(int argc, char **argv)
33923446

33933447
TEST_CASE(fuzz_crash);
33943448

3449+
TEST_CASE(leak);
3450+
33953451
return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
33963452
}

0 commit comments

Comments
 (0)