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:
parent
307fd2fcd2
commit
c63c0035f3
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue