Skip to content

Commit 5079ead

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 b39e6d6 commit 5079ead

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)
@@ -3039,9 +3041,11 @@ static std::string openHeaderDirect(std::ifstream &f, const std::string &path)
30393041
if (nonExistingFilesCache.contains(path))
30403042
return ""; // file is known not to exist, skip expensive file open call
30413043
#endif
3042-
f.open(path.c_str());
3043-
if (f.is_open())
3044-
return path;
3044+
if (simplecpp::isFile(path)) {
3045+
f.open(path.c_str());
3046+
if (f.is_open())
3047+
return path;
3048+
}
30453049
#ifdef SIMPLECPP_WINDOWS
30463050
nonExistingFilesCache.add(path);
30473051
#endif
@@ -3175,6 +3179,9 @@ bool simplecpp::FileDataCache::getFileId(const std::string &path, FileID &id)
31753179
if (stat(path.c_str(), &statbuf) != 0)
31763180
return false;
31773181

3182+
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
3183+
return false;
3184+
31783185
id.dev = statbuf.st_dev;
31793186
id.ino = statbuf.st_ino;
31803187

@@ -3951,3 +3958,21 @@ std::string simplecpp::getCppStdString(const std::string &std)
39513958
{
39523959
return getCppStdString(getCppStd(std));
39533960
}
3961+
3962+
static mode_t file_type(const std::string &path)
3963+
{
3964+
struct stat file_stat;
3965+
if (stat(path.c_str(), &file_stat) == -1)
3966+
return 0;
3967+
return file_stat.st_mode & S_IFMT;
3968+
}
3969+
3970+
bool simplecpp::isFile(const std::string &path)
3971+
{
3972+
return file_type(path) == S_IFREG;
3973+
}
3974+
3975+
bool simplecpp::isDirectory(const std::string &path)
3976+
{
3977+
return file_type(path) == S_IFDIR;
3978+
}

simplecpp.h

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

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

test.cpp

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

2231+
#ifndef _WIN32
2232+
static void missingHeader5()
2233+
{
2234+
// this is a directory
2235+
const char code[] = "#include \"/\"\n";
2236+
simplecpp::OutputList outputList;
2237+
ASSERT_EQUALS("", preprocess(code, &outputList));
2238+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/\"\n", toString(outputList));
2239+
}
2240+
2241+
static void missingHeader6()
2242+
{
2243+
// this is a directory
2244+
const char code[] = "#include \"/usr\"\n";
2245+
simplecpp::OutputList outputList;
2246+
ASSERT_EQUALS("", preprocess(code, &outputList));
2247+
ASSERT_EQUALS("file0,1,missing_header,Header not found: \"/usr\"\n", toString(outputList));
2248+
}
2249+
2250+
static void missingHeader7()
2251+
{
2252+
// this is a directory
2253+
const char code[] = "#include </>\n";
2254+
simplecpp::OutputList outputList;
2255+
ASSERT_EQUALS("", preprocess(code, &outputList));
2256+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </>\n", toString(outputList));
2257+
}
2258+
2259+
static void missingHeader8()
2260+
{
2261+
// this is a directory
2262+
const char code[] = "#include </usr>\n";
2263+
simplecpp::OutputList outputList;
2264+
ASSERT_EQUALS("", preprocess(code, &outputList));
2265+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </usr>\n", toString(outputList));
2266+
}
2267+
#endif
2268+
22312269
static void nestedInclude()
22322270
{
22332271
const char code[] = "#include \"test.h\"\n";
@@ -3598,6 +3636,14 @@ static void leak()
35983636
"#define e\n";
35993637
(void)preprocess(code, simplecpp::DUI());
36003638
}
3639+
{
3640+
const char code[] = "#include</\\\\>\n"
3641+
"#include</\\\\>\n";
3642+
simplecpp::OutputList outputList;
3643+
ASSERT_EQUALS("", preprocess(code, &outputList));
3644+
ASSERT_EQUALS("file0,1,missing_header,Header not found: </\\\\>\n"
3645+
"file0,2,missing_header,Header not found: </\\\\>\n", toString(outputList));
3646+
}
36013647
}
36023648

36033649
int main(int argc, char **argv)
@@ -3780,6 +3826,12 @@ int main(int argc, char **argv)
37803826
TEST_CASE(missingHeader2);
37813827
TEST_CASE(missingHeader3);
37823828
TEST_CASE(missingHeader4);
3829+
#ifndef _WIN32
3830+
TEST_CASE(missingHeader5);
3831+
TEST_CASE(missingHeader6);
3832+
TEST_CASE(missingHeader7);
3833+
TEST_CASE(missingHeader8);
3834+
#endif
37833835
TEST_CASE(nestedInclude);
37843836
TEST_CASE(systemInclude);
37853837
TEST_CASE(circularInclude);

0 commit comments

Comments
 (0)