Fix freeze and high CPU usage on invalid STDIN data, resolves #1620

This commit is contained in:
Janek Bevendorff 2018-03-04 23:56:06 +01:00
parent 386b78b896
commit 63a17f697c
3 changed files with 41 additions and 23 deletions

View file

@ -107,18 +107,26 @@ void NativeMessagingHost::readLength()
void NativeMessagingHost::readStdIn(const quint32 length) void NativeMessagingHost::readStdIn(const quint32 length)
{ {
if (length > 0) { if (length <= 0) {
QByteArray arr; return;
arr.reserve(length); }
for (quint32 i = 0; i < length; ++i) { QByteArray arr;
arr.append(getchar()); arr.reserve(length);
}
if (arr.length() > 0) { QMutexLocker locker(&m_mutex);
QMutexLocker locker(&m_mutex);
sendReply(m_browserClients.readResponse(arr)); for (quint32 i = 0; i < length; ++i) {
int c = std::getchar();
if (c == EOF) {
// message ended prematurely, ignore it and return
return;
} }
arr.append(static_cast<char>(c));
}
if (arr.length() > 0) {
sendReply(m_browserClients.readResponse(arr));
} }
} }

View file

@ -143,12 +143,15 @@ int main(int argc, char** argv)
const bool pwstdin = parser.isSet(pwstdinOption); const bool pwstdin = parser.isSet(pwstdinOption);
for (const QString& filename: fileNames) { for (const QString& filename: fileNames) {
QString password;
if (pwstdin) {
// we always need consume a line of STDIN if --pw-stdin is set to clear out the
// buffer for native messaging, even if the specified file does not exist
static QTextStream in(stdin, QIODevice::ReadOnly);
password = in.readLine();
}
if (!filename.isEmpty() && QFile::exists(filename) && !filename.endsWith(".json", Qt::CaseInsensitive)) { if (!filename.isEmpty() && QFile::exists(filename) && !filename.endsWith(".json", Qt::CaseInsensitive)) {
QString password;
if (pwstdin) {
static QTextStream in(stdin, QIODevice::ReadOnly);
password = in.readLine();
}
mainWindow.openDatabase(filename, password, parser.value(keyfileOption)); mainWindow.openDatabase(filename, password, parser.value(keyfileOption));
} }
} }

View file

@ -51,18 +51,25 @@ void NativeMessagingHost::readLength()
void NativeMessagingHost::readStdIn(const quint32 length) void NativeMessagingHost::readStdIn(const quint32 length)
{ {
if (length > 0) { if (length <= 0) {
QByteArray arr; return;
arr.reserve(length); }
for (quint32 i = 0; i < length; ++i) { QByteArray arr;
arr.append(getchar()); arr.reserve(length);
}
if (arr.length() > 0 && m_localSocket && m_localSocket->state() == QLocalSocket::ConnectedState) { for (quint32 i = 0; i < length; ++i) {
m_localSocket->write(arr.constData(), arr.length()); int c = std::getchar();
m_localSocket->flush(); if (c == EOF) {
// message ended prematurely, ignore it and return
return;
} }
arr.append(static_cast<char>(c));
}
if (arr.length() > 0 && m_localSocket && m_localSocket->state() == QLocalSocket::ConnectedState) {
m_localSocket->write(arr.constData(), arr.length());
m_localSocket->flush();
} }
} }