Skip to content

Commit 55488b2

Browse files
committed
test.cpp: added test to make sure the leak with empty headers no longer occurs
do not treat directories like regular files in existence checks added the file/directory existence functions from Cppcheck
1 parent 145f95c commit 55488b2

3 files changed

Lines changed: 94 additions & 3 deletions

File tree

simplecpp.cpp

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

5454
#ifdef _WIN32
5555
# include <direct.h>
56+
using mode_t = unsigned short;
5657
#else
5758
# include <sys/stat.h>
59+
# include <sys/types.h>
5860
#endif
5961

6062
static bool isHex(const std::string &s)
@@ -3044,9 +3046,11 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path)
30443046
if (nonExistingFilesCache.contains(path))
30453047
return ""; // file is known not to exist, skip expensive file open call
30463048
#endif
3047-
f.open(path.c_str());
3048-
if (f.is_open())
3049-
return path;
3049+
if (simplecpp::isFile(path)) {
3050+
f.open(path.c_str());
3051+
if (f.is_open())
3052+
return path;
3053+
}
30503054
#ifdef SIMPLECPP_WINDOWS
30513055
nonExistingFilesCache.add(path);
30523056
#endif
@@ -3180,6 +3184,9 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
31803184
if (stat(path.c_str(), &statbuf) != 0)
31813185
return false;
31823186

3187+
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
3188+
return false;
3189+
31833190
id.dev = statbuf.st_dev;
31843191
id.ino = statbuf.st_ino;
31853192

@@ -3967,3 +3974,21 @@ std::string simplecpp::getCppStdString(const std::string &std)
39673974
{
39683975
return getCppStdString(getCppStd(std));
39693976
}
3977+
3978+
static mode_t file_type(const std::string &path)
3979+
{
3980+
struct stat file_stat;
3981+
if (stat(path.c_str(), &file_stat) == -1)
3982+
return 0;
3983+
return file_stat.st_mode & S_IFMT;
3984+
}
3985+
3986+
bool simplecpp::isFile(const std::string &path)
3987+
{
3988+
return file_type(path) == S_IFREG;
3989+
}
3990+
3991+
bool simplecpp::isDirectory(const std::string &path)
3992+
{
3993+
return file_type(path) == S_IFDIR;
3994+
}

simplecpp.h

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

446+
/**
447+
* @brief Checks if given path is a file
448+
* @param path Path to be checked
449+
* @return true if given path is a file
450+
*/
451+
SIMPLECPP_LIB bool isFile(const std::string &path);
452+
453+
/**
454+
* @brief Checks if a given path is a directory
455+
* @param path Path to be checked
456+
* @return true if given path is a directory
457+
*/
458+
SIMPLECPP_LIB bool isDirectory(const std::string &path);
459+
446460
struct SIMPLECPP_LIB FileData {
447461
/** The canonical filename associated with this data */
448462
std::string filename;

test.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,6 +2247,44 @@ static void missingHeader4()
22472247
ASSERT_EQUALS("file0,1,syntax_error,No header in #include\n", toString(outputList));
22482248
}
22492249

2250+
#ifndef _WIN32
2251+
static void missingHeader5()
2252+
{
2253+
// this is a directory
2254+
const char code[] = "#include \"/\"\n";
2255+
simplecpp::OutputList outputList;
2256+
ASSERT_EQUALS("", preprocess(code, &outputList));
2257+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/\"\n", toString(outputList));
2258+
}
2259+
2260+
static void missingHeader6()
2261+
{
2262+
// this is a directory
2263+
const char code[] = "#include \"/usr\"\n";
2264+
simplecpp::OutputList outputList;
2265+
ASSERT_EQUALS("", preprocess(code, &outputList));
2266+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/usr\"\n", toString(outputList));
2267+
}
2268+
2269+
static void missingHeader7()
2270+
{
2271+
// this is a directory
2272+
const char code[] = "#include </>\n";
2273+
simplecpp::OutputList outputList;
2274+
ASSERT_EQUALS("", preprocess(code, &outputList));
2275+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </>\n", toString(outputList));
2276+
}
2277+
2278+
static void missingHeader8()
2279+
{
2280+
// this is a directory
2281+
const char code[] = "#include </usr>\n";
2282+
simplecpp::OutputList outputList;
2283+
ASSERT_EQUALS("", preprocess(code, &outputList));
2284+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </usr>\n", toString(outputList));
2285+
}
2286+
#endif
2287+
22502288
static void nestedInclude()
22512289
{
22522290
const char code[] = "#include \"test.h\"\n";
@@ -3617,6 +3655,14 @@ static void leak()
36173655
"#define e\n";
36183656
(void)preprocess(code, simplecpp::DUI());
36193657
}
3658+
{
3659+
const char code[] = "#include</\\\\>\n"
3660+
"#include</\\\\>\n";
3661+
simplecpp::OutputList outputList;
3662+
ASSERT_EQUALS("", preprocess(code, &outputList));
3663+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3664+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3665+
}
36203666
}
36213667

36223668
int main(int argc, char **argv)
@@ -3801,6 +3847,12 @@ int main(int argc, char **argv)
38013847
TEST_CASE(missingHeader2);
38023848
TEST_CASE(missingHeader3);
38033849
TEST_CASE(missingHeader4);
3850+
#ifndef _WIN32
3851+
TEST_CASE(missingHeader5);
3852+
TEST_CASE(missingHeader6);
3853+
TEST_CASE(missingHeader7);
3854+
TEST_CASE(missingHeader8);
3855+
#endif
38043856
TEST_CASE(nestedInclude);
38053857
TEST_CASE(systemInclude);
38063858
TEST_CASE(circularInclude);

0 commit comments

Comments
 (0)