Skip to content

Commit be0e762

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 c5b816b commit be0e762

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)
@@ -2984,9 +2986,11 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path)
29842986
if (nonExistingFilesCache.contains(path))
29852987
return ""; // file is known not to exist, skip expensive file open call
29862988
#endif
2987-
f.open(path.c_str());
2988-
if (f.is_open())
2989-
return path;
2989+
if (simplecpp::isFile(path)) {
2990+
f.open(path.c_str());
2991+
if (f.is_open())
2992+
return path;
2993+
}
29902994
#ifdef SIMPLECPP_WINDOWS
29912995
nonExistingFilesCache.add(path);
29922996
#endif
@@ -3107,6 +3111,9 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
31073111
if (stat(path.c_str(), &statbuf) != 0)
31083112
return false;
31093113

3114+
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
3115+
return false;
3116+
31103117
id.dev = statbuf.st_dev;
31113118
id.ino = statbuf.st_ino;
31123119

@@ -3843,3 +3850,21 @@ std::string simplecpp::getCppStdString(const std::string &std)
38433850
{
38443851
return getCppStdString(getCppStd(std));
38453852
}
3853+
3854+
static mode_t file_type(const std::string &path)
3855+
{
3856+
struct stat file_stat;
3857+
if (stat(path.c_str(), &file_stat) == -1)
3858+
return 0;
3859+
return file_stat.st_mode & S_IFMT;
3860+
}
3861+
3862+
bool simplecpp::isFile(const std::string &path)
3863+
{
3864+
return file_type(path) == S_IFREG;
3865+
}
3866+
3867+
bool simplecpp::isDirectory(const std::string &path)
3868+
{
3869+
return file_type(path) == S_IFDIR;
3870+
}

simplecpp.h

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

354+
/**
355+
* @brief Checks if given path is a file
356+
* @param path Path to be checked
357+
* @return true if given path is a file
358+
*/
359+
SIMPLECPP_LIB bool isFile(const std::string &path);
360+
361+
/**
362+
* @brief Checks if a given path is a directory
363+
* @param path Path to be checked
364+
* @return true if given path is a directory
365+
*/
366+
SIMPLECPP_LIB bool isDirectory(const std::string &path);
367+
354368
struct SIMPLECPP_LIB FileData {
355369
/** The canonical filename associated with this data */
356370
std::string filename;

test.cpp

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

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

3224+
static void leak()
3225+
{
3226+
const char code[] = "#include</\\\\>\n"
3227+
"#include</\\\\>\n";
3228+
simplecpp::OutputList outputList;
3229+
ASSERT_EQUALS("", preprocess(code, &outputList));
3230+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3231+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3232+
}
3233+
31863234
int main(int argc, char **argv)
31873235
{
31883236
TEST_CASE(backslash);
@@ -3356,6 +3404,12 @@ int main(int argc, char **argv)
33563404
TEST_CASE(missingHeader2);
33573405
TEST_CASE(missingHeader3);
33583406
TEST_CASE(missingHeader4);
3407+
#ifndef _WIN32
3408+
TEST_CASE(missingHeader5);
3409+
TEST_CASE(missingHeader6);
3410+
TEST_CASE(missingHeader7);
3411+
TEST_CASE(missingHeader8);
3412+
#endif
33593413
TEST_CASE(nestedInclude);
33603414
TEST_CASE(systemInclude);
33613415
TEST_CASE(circularInclude);
@@ -3437,5 +3491,7 @@ int main(int argc, char **argv)
34373491

34383492
TEST_CASE(fuzz_crash);
34393493

3494+
TEST_CASE(leak);
3495+
34403496
return numberOfFailedAssertions > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
34413497
}

0 commit comments

Comments
 (0)