summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2018-10-21 00:34:25 +0200
committerMike Kaganski <mike.kaganski@collabora.com>2018-10-21 07:08:05 +0200
commit79e837d8e2fb961cd4825566f07aabf031fddb5f (patch)
tree74952c7f0a976a37e2649c72149bfe4abda4743e
parent70198d4f7ffc7b3139cf34764b0e6bb6971489c6 (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>
-rw-r--r--desktop/win32/source/guistdio/guistdio.inc123
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;
}