Skip to content

Commit 211f4c0

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 802e96c commit 211f4c0

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
@@ -156,6 +156,10 @@ int main(int argc, char **argv)
156156
std::cout << "error: could not open file '" << filename << "'" << std::endl;
157157
std::exit(1);
158158
}
159+
if (!simplecpp::isFile(filename)) {
160+
std::cout << "error: could not open file '" << filename << "' - not a regular file" << std::endl;
161+
std::exit(1);
162+
}
159163
rawtokens = new simplecpp::TokenList(f, files,filename,&outputList);
160164
} else {
161165
rawtokens = new simplecpp::TokenList(filename,files,&outputList);

simplecpp.cpp

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

5050
#ifdef _WIN32
5151
# include <direct.h>
52+
using mode_t = unsigned short;
5253
#else
5354
# include <sys/stat.h>
55+
# include <sys/types.h>
5456
#endif
5557

5658
static bool isHex(const std::string &s)
@@ -2991,9 +2993,11 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path)
29912993
if (nonExistingFilesCache.contains(path))
29922994
return ""; // file is known not to exist, skip expensive file open call
29932995
#endif
2994-
f.open(path.c_str());
2995-
if (f.is_open())
2996-
return path;
2996+
if (simplecpp::isFile(path)) {
2997+
f.open(path.c_str());
2998+
if (f.is_open())
2999+
return path;
3000+
}
29973001
#ifdef SIMPLECPP_WINDOWS
29983002
nonExistingFilesCache.add(path);
29993003
#endif
@@ -3113,6 +3117,9 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
31133117
if (stat(path.c_str(), &statbuf) != 0)
31143118
return false;
31153119

3120+
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
3121+
return false;
3122+
31163123
id.dev = statbuf.st_dev;
31173124
id.ino = statbuf.st_ino;
31183125

@@ -3855,3 +3862,21 @@ std::string simplecpp::getCppStdString(const std::string &std)
38553862
{
38563863
return getCppStdString(getCppStd(std));
38573864
}
3865+
3866+
static mode_t file_type(const std::string &path)
3867+
{
3868+
struct stat file_stat;
3869+
if (stat(path.c_str(), &file_stat) == -1)
3870+
return 0;
3871+
return file_stat.st_mode & S_IFMT;
3872+
}
3873+
3874+
bool simplecpp::isFile(const std::string &path)
3875+
{
3876+
return file_type(path) == S_IFREG;
3877+
}
3878+
3879+
bool simplecpp::isDirectory(const std::string &path)
3880+
{
3881+
return file_type(path) == S_IFDIR;
3882+
}

simplecpp.h

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

406+
/**
407+
* @brief Checks if given path is a file
408+
* @param path Path to be checked
409+
* @return true if given path is a file
410+
*/
411+
SIMPLECPP_LIB bool isFile(const std::string &path);
412+
413+
/**
414+
* @brief Checks if a given path is a directory
415+
* @param path Path to be checked
416+
* @return true if given path is a directory
417+
*/
418+
SIMPLECPP_LIB bool isDirectory(const std::string &path);
419+
406420
struct SIMPLECPP_LIB FileData {
407421
/** The canonical filename associated with this data */
408422
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)