diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2018-10-21 00:34:25 +0200 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2018-10-21 07:08:05 +0200 |
commit | 79e837d8e2fb961cd4825566f07aabf031fddb5f (patch) | |
tree | 74952c7f0a976a37e2649c72149bfe4abda4743e /desktop | |
parent | 70198d4f7ffc7b3139cf34764b0e6bb6971489c6 (diff) |
tdf#120703 (PVS): handle failed (re)allocations
V769 The 'readBuf' pointer in the 'readBuf + readAll' expression could be nullptr.
In such case, resulting value will be senseless and it should not be used.
Check lines: 171, 166.
V701 realloc() possible leak: when realloc() fails in allocating memory, original
pointer 'readBuf' is lost. Consider assigning realloc() to a temporary
pointer.
Change-Id: I2e15a1abb79516dd42d64256463333bb54eab5b8
Reviewed-on: https://gerrit.libreoffice.org/62117
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/win32/source/guistdio/guistdio.inc | 123 |
1 files changed, 67 insertions, 56 deletions
diff --git a/desktop/win32/source/guistdio/guistdio.inc b/desktop/win32/source/guistdio/guistdio.inc index eb1b9cda1639..ea466769d517 100644 --- a/desktop/win32/source/guistdio/guistdio.inc +++ b/desktop/win32/source/guistdio/guistdio.inc @@ -26,6 +26,7 @@ #include <stdio.h> #include <sal/macros.h> +#include <o3tl/make_unique.hxx> #ifdef UNOPKG @@ -147,70 +148,80 @@ DWORD WINAPI InputThread( LPVOID pParam ) { DWORD dwRead = 0; HANDLE hWritePipe = static_cast<HANDLE>(pParam); - - //We need to read in the complete input until we encounter a new line before - //converting to Unicode. This is necessary because the input string can use - //characters of one, two, and more bytes. If the last character is not - //complete, then it will not be converted properly. - - //Find out how a new line (0xd 0xa) looks like with the used code page. - //Characters may have one or multiple bytes and different byte ordering - //can be used (little and big endian); - int cNewLine = WideCharToMultiByte( - GetConsoleCP(), 0, L"\r\n", 2, nullptr, 0, nullptr, nullptr); - char * mbBuff = new char[cNewLine]; - WideCharToMultiByte( - GetConsoleCP(), 0, L"\r\n", 2, mbBuff, cNewLine, nullptr, nullptr); - - const DWORD dwBufferSize = 256; - char* readBuf = static_cast<char*>(malloc(dwBufferSize)); - int readAll = 0; - DWORD curBufSize = dwBufferSize; - - while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), - readBuf + readAll, - curBufSize - readAll, &dwRead, nullptr ) ) + char* readBuf = nullptr; + try { - readAll += dwRead; - int lastBufSize = curBufSize; - //Grow the buffer if necessary - if (readAll > curBufSize * 0.7) + //We need to read in the complete input until we encounter a new line before + //converting to Unicode. This is necessary because the input string can use + //characters of one, two, and more bytes. If the last character is not + //complete, then it will not be converted properly. + + //Find out how a new line (0xd 0xa) looks like with the used code page. + //Characters may have one or multiple bytes and different byte ordering + //can be used (little and big endian); + int cNewLine = WideCharToMultiByte( + GetConsoleCP(), 0, L"\r\n", 2, nullptr, 0, nullptr, nullptr); + auto mbBuff = o3tl::make_unique<char[]>(cNewLine); + WideCharToMultiByte( + GetConsoleCP(), 0, L"\r\n", 2, mbBuff.get(), cNewLine, nullptr, nullptr); + + const DWORD dwBufferSize = 256; + readBuf = static_cast<char*>(malloc(dwBufferSize)); + if (!readBuf) + throw std::bad_alloc(); + int readAll = 0; + DWORD curBufSize = dwBufferSize; + + while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), + readBuf + readAll, + curBufSize - readAll, &dwRead, nullptr ) ) { - curBufSize *= 2; - readBuf = static_cast<char *>(realloc(readBuf, curBufSize)); - } + readAll += dwRead; + int lastBufSize = curBufSize; + //Grow the buffer if necessary + if (readAll > curBufSize * 0.7) + { + curBufSize *= 2; + if (auto p = static_cast<char *>(realloc(readBuf, curBufSize))) + readBuf = p; + else + { + throw std::bad_alloc(); + } + } - //If the buffer was filled completely then - //there could be more input coming. But if we read from the console - //and the console input fits exactly in the buffer, then the next - //ReadFile would block until the users presses return, etc. - //Therefore we check if last character is a new line. - //To test this, set dwBufferSize to 4 and enter "no". This should produce - //4 bytes with most code pages. - if ( readAll == lastBufSize - && memcmp(readBuf + lastBufSize - cNewLine, mbBuff, cNewLine) != 0) - { - //The buffer was completely filled and the last byte(s) are no - //new line, so there is more to come. - continue; - } - //Obtain the size of the buffer for the converted string. - int sizeWBuf = MultiByteToWideChar( - GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, nullptr, 0); + //If the buffer was filled completely then + //there could be more input coming. But if we read from the console + //and the console input fits exactly in the buffer, then the next + //ReadFile would block until the users presses return, etc. + //Therefore we check if last character is a new line. + //To test this, set dwBufferSize to 4 and enter "no". This should produce + //4 bytes with most code pages. + if ( readAll == lastBufSize + && memcmp(readBuf + lastBufSize - cNewLine, mbBuff.get(), cNewLine) != 0) + { + //The buffer was completely filled and the last byte(s) are no + //new line, so there is more to come. + continue; + } + //Obtain the size of the buffer for the converted string. + int sizeWBuf = MultiByteToWideChar( + GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, nullptr, 0); - wchar_t * wideBuf = new wchar_t[sizeWBuf]; + auto wideBuf = o3tl::make_unique<wchar_t[]>(sizeWBuf); - //Do the conversion. - MultiByteToWideChar( - GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, wideBuf, sizeWBuf); + //Do the conversion. + MultiByteToWideChar( + GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, wideBuf.get(), sizeWBuf); - DWORD dwWritten; - (void)WriteFile( hWritePipe, wideBuf, sizeWBuf * 2, &dwWritten, nullptr ); + DWORD dwWritten; + (void)WriteFile( hWritePipe, wideBuf.get(), sizeWBuf * 2, &dwWritten, nullptr ); - delete[] wideBuf; - readAll = 0; + readAll = 0; + } } - delete[] mbBuff; + catch (...) + {} free(readBuf); return 0; } |