diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index 845aeaf91..a3edd4a90 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -50,26 +50,53 @@ wstring commafyInt(size_t n) return ss.str(); } -std::string getFileContent(const wchar_t *file2read) +std::string getFileContent(const wchar_t* file2read, bool* pbFailed) { + if (pbFailed) + *pbFailed = false; // reset + if (!doesFileExist(file2read)) - return ""; - - const size_t blockSize = 1024; - char data[blockSize]; - std::string wholeFileContent = ""; - FILE *fp = _wfopen(file2read, L"rb"); - if (!fp) - return ""; - - size_t lenFile = 0; - do { - lenFile = fread(data, 1, blockSize, fp); - if (lenFile == 0) break; - wholeFileContent.append(data, lenFile); + if (pbFailed) + *pbFailed = true; + return ""; + } + + FILE* fp = _wfopen(file2read, L"rb"); + if (!fp) + { + if (pbFailed) + *pbFailed = true; + return ""; + } + + static constexpr size_t blockSize = 1024 * 4; // 4K is optimal chunk for memory, cache, disk or network + char data[blockSize]; + std::string wholeFileContent; + size_t lenFile = 0; + try + { + do + { + lenFile = fread(data, 1, blockSize, fp); + if (lenFile == 0) break; + wholeFileContent.append(data, lenFile); + } while (lenFile > 0); + } + catch ([[maybe_unused]] const std::bad_alloc& ex) + { + if (pbFailed) + *pbFailed = true; + std::string().swap(wholeFileContent); // to immediately release all the allocated memory + ::MessageBoxW(NULL, L"std::bad_alloc exception caught!\n\nProbably not enough contiguous memory to complete the operation.", + L"Notepad++ - getFileContent", MB_OK | MB_ICONWARNING | MB_APPLMODAL); + } + catch (...) + { + if (pbFailed) + *pbFailed = true; + std::string().swap(wholeFileContent); // to immediately release all the allocated memory } - while (lenFile > 0); fclose(fp); return wholeFileContent; diff --git a/PowerEditor/src/MISC/Common/Common.h b/PowerEditor/src/MISC/Common/Common.h index 54bed0dd6..c13ae75ef 100644 --- a/PowerEditor/src/MISC/Common/Common.h +++ b/PowerEditor/src/MISC/Common/Common.h @@ -56,7 +56,7 @@ std::string wstring2string(const std::wstring & rwString, UINT codepage); bool isInList(const wchar_t *token, const wchar_t *list); std::wstring BuildMenuFileName(int filenameLen, unsigned int pos, const std::wstring &filename, bool ordinalNumber = true); -std::string getFileContent(const wchar_t *file2read); +std::string getFileContent(const wchar_t* file2read, bool* pbFailed = nullptr); std::wstring relativeFilePathToFullFilePath(const wchar_t *relativeFilePath); void writeFileContent(const wchar_t *file2write, const char *content2write); bool matchInList(const wchar_t *fileName, const std::vector & patterns); diff --git a/PowerEditor/src/MISC/Common/verifySignedfile.cpp b/PowerEditor/src/MISC/Common/verifySignedfile.cpp index da2a2121c..e7f9d028f 100644 --- a/PowerEditor/src/MISC/Common/verifySignedfile.cpp +++ b/PowerEditor/src/MISC/Common/verifySignedfile.cpp @@ -72,7 +72,11 @@ bool SecurityGuard::checkSha256(const std::wstring& filePath, NppModule module2c return true; */ - std::string content = getFileContent(filePath.c_str()); + bool bLoadingFailed = false; + std::string content = getFileContent(filePath.c_str(), &bLoadingFailed); + if (bLoadingFailed) + return false; + uint8_t sha2hash[32]; calc_sha_256(sha2hash, reinterpret_cast(content.c_str()), content.length()); diff --git a/PowerEditor/src/MISC/md5/md5Dlgs.cpp b/PowerEditor/src/MISC/md5/md5Dlgs.cpp index bf43d1d11..19876e610 100644 --- a/PowerEditor/src/MISC/md5/md5Dlgs.cpp +++ b/PowerEditor/src/MISC/md5/md5Dlgs.cpp @@ -148,7 +148,10 @@ intptr_t CALLBACK HashFromFilesDlg::run_dlgProc(UINT message, WPARAM wParam, LPA } else { - std::string content = getFileContent(it.c_str()); + bool bLoadingFailed = false; + std::string content = getFileContent(it.c_str(), &bLoadingFailed); + if (bLoadingFailed) + return FALSE; uint8_t hash[HASH_MAX_LENGTH]{}; wchar_t hashStr[HASH_STR_MAX_LENGTH]{}; diff --git a/PowerEditor/src/Notepad_plus_Window.cpp b/PowerEditor/src/Notepad_plus_Window.cpp index b23b1aa46..e20833c63 100644 --- a/PowerEditor/src/Notepad_plus_Window.cpp +++ b/PowerEditor/src/Notepad_plus_Window.cpp @@ -376,24 +376,28 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const wchar_t *cmdL { if (doesFileExist(cmdLineParams->_easterEggName.c_str())) { - std::string content = getFileContent(cmdLineParams->_easterEggName.c_str()); - WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance(); - _userQuote = wmc.char2wchar(content.c_str(), SC_CP_UTF8); - if (!_userQuote.empty()) + bool bLoadingFailed = false; + std::string content = getFileContent(cmdLineParams->_easterEggName.c_str(), &bLoadingFailed); + if (!bLoadingFailed) { - _quoteParams.reset(); - _quoteParams._quote = _userQuote.c_str(); - _quoteParams._quoter = L"Anonymous #999"; - _quoteParams._shouldBeTrolling = false; - _quoteParams._lang = cmdLineParams->_langType; - if (cmdLineParams->_ghostTypingSpeed == 1) - _quoteParams._speed = QuoteParams::slow; - else if (cmdLineParams->_ghostTypingSpeed == 2) - _quoteParams._speed = QuoteParams::rapid; - else if (cmdLineParams->_ghostTypingSpeed == 3) - _quoteParams._speed = QuoteParams::speedOfLight; + WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance(); + _userQuote = wmc.char2wchar(content.c_str(), SC_CP_UTF8); + if (!_userQuote.empty()) + { + _quoteParams.reset(); + _quoteParams._quote = _userQuote.c_str(); + _quoteParams._quoter = L"Anonymous #999"; + _quoteParams._shouldBeTrolling = false; + _quoteParams._lang = cmdLineParams->_langType; + if (cmdLineParams->_ghostTypingSpeed == 1) + _quoteParams._speed = QuoteParams::slow; + else if (cmdLineParams->_ghostTypingSpeed == 2) + _quoteParams._speed = QuoteParams::rapid; + else if (cmdLineParams->_ghostTypingSpeed == 3) + _quoteParams._speed = QuoteParams::speedOfLight; - _notepad_plus_plus_core.showQuote(&_quoteParams); + _notepad_plus_plus_core.showQuote(&_quoteParams); + } } } } diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 16e2a8292..36e9a82eb 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -1238,10 +1238,14 @@ bool NppParameters::load() if (_isCloud) { // Read cloud choice - std::string cloudChoiceStr = getFileContent(cloudChoicePath.c_str()); - WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance(); - std::wstring cloudChoiceStrW = wmc.char2wchar(cloudChoiceStr.c_str(), SC_CP_UTF8); - + std::wstring cloudChoiceStrW = L""; + bool bLoadingFailed = false; + std::string cloudChoiceStr = getFileContent(cloudChoicePath.c_str(), &bLoadingFailed); + if (!bLoadingFailed) + { + WcharMbcsConvertor& wmc = WcharMbcsConvertor::getInstance(); + cloudChoiceStrW = wmc.char2wchar(cloudChoiceStr.c_str(), SC_CP_UTF8); + } if (!cloudChoiceStrW.empty() && doesDirectoryExist(cloudChoiceStrW.c_str())) { _userPath = cloudChoiceStrW;