Skip to content

Commit

Permalink
Merge pull request #1572 from berryzplus/feature/remake_CFilePath_GetExt
Browse files Browse the repository at this point in the history
SonarCloudにBugだと言われているCFilePath::GetExtの領域外アクセスに対処する
  • Loading branch information
berryzplus authored Mar 9, 2021
2 parents f2512c7 + d80d268 commit 7d69bcc
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 16 deletions.
36 changes: 20 additions & 16 deletions sakura_core/basis/CMyString.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ class CFilePath : public StaticString<WCHAR,_MAX_PATH>{
private:
typedef StaticString<WCHAR,_MAX_PATH> Super;
public:
CFilePath() : Super() { }
CFilePath() = default;
CFilePath(const WCHAR* rhs) : Super(rhs) { }

bool IsValidPath() const{ return At(0)!=L'\0'; }
std::wstring GetDirPath() const
[[nodiscard]] bool IsValidPath() const{ return At(0)!=L'\0'; }
[[nodiscard]] std::wstring GetDirPath() const
{
WCHAR szDirPath[_MAX_PATH];
WCHAR szDrive[_MAX_DRIVE];
Expand All @@ -59,22 +59,26 @@ class CFilePath : public StaticString<WCHAR,_MAX_PATH>{
wcscat( szDirPath, szDir );
return szDirPath;
}

//拡張子を取得する
LPCWSTR GetExt( bool bWithoutDot = false ) const
[[nodiscard]] LPCWSTR GetExt( bool bWithoutDot = false ) const
{
const WCHAR* head = c_str();
const WCHAR* p = wcschr(head,L'\0') - 1;
while(p>=head){
if(*p==L'.')break;
if(*p==L'\\')break;
if(*p==L'/')break;
p--;
}
if(p>=head && *p==L'.'){
return bWithoutDot ? p+1 : p; //bWithoutDot==trueならドットなしを返す
}else{
return wcschr(head,L'\0');
// 文字列の末尾アドレスを取得
const WCHAR* tail = c_str() + Length();

// 文字列末尾から逆方向に L'.' を検索
if (const auto *p = ::wcsrchr(c_str(), L'.')) {
// L'.'で始まる文字列がパス区切りを含まない場合のみ「拡張子あり」と看做す
if (const bool hasExt = !::wcspbrk(p, L"\\/"); hasExt && !bWithoutDot) {
return p;
}
else if (hasExt && p < tail) {
return p + 1; //bWithoutDot==trueならドットなしを返す
}
}

// 文字列末尾のアドレスを返す
return tail;
}
};

Expand Down
29 changes: 29 additions & 0 deletions tests/unittests/test-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,3 +443,32 @@ TEST(file, GetIniFileNameForIO)
std::filesystem::remove(iniPath);
ASSERT_FALSE(fexist(iniPath.c_str()));
}

/*!
GetExtのテスト
*/
TEST(CFilePath, GetExt)
{
CFilePath path;

// 最も単純なパターン
path = L"test.txt";
ASSERT_STREQ(L".txt", path.GetExt());
ASSERT_STREQ(L"txt", path.GetExt(true));

// ファイルに拡張子がないパターン
path = L"lib\\.NET Core\\README";
ASSERT_STREQ(L"", path.GetExt());
ASSERT_STREQ(L"", path.GetExt(true));

// 拡張子がない場合に返却されるポインタ値の確認
ASSERT_EQ(path.c_str() + path.Length(), path.GetExt());

// ファイルに拡張子がないパターン
path = L"lib/.NET Core/README";
ASSERT_STREQ(L"", path.GetExt());
ASSERT_STREQ(L"", path.GetExt(true));

// 拡張子がない場合に返却されるポインタ値の確認
ASSERT_EQ(path.c_str() + path.Length(), path.GetExt());
}

0 comments on commit 7d69bcc

Please sign in to comment.