Fix saving 4GB+ files file size cutting off issue

This commit fixes invalid 64-bit to 32-bit castings of filesize integers.

Fix #12526, close #12736
This commit is contained in:
xomx 2022-12-31 03:29:40 +01:00 committed by Don Ho
parent 307fd2fcd2
commit c63c0035f3
5 changed files with 36 additions and 13 deletions

View File

@ -122,15 +122,38 @@ unsigned long Win32_IO_File::read(void *rbuf, unsigned long buf_size)
}
*/
bool Win32_IO_File::write(const void *wbuf, unsigned long buf_size)
bool Win32_IO_File::write(const void *wbuf, size_t buf_size)
{
if (!isOpened() || (wbuf == nullptr))
return false;
DWORD bytes_written = 0;
// we need to split any 4GB+ data for the WriteFile WINAPI later
constexpr DWORD c_max_dword = ~(DWORD(0)); // 0xFFFFFFFF
size_t total_bytes_written = 0;
size_t bytes_left_to_write = buf_size;
BOOL success = FALSE;
do
{
const DWORD bytes_to_write = (bytes_left_to_write < static_cast<size_t>(c_max_dword)) ?
static_cast<DWORD>(bytes_left_to_write) : c_max_dword;
DWORD bytes_written = 0;
success = ::WriteFile(_hFile, static_cast<const char*>(wbuf) + total_bytes_written,
bytes_to_write, &bytes_written, NULL);
if (success)
{
success = (bytes_written == bytes_to_write);
bytes_left_to_write -= static_cast<size_t>(bytes_written);
total_bytes_written += static_cast<size_t>(bytes_written);
}
} while (success && bytes_left_to_write);
NppParameters& nppParam = NppParameters::getInstance();
if (::WriteFile(_hFile, wbuf, buf_size, &bytes_written, NULL) == FALSE)
if (success == FALSE)
{
if (nppParam.isEndSessionStarted() && nppParam.doNppLogNulContentCorruptionIssue())
{
@ -160,7 +183,7 @@ bool Win32_IO_File::write(const void *wbuf, unsigned long buf_size)
std::string msg = _path;
msg += " ";
msg += std::to_string(bytes_written);
msg += std::to_string(total_bytes_written);
msg += "/";
msg += std::to_string(buf_size);
msg += " bytes are written.";
@ -171,6 +194,6 @@ bool Win32_IO_File::write(const void *wbuf, unsigned long buf_size)
if (!_written)
_written = true;
return (bytes_written == buf_size);
return (total_bytes_written == buf_size);
}

View File

@ -45,10 +45,10 @@ public:
//int_fast64_t getSize();
//unsigned long read(void *rbuf, unsigned long buf_size);
bool write(const void *wbuf, unsigned long buf_size);
bool write(const void *wbuf, size_t buf_size);
bool writeStr(const std::string& str) {
return write(str.c_str(), static_cast<unsigned long>(str.length()));
return write(str.c_str(), str.length());
};
private:

View File

@ -1036,7 +1036,7 @@ bool FileManager::backupCurrentBuffer()
if (encoding == -1) //no special encoding; can be handled directly by Utf8_16_Write
{
isWrittenSuccessful = UnicodeConvertor.writeFile(buf, static_cast<unsigned long>(lengthDoc));
isWrittenSuccessful = UnicodeConvertor.writeFile(buf, lengthDoc);
if (lengthDoc == 0)
isWrittenSuccessful = true;
}
@ -1054,7 +1054,7 @@ bool FileManager::backupCurrentBuffer()
int incompleteMultibyteChar = 0;
const char *newData = wmc.encode(SC_CP_UTF8, encoding, buf+i, static_cast<int>(grabSize), &newDataLen, &incompleteMultibyteChar);
grabSize -= incompleteMultibyteChar;
isWrittenSuccessful = UnicodeConvertor.writeFile(newData, static_cast<unsigned long>(newDataLen));
isWrittenSuccessful = UnicodeConvertor.writeFile(newData, newDataLen);
}
if (lengthDoc == 0)
isWrittenSuccessful = true;
@ -1170,7 +1170,7 @@ SavingStatus FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool i
if (encoding == -1) //no special encoding; can be handled directly by Utf8_16_Write
{
isWrittenSuccessful = UnicodeConvertor.writeFile(buf, static_cast<unsigned long>(lengthDoc));
isWrittenSuccessful = UnicodeConvertor.writeFile(buf, lengthDoc);
if (lengthDoc == 0)
isWrittenSuccessful = true;
}
@ -1194,7 +1194,7 @@ SavingStatus FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool i
int incompleteMultibyteChar = 0;
const char* newData = wmc.encode(SC_CP_UTF8, encoding, buf + i, static_cast<int>(grabSize), &newDataLen, &incompleteMultibyteChar);
grabSize -= incompleteMultibyteChar;
isWrittenSuccessful = UnicodeConvertor.writeFile(newData, static_cast<unsigned long>(newDataLen));
isWrittenSuccessful = UnicodeConvertor.writeFile(newData, newDataLen);
}
}
}

View File

@ -299,7 +299,7 @@ bool Utf8_16_Write::openFile(const TCHAR *name)
return true;
}
bool Utf8_16_Write::writeFile(const void* p, unsigned long _size)
bool Utf8_16_Write::writeFile(const void* p, size_t _size)
{
// no file open
if (!m_pFile)

View File

@ -140,7 +140,7 @@ public:
void setEncoding(UniMode eType);
bool openFile(const TCHAR *name);
bool writeFile(const void* p, unsigned long _size);
bool writeFile(const void* p, size_t _size);
void closeFile();
size_t convert(char* p, size_t _size);