diff options
author | kh <karsten.heimrich@theqtcompany.com> | 2014-11-28 16:41:15 +0100 |
---|---|---|
committer | Kai Koehne <kai.koehne@theqtcompany.com> | 2014-12-01 16:11:55 +0100 |
commit | 52e176b4a40d55b84aac762b77da5262687f6503 (patch) | |
tree | 221c07797e1edf60a40951e496beedb0d4cb15cd /src | |
parent | a439e6fab484461744a657f5173a738622064edf (diff) |
Fix online installation into directory with elevated permissions.
Inside the Resource class we can't use QFile, as that will access
the elevated running server to read from a only client side mapped
file. Adjust Resource::readData to behave properly with the file
engine's nativeRead(...) implementation, e.g. on Unix it returns
-1 if called to read with a size of 0 bytes.
Do not write to the socket if we are running in a different thread
than the one the socket was created in. Fix logically broken connect
function.
Task-number: QTIFW-572
Change-Id: I993b5d3a5c217b0aedbbc27837dce2619e51d224
Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
Reviewed-by: Takayuki ORITO <iori.ayane@gmail.com>
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/installer/binaryformat.cpp | 7 | ||||
-rw-r--r-- | src/libs/installer/binaryformat.h | 4 | ||||
-rw-r--r-- | src/libs/installer/remoteclient.cpp | 56 | ||||
-rw-r--r-- | src/libs/installer/remoteclient_p.h | 2 | ||||
-rw-r--r-- | src/libs/installer/remoteobject.cpp | 12 |
5 files changed, 41 insertions, 40 deletions
diff --git a/src/libs/installer/binaryformat.cpp b/src/libs/installer/binaryformat.cpp index 9cf7ef28a..015e21b2f 100644 --- a/src/libs/installer/binaryformat.cpp +++ b/src/libs/installer/binaryformat.cpp @@ -197,9 +197,14 @@ qint64 Resource::size() const */ qint64 Resource::readData(char* data, qint64 maxSize) { + // check if there is anything left to read + maxSize = qMin<quint64>(maxSize, m_segment.length() - pos()); + if (maxSize <= 0) + return 0; + const qint64 p = m_file.pos(); m_file.seek(m_segment.start() + pos()); - const qint64 amountRead = m_file.read(data, qMin<quint64>(maxSize, m_segment.length() - pos())); + const qint64 amountRead = m_file.read(data, maxSize); m_file.seek(p); return amountRead; } diff --git a/src/libs/installer/binaryformat.h b/src/libs/installer/binaryformat.h index 85bc96d8c..551c701ce 100644 --- a/src/libs/installer/binaryformat.h +++ b/src/libs/installer/binaryformat.h @@ -39,7 +39,7 @@ #include "range.h" #include <QCoreApplication> -#include <QFile> +#include <QtCore/private/qfsfileengine_p.h> #include <QList> #include <QSharedPointer> @@ -87,7 +87,7 @@ private: void setOpenMode(OpenMode mode) { QIODevice::setOpenMode(mode); } private: - QFile m_file; + QFSFileEngine m_file; QByteArray m_name; Range<qint64> m_segment; }; diff --git a/src/libs/installer/remoteclient.cpp b/src/libs/installer/remoteclient.cpp index d8c8478b6..573bd22ed 100644 --- a/src/libs/installer/remoteclient.cpp +++ b/src/libs/installer/remoteclient.cpp @@ -46,8 +46,6 @@ RemoteClient::RemoteClient() RemoteClient::~RemoteClient() { - Q_D(RemoteClient); - d->m_quit = true; } RemoteClient &RemoteClient::instance() @@ -94,39 +92,31 @@ void RemoteClient::shutdown() bool RemoteClient::connect(QTcpSocket *socket) const { Q_D(const RemoteClient); - if (d->m_quit) + socket->connectToHost(d->m_address, d->m_port); + + QElapsedTimer stopWatch; + stopWatch.start(); + while ((socket->state() == QAbstractSocket::ConnectingState) + && (stopWatch.elapsed() < 30000)) { + if ((stopWatch.elapsed() % 2500) == 0) + QCoreApplication::processEvents(); + } + + if (socket->state() != QAbstractSocket::ConnectedState) return false; - int tries = 3; - while ((tries > 0) && (!d->m_quit)) { - socket->connectToHost(d->m_address, d->m_port); - - QElapsedTimer stopWatch; - stopWatch.start(); - while ((socket->state() == QAbstractSocket::ConnectingState) - && (stopWatch.elapsed() < 10000) && (!d->m_quit)) { - --tries; - if (!QCoreApplication::closingDown()) - qApp->processEvents(); - continue; - } - if ((socket->state() != QAbstractSocket::ConnectedState) || d->m_quit) - return false; - - QDataStream stream; - stream.setDevice(socket); - stream << QString::fromLatin1(Protocol::Authorize) << d->m_key; - - socket->waitForBytesWritten(-1); - if (!socket->bytesAvailable()) - socket->waitForReadyRead(-1); - - quint32 size; stream >> size; - bool authorized; stream >> authorized; - if (authorized && (!d->m_quit)) - return true; - } - return false; + QDataStream stream; + stream.setDevice(socket); + stream << QString::fromLatin1(Protocol::Authorize) << authorizationKey(); + + socket->waitForBytesWritten(-1); + if (!socket->bytesAvailable()) + socket->waitForReadyRead(-1); + + quint32 size; stream >> size; + bool authorized = false; + stream >> authorized; + return authorized; } bool RemoteClient::isActive() const diff --git a/src/libs/installer/remoteclient_p.h b/src/libs/installer/remoteclient_p.h index fdcfabb64..6c1d41951 100644 --- a/src/libs/installer/remoteclient_p.h +++ b/src/libs/installer/remoteclient_p.h @@ -122,7 +122,6 @@ public: , m_key(QLatin1String(Protocol::DefaultAuthorizationKey)) , m_mode(Protocol::Mode::Debug) , m_object(0) - , m_quit(false) { } @@ -263,7 +262,6 @@ private: QThread m_thread; Protocol::Mode m_mode; KeepAliveObject *m_object; - volatile bool m_quit; }; } // namespace QInstaller diff --git a/src/libs/installer/remoteobject.cpp b/src/libs/installer/remoteobject.cpp index d69c49735..970eab228 100644 --- a/src/libs/installer/remoteobject.cpp +++ b/src/libs/installer/remoteobject.cpp @@ -37,6 +37,8 @@ #include "protocol.h" #include "remoteclient.h" +#include <QThread> + namespace QInstaller { RemoteObject::RemoteObject(const QString &wrappedType, QObject *parent) @@ -52,8 +54,14 @@ RemoteObject::RemoteObject(const QString &wrappedType, QObject *parent) RemoteObject::~RemoteObject() { if (m_socket) { - m_stream << QString::fromLatin1(Protocol::Destroy) << m_type; - m_socket->waitForBytesWritten(-1); + if (QThread::currentThread() == m_socket->thread()) { + m_stream << QString::fromLatin1(Protocol::Destroy) << m_type; + m_socket->waitForBytesWritten(-1); + } else { + Q_ASSERT_X(false, Q_FUNC_INFO, "Socket running in a different Thread than this object."); + } + m_socket->deleteLater(); + m_socket = 0; } } |