summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPasi Pentikainen <ext-pasi.a.pentikainen@nokia.com>2012-01-12 22:41:28 +0200
committerPasi Pentikainen <ext-pasi.a.pentikainen@nokia.com>2012-01-12 22:41:28 +0200
commitb902cccfab0ad8b87b4edcc479c266132ae267e0 (patch)
tree7a5b25dd85bd4dcff033655734268b1902f78579
parent443f2df750ac01b3c598d833d5c067798c1e670d (diff)
parentc5ddcb3387f968ce0c2ac6420a05c5ebc528b260 (diff)
downloadqt4-tools-b902cccfab0ad8b87b4edcc479c266132ae267e0.tar.gz
Merge commit 'c5ddcb33' into 4.8.0-symbian
* commit 'c5ddcb33': Fix http authentication to a different realm on the same server Fix race in http connection channel Don't fetch credentials from cache following a failed proxy authentication Handle plain socket write errors in SSL Fix for assertion failure Fix faulty logic in http connection pipelining Test case for QTBUG-22875 QThreads on Symbian are named to allow them to be opened externally Symbian: Fix exporting and importing of some functions for autotests Symbian: Fix SRCDIR usage in qlayout autotest. Symbian: Fix qcssparser autotest Symbian: Fix qscriptextensionplugin autotest Fix missing part from commit dae052cb11c0018121f2c4028aed9db17769fd77 Fix m_longTapDetector causing crash. Fix to incorrect ApplicationActivate event in QtOpenGL Symbian - Fix QFile::map with non page aligned offsets Symbian: fix tst_QMenuBar::task256322_highlight() regression Default to QDir::homePath() in Symbian native file dialogs Fix NTLM authentication with email address Fix null pointer dereference in NTLM authentication Change-Id: Ie087fce22bb0c6605de308975eba483885708bb3
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp8
-rw-r--r--src/corelib/thread/qthread_symbian.cpp18
-rw-r--r--src/gui/dialogs/qfiledialog_symbian.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp2
-rw-r--r--src/gui/kernel/qapplication_s60.cpp57
-rw-r--r--src/gui/kernel/qwidget.cpp1
-rw-r--r--src/gui/kernel/qwidget_p.h1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp18
-rw-r--r--src/gui/painting/qmatrix.cpp2
-rw-r--r--src/gui/painting/qpainter.cpp2
-rw-r--r--src/gui/painting/qpdf.cpp2
-rw-r--r--src/gui/painting/qtransform.cpp2
-rw-r--r--src/gui/widgets/qmenubar.cpp2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp25
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp15
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h2
-rw-r--r--src/network/access/qnetworkaccessauthenticationmanager.cpp12
-rw-r--r--src/network/access/qnetworkaccessauthenticationmanager_p.h2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp12
-rw-r--r--src/network/kernel/qauthenticator.cpp18
-rw-r--r--src/network/kernel/qauthenticator_p.h1
-rw-r--r--src/network/socket/qhttpsocketengine.cpp20
-rw-r--r--src/network/socket/qhttpsocketengine_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp11
-rw-r--r--src/opengl/qgl_p.h8
-rw-r--r--src/opengl/qwindowsurface_gl.cpp25
-rw-r--r--src/opengl/qwindowsurface_gl_p.h1
-rw-r--r--tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp2
-rw-r--r--tests/auto/qcssparser/qcssparser.pro5
-rw-r--r--tests/auto/qgl/tst_qgl.cpp2
-rw-r--r--tests/auto/qlayout/tst_qlayout.cpp4
-rw-r--r--tests/auto/qmdisubwindow/tst_qmdisubwindow.cpp2
-rw-r--r--tests/auto/qnetworkreply/tst_qnetworkreply.cpp218
-rw-r--r--tests/auto/qpixmapcache/tst_qpixmapcache.cpp2
-rw-r--r--tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp2
-rw-r--r--tests/auto/qregion/tst_qregion.cpp2
-rw-r--r--tests/auto/qscriptcontext/tst_qscriptcontext.cpp2
-rw-r--r--tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro1
-rw-r--r--tests/auto/qscriptextensionplugin/test/test.pro9
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp2
-rw-r--r--tests/auto/qtextedit/tst_qtextedit.cpp2
-rw-r--r--tests/auto/qtextlayout/tst_qtextlayout.cpp4
43 files changed, 439 insertions, 94 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 4961722194..781a5f0130 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -1058,22 +1058,24 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
TInt nativeMapError = KErrNone;
RFileMap mapping;
TUint mode(EFileMapRemovableMedia);
+ TUint64 nativeOffset = offset & ~(mapping.PageSizeInBytes() - 1);
+
//If the file was opened for write or read/write, then open the map for read/write
if (openMode & QIODevice::WriteOnly)
mode |= EFileMapWrite;
if (symbianFile.SubSessionHandle()) {
- nativeMapError = mapping.Open(symbianFile, offset, size, mode);
+ nativeMapError = mapping.Open(symbianFile, nativeOffset, size, mode);
} else {
//map file by name if we don't have a native handle
QString fn = QFileSystemEngine::absoluteName(fileEntry).nativeFilePath();
TUint filemode = EFileShareReadersOrWriters | EFileRead;
if (openMode & QIODevice::WriteOnly)
filemode |= EFileWrite;
- nativeMapError = mapping.Open(qt_s60GetRFs(), qt_QString2TPtrC(fn), filemode, offset, size, mode);
+ nativeMapError = mapping.Open(qt_s60GetRFs(), qt_QString2TPtrC(fn), filemode, nativeOffset, size, mode);
}
if (nativeMapError == KErrNone) {
QScopedResource<RFileMap> ptr(mapping); //will call Close if adding to mapping throws an exception
- uchar *address = mapping.Base();
+ uchar *address = mapping.Base() + (offset - nativeOffset);
maps[address] = mapping;
ptr.take();
return address;
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp
index 2ea1b447b8..78bb293c75 100644
--- a/src/corelib/thread/qthread_symbian.cpp
+++ b/src/corelib/thread/qthread_symbian.cpp
@@ -46,10 +46,12 @@
#include "qthreadstorage.h"
#include "qthread_p.h"
#include <private/qsystemerror_p.h>
+#include <private/qcore_symbian_p.h>
#include <sched.h>
#include <hal.h>
#include <hal_data.h>
+#include <e32math.h>
// You only find these enumerations on Symbian^3 onwards, so we need to provide our own
// to remain compatible with older releases. They won't be called by pre-Sym^3 SDKs.
@@ -509,7 +511,21 @@ void QThread::start(Priority priority)
// operations like file I/O fail, so we increase it by default.
d->stackSize = 0x14000; // Maximum stack size on Symbian.
- int code = d->data->symbian_thread_handle.Create(KNullDesC, (TThreadFunction) QThreadPrivate::start, d->stackSize, NULL, this);
+ int code = KErrAlreadyExists;
+ QString objName = objectName();
+ TPtrC objNamePtr(qt_QString2TPtrC(objName));
+ TName name;
+ objNamePtr.Set(objNamePtr.Left(qMin(objNamePtr.Length(), name.MaxLength() - 16)));
+ const int MaxRetries = 10;
+ for (int i=0; i<MaxRetries && code == KErrAlreadyExists; i++) {
+ // generate a thread name using a similar method to libpthread in Symbian
+ // a named thread can be opened from another process
+ name.Zero();
+ name.Append(objNamePtr);
+ name.AppendNumFixedWidth(int(this), EHex, 8);
+ name.AppendNumFixedWidth(Math::Random(), EHex, 8);
+ code = d->data->symbian_thread_handle.Create(name, (TThreadFunction) QThreadPrivate::start, d->stackSize, NULL, this);
+ }
if (code == KErrNone) {
d->thread_id = d->data->symbian_thread_handle.Id();
TThreadPriority symPriority = calculateSymbianPriority(priority);
diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp
index 1ffbf1dfe2..01c7b9b7db 100644
--- a/src/gui/dialogs/qfiledialog_symbian.cpp
+++ b/src/gui/dialogs/qfiledialog_symbian.cpp
@@ -143,8 +143,8 @@ static QString launchSymbianDialog(const QString dialogCaption, const QString st
tryCount = 0;
} else {
// Symbian native file dialog doesn't allow accessing files outside C:/Data
- // It will always leave in that case, so default into QDir::rootPath() in error cases.
- QString dir = QDir::toNativeSeparators(QDir::rootPath());
+ // It will always leave in that case, so default into QDir::homePath() in error cases.
+ QString dir = QDir::toNativeSeparators(QDir::homePath());
startFolder = qt_QString2TPtrC(dir);
}
}
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 9ea0b8387f..532af247da 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -9509,7 +9509,7 @@ QVariant QGraphicsLineItem::extension(const QVariant &variant) const
QPixmap::createHeuristicMask(). The performance and memory consumption
is similar to MaskShape.
*/
-extern QPainterPath qt_regionToPath(const QRegion &region);
+extern Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region);
class QGraphicsPixmapItemPrivate : public QGraphicsItemPrivate
{
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index d2e21fba89..4e6f91637a 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -1023,7 +1023,7 @@ void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array
delete [] array;
}
-extern QPainterPath qt_regionToPath(const QRegion &region);
+extern Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region);
/*!
### Adjustments in findItems: mapToScene(QRect) forces us to adjust the
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 587c0f2d31..1518d2ddf4 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -552,11 +552,13 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
// the control's window
qwidget->d_func()->createExtra();
- SetFocusing(true);
- m_longTapDetector = QLongTapTimer::NewL(this);
- m_doubleClickTimer.invalidate();
+ if (!qwidget->d_func()->isGLGlobalShareWidget) {
+ SetFocusing(true);
+ m_longTapDetector = QLongTapTimer::NewL(this);
+ m_doubleClickTimer.invalidate();
- DrawableWindow()->SetPointerGrab(ETrue);
+ DrawableWindow()->SetPointerGrab(ETrue);
+ }
}
#ifdef Q_SYMBIAN_TRANSITION_EFFECTS
@@ -590,25 +592,27 @@ void QSymbianControl::ConstructL(bool isWindowOwning, bool desktop)
QSymbianControl::~QSymbianControl()
{
- // Ensure backing store is deleted before the top-level
- // window is destroyed
- QT_TRY {
- qt_widget_private(qwidget)->topData()->backingStore.destroy();
- } QT_CATCH(const std::exception&) {
- // ignore exceptions, nothing can be done
- }
-
- if (S60->curWin == this)
- S60->curWin = 0;
- if (!QApplicationPrivate::is_app_closing) {
+ if (!qwidget->d_func()->isGLGlobalShareWidget) { // GLGlobalShareWidget doesn't interact with scene
+ // Ensure backing store is deleted before the top-level
+ // window is destroyed
QT_TRY {
- setFocusSafely(false);
+ qt_widget_private(qwidget)->topData()->backingStore.destroy();
} QT_CATCH(const std::exception&) {
// ignore exceptions, nothing can be done
}
+
+ if (S60->curWin == this)
+ S60->curWin = 0;
+ if (!QApplicationPrivate::is_app_closing) {
+ QT_TRY {
+ setFocusSafely(false);
+ } QT_CATCH(const std::exception&) {
+ // ignore exceptions, nothing can be done
+ }
+ }
+ S60->appUi()->RemoveFromStack(this);
+ delete m_longTapDetector;
}
- S60->appUi()->RemoveFromStack(this);
- delete m_longTapDetector;
}
void QSymbianControl::setWidget(QWidget *w)
@@ -826,7 +830,8 @@ void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
const TPointerEvent *pointerEvent = eventData.Pointer(i);
const TAdvancedPointerEvent *advEvent = pointerEvent->AdvancedPointerEvent();
if (!advEvent || advEvent->PointerNumber() == 0) {
- m_longTapDetector->PointerEventL(*pointerEvent);
+ if (m_longTapDetector)
+ m_longTapDetector->PointerEventL(*pointerEvent);
QT_TRYCATCH_LEAVING(HandlePointerEvent(*pointerEvent));
}
}
@@ -843,8 +848,8 @@ void QSymbianControl::HandlePointerEventL(const TPointerEvent& pEvent)
}
}
#endif
-
- m_longTapDetector->PointerEventL(pEvent);
+ if (m_longTapDetector)
+ m_longTapDetector->PointerEventL(pEvent);
QT_TRYCATCH_LEAVING(HandlePointerEvent(pEvent));
}
@@ -1535,6 +1540,10 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop)
return;
+ // just in case
+ if (qwidget->d_func()->isGLGlobalShareWidget)
+ return;
+
#ifdef Q_WS_S60
if (S60->splitViewLastWidget)
return;
@@ -1710,7 +1719,8 @@ void QSymbianControl::HandleResourceChange(int resourceType)
}
void QSymbianControl::CancelLongTapTimer()
{
- m_longTapDetector->Cancel();
+ if (m_longTapDetector)
+ m_longTapDetector->Cancel();
}
TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id)
@@ -1723,6 +1733,9 @@ TTypeUid::Ptr QSymbianControl::MopSupplyObject(TTypeUid id)
void QSymbianControl::setFocusSafely(bool focus)
{
+ if (qwidget->d_func()->isGLGlobalShareWidget)
+ return;
+
// The stack hack in here is very unfortunate, but it is the only way to ensure proper
// focus in Symbian. If this is not executed, the control which happens to be on
// the top of the stack may randomly be assigned focus by Symbian, for example
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 7055c6b4b7..bceda662f0 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -314,6 +314,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
#elif defined(Q_OS_SYMBIAN)
, symbianScreenNumber(0)
, fixNativeOrientationCalled(false)
+ , isGLGlobalShareWidget(0)
#endif
{
if (!qApp) {
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 9ac94795d5..94c1d630b1 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -916,6 +916,7 @@ public:
void reparentChildren();
void registerTouchWindow();
QList<WId> widCleanupList;
+ uint isGLGlobalShareWidget : 1;
#endif
};
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index a37c265f8e..fefa781fb5 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -393,16 +393,18 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
stackingFlags = ECoeStackFlagStandard;
}
control->MakeVisible(false);
- QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags));
- // Avoid keyboard focus to a hidden window.
- control->setFocusSafely(false);
- RDrawableWindow *const drawableWindow = control->DrawableWindow();
- // Request mouse move events.
- drawableWindow->PointerFilter(EPointerFilterEnterExit
- | EPointerFilterMove | EPointerFilterDrag, 0);
- drawableWindow->EnableVisibilityChangeEvents();
+ if (!isGLGlobalShareWidget) {
+ QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags));
+ // Avoid keyboard focus to a hidden window.
+ control->setFocusSafely(false);
+ RDrawableWindow *const drawableWindow = control->DrawableWindow();
+ // Request mouse move events.
+ drawableWindow->PointerFilter(EPointerFilterEnterExit
+ | EPointerFilterMove | EPointerFilterDrag, 0);
+ drawableWindow->EnableVisibilityChangeEvents();
+ }
}
q->setAttribute(Qt::WA_WState_Created);
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
index 6209e66a7b..2c91f1d417 100644
--- a/src/gui/painting/qmatrix.cpp
+++ b/src/gui/painting/qmatrix.cpp
@@ -654,7 +654,7 @@ QPolygonF QMatrix::map(const QPolygonF &a) const
\sa QMatrix::map()
*/
-extern QPainterPath qt_regionToPath(const QRegion &region);
+extern Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region);
/*!
\fn QRegion QMatrix::map(const QRegion &region) const
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 72357a6869..619dbdd1b3 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -2663,7 +2663,7 @@ QRegion QPainter::clipRegion() const
return region;
}
-extern QPainterPath qt_regionToPath(const QRegion &region);
+extern Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region);
/*!
Returns the currently clip as a path. Note that the clip path is
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 958e49907b..2954190012 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1231,7 +1231,7 @@ void QPdfBaseEngine::setupGraphicsState(QPaintEngine::DirtyFlags flags)
setPen();
}
-extern QPainterPath qt_regionToPath(const QRegion &region);
+extern Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region);
void QPdfBaseEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
{
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 4d7b3391a6..be263bb23e 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -1454,7 +1454,7 @@ QPolygon QTransform::map(const QPolygon &a) const
\sa QTransform::map()
*/
-extern QPainterPath qt_regionToPath(const QRegion &region);
+extern Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region);
/*!
\fn QRegion QTransform::map(const QRegion &region) const
diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp
index 3e5365c7a7..ec7923773e 100644
--- a/src/gui/widgets/qmenubar.cpp
+++ b/src/gui/widgets/qmenubar.cpp
@@ -1111,8 +1111,10 @@ void QMenuBar::setVisible(bool visible)
#else
#if defined(Q_WS_MAC) || defined(Q_OS_WINCE) || defined(Q_WS_S60)
if (isNativeMenuBar()) {
+#ifndef Q_WS_S60
if (!visible)
QWidget::setVisible(false);
+#endif
return;
}
#endif
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 0365703f9c..33e3be9802 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -375,9 +375,23 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
if (priv->phase == QAuthenticatorPrivate::Done) {
pauseConnection();
if (!isProxy) {
+ if (channels[i].authenticationCredentialsSent) {
+ auth->detach();
+ priv = QAuthenticatorPrivate::getPrivate(*auth);
+ priv->hasFailed = true;
+ priv->phase = QAuthenticatorPrivate::Done;
+ channels[i].authenticationCredentialsSent = false;
+ }
emit reply->authenticationRequired(reply->request(), auth);
#ifndef QT_NO_NETWORKPROXY
} else {
+ if (channels[i].proxyCredentialsSent) {
+ auth->detach();
+ priv = QAuthenticatorPrivate::getPrivate(*auth);
+ priv->hasFailed = true;
+ priv->phase = QAuthenticatorPrivate::Done;
+ channels[i].proxyCredentialsSent = false;
+ }
emit reply->proxyAuthenticationRequired(networkProxy, auth);
#endif
}
@@ -415,7 +429,6 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
reply->d_func()->errorString = errorDetail(errorCode, socket);
emit reply->finishedWithError(errorCode, reply->d_func()->errorString);
// ### at this point the reply could be deleted
- socket->close();
return true;
}
//resend the request
@@ -438,6 +451,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
if (priv && priv->method != QAuthenticatorPrivate::None) {
QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false));
request.setHeaderField("Authorization", response);
+ channels[i].authenticationCredentialsSent = true;
}
}
}
@@ -449,6 +463,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
if (priv && priv->method != QAuthenticatorPrivate::None) {
QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false));
request.setHeaderField("Proxy-Authorization", response);
+ channels[i].proxyCredentialsSent = true;
}
}
}
@@ -582,9 +597,13 @@ void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket)
// we do not like authentication stuff
// ### make sure to be OK with this in later releases
- if (!channels[i].authenticator.isNull() || !channels[i].authenticator.user().isEmpty())
+ if (!channels[i].authenticator.isNull()
+ && (!channels[i].authenticator.user().isEmpty()
+ || !channels[i].authenticator.password().isEmpty()))
return;
- if (!channels[i].proxyAuthenticator.isNull() || !channels[i].proxyAuthenticator.user().isEmpty())
+ if (!channels[i].proxyAuthenticator.isNull()
+ && (!channels[i].proxyAuthenticator.user().isEmpty()
+ || !channels[i].proxyAuthenticator.password().isEmpty()))
return;
// must be in ReadingState or WaitingState
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index b9db7fe7ec..628114ae2a 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -73,6 +73,8 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
, lastStatus(0)
, pendingEncrypt(false)
, reconnectAttempts(2)
+ , authenticationCredentialsSent(false)
+ , proxyCredentialsSent(false)
, authMethod(QAuthenticatorPrivate::None)
, proxyAuthMethod(QAuthenticatorPrivate::None)
#ifndef QT_NO_OPENSSL
@@ -555,6 +557,14 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
// reset state
pipeliningSupported = PipeliningSupportUnknown;
+ authenticationCredentialsSent = false;
+ proxyCredentialsSent = false;
+ authenticator.detach();
+ QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(authenticator);
+ priv->hasFailed = false;
+ proxyAuthenticator.detach();
+ priv = QAuthenticatorPrivate::getPrivate(proxyAuthenticator);
+ priv->hasFailed = false;
// This workaround is needed since we use QAuthenticator for NTLM authentication. The "phase == Done"
// is the usual criteria for emitting authentication signals. The "phase" is set to "Done" when the
@@ -562,7 +572,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
// check the "phase" for generating the Authorization header. NTLM authentication is a two stage
// process & needs the "phase". To make sure the QAuthenticator uses the current username/password
// the phase is reset to Start.
- QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(authenticator);
+ priv = QAuthenticatorPrivate::getPrivate(authenticator);
if (priv && priv->phase == QAuthenticatorPrivate::Done)
priv->phase = QAuthenticatorPrivate::Start;
priv = QAuthenticatorPrivate::getPrivate(proxyAuthenticator);
@@ -837,6 +847,9 @@ void QHttpNetworkConnectionChannel::handleStatus()
closeAndResendCurrentRequest();
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
}
+ } else {
+ //authentication cancelled, close the channel.
+ close();
}
} else {
emit reply->headerChanged();
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index f635cc9557..31a286b3c8 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -113,6 +113,8 @@ public:
QAuthenticatorPrivate::Method proxyAuthMethod;
QAuthenticator authenticator;
QAuthenticator proxyAuthenticator;
+ bool authenticationCredentialsSent;
+ bool proxyCredentialsSent;
#ifndef QT_NO_OPENSSL
bool ignoreAllSslErrors;
QList<QSslError> ignoreSslErrorsList;
diff --git a/src/network/access/qnetworkaccessauthenticationmanager.cpp b/src/network/access/qnetworkaccessauthenticationmanager.cpp
index 1b15cf9cdf..9551b767df 100644
--- a/src/network/access/qnetworkaccessauthenticationmanager.cpp
+++ b/src/network/access/qnetworkaccessauthenticationmanager.cpp
@@ -159,6 +159,11 @@ void QNetworkAccessAuthenticationManager::cacheProxyCredentials(const QNetworkPr
QString realm = authenticator->realm();
QNetworkProxy proxy = p;
proxy.setUser(authenticator->user());
+
+ // don't cache null passwords, empty password may be valid though
+ if (authenticator->password().isNull())
+ return;
+
// Set two credentials: one with the username and one without
do {
// Set two credentials actually: one with and one without the realm
@@ -283,9 +288,12 @@ QNetworkAccessAuthenticationManager::fetchCachedCredentials(const QUrl &url,
QNetworkAuthenticationCache *auth =
static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey));
- QNetworkAuthenticationCredential cred = *auth->findClosestMatch(url.path());
+ QNetworkAuthenticationCredential *cred = auth->findClosestMatch(url.path());
+ QNetworkAuthenticationCredential ret;
+ if (cred)
+ ret = *cred;
authenticationCache.releaseEntry(cacheKey);
- return cred;
+ return ret;
}
void QNetworkAccessAuthenticationManager::clearCache()
diff --git a/src/network/access/qnetworkaccessauthenticationmanager_p.h b/src/network/access/qnetworkaccessauthenticationmanager_p.h
index ddfc11606d..718c58fc8d 100644
--- a/src/network/access/qnetworkaccessauthenticationmanager_p.h
+++ b/src/network/access/qnetworkaccessauthenticationmanager_p.h
@@ -73,7 +73,7 @@ public:
QString user;
QString password;
bool isNull() {
- return domain.isNull();
+ return domain.isNull() && user.isNull() && password.isNull();
}
};
Q_DECLARE_TYPEINFO(QNetworkAuthenticationCredential, Q_MOVABLE_TYPE);
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 8fc8eb768d..689441eebf 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -61,7 +61,7 @@
#include "QtCore/qbuffer.h"
#include "QtCore/qurl.h"
#include "QtCore/qvector.h"
-#include "QtNetwork/qauthenticator.h"
+#include "QtNetwork/private/qauthenticator_p.h"
#include "QtNetwork/qsslconfiguration.h"
#include "QtNetwork/qnetworkconfigmanager.h"
#include "QtNetwork/qhttpmultipart.h"
@@ -1093,14 +1093,8 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(QNetworkAccessBac
QAuthenticator *authenticator)
{
Q_Q(QNetworkAccessManager);
- // ### FIXME Tracking of successful authentications
- // This code is a bit broken right now for SOCKS authentication
- // first request: proxyAuthenticationRequired gets emitted, credentials gets saved
- // second request: (proxy != backend->reply->lastProxyAuthentication) does not evaluate to true,
- // proxyAuthenticationRequired gets emitted again
- // possible solution: some tracking inside the authenticator
- // or a new function proxyAuthenticationSucceeded(true|false)
- if (proxy != backend->reply->lastProxyAuthentication) {
+ QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*authenticator);
+ if (proxy != backend->reply->lastProxyAuthentication && (!priv || !priv->hasFailed)) {
QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy);
if (!cred.isNull()) {
authenticator->setUser(cred.user);
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 0423e2224d..d0524eec64 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -220,12 +220,6 @@ void QAuthenticator::setUser(const QString &user)
d->userDomain = user.left(separatorPosn);
d->extractedUser = user.mid(separatorPosn + 1);
d->user = user;
- } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) {
- //domain name is present
- d->realm.clear();
- d->userDomain = user.mid(separatorPosn + 1);
- d->extractedUser = user.left(separatorPosn);
- d->user = user;
} else {
d->extractedUser = user;
d->user = user;
@@ -332,6 +326,7 @@ bool QAuthenticator::isNull() const
QAuthenticatorPrivate::QAuthenticatorPrivate()
: ref(0)
, method(None)
+ , hasFailed(false)
, phase(Start)
, nonceCount(0)
{
@@ -393,8 +388,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
switch(method) {
case Basic:
- if(realm.isEmpty())
- this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
+ this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
if (user.isEmpty() && password.isEmpty())
phase = Done;
break;
@@ -402,8 +396,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
// #### extract from header
break;
case DigestMd5: {
- if(realm.isEmpty())
- this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
+ this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
if (options.value("stale").toLower() == "true")
phase = Start;
if (user.isEmpty() && password.isEmpty())
@@ -1381,8 +1374,9 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
int offset = QNtlmPhase3BlockBase::Size;
Q_ASSERT(QNtlmPhase3BlockBase::Size == sizeof(QNtlmPhase3BlockBase));
-
- if(ctx->userDomain.isEmpty()) {
+
+ // for kerberos style user@domain logins, NTLM domain string should be left empty
+ if (ctx->userDomain.isEmpty() && !ctx->extractedUser.contains(QLatin1Char('@'))) {
offset = qEncodeNtlmString(pb.domain, offset, ch.targetNameStr, unicode);
pb.domainStr = ch.targetNameStr;
} else {
diff --git a/src/network/kernel/qauthenticator_p.h b/src/network/kernel/qauthenticator_p.h
index 88a30511b1..937f4e0f04 100644
--- a/src/network/kernel/qauthenticator_p.h
+++ b/src/network/kernel/qauthenticator_p.h
@@ -77,6 +77,7 @@ public:
Method method;
QString realm;
QByteArray challenge;
+ bool hasFailed; //credentials have been tried but rejected by server.
enum Phase {
Start,
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index b62bc05d22..c582c57a7f 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -136,6 +136,8 @@ bool QHttpSocketEngine::connectInternal()
{
Q_D(QHttpSocketEngine);
+ d->credentialsSent = false;
+
// If the handshake is done, enter ConnectedState state and return true.
if (d->state == Connected) {
qWarning("QHttpSocketEngine::connectToHost: called when already connected");
@@ -514,6 +516,7 @@ void QHttpSocketEngine::slotSocketConnected()
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
//qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1);
if (priv && priv->method != QAuthenticatorPrivate::None) {
+ d->credentialsSent = true;
data += "Proxy-Authorization: " + priv->calculateResponse(method, path);
data += "\r\n";
}
@@ -591,15 +594,26 @@ void QHttpSocketEngine::slotSocketReadNotification()
d->readBuffer.clear(); // we parsed the proxy protocol response. from now on direct socket reading will be done
int statusCode = responseHeader.statusCode();
+ QAuthenticatorPrivate *priv = 0;
if (statusCode == 200) {
d->state = Connected;
setLocalAddress(d->socket->localAddress());
setLocalPort(d->socket->localPort());
setState(QAbstractSocket::ConnectedState);
+ d->authenticator.detach();
+ priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
+ priv->hasFailed = false;
} else if (statusCode == 407) {
- if (d->authenticator.isNull())
+ if (d->credentialsSent) {
+ //407 response again means the provided username/password were invalid.
+ d->authenticator = QAuthenticator(); //this is needed otherwise parseHttpResponse won't set the state, and then signal isn't emitted.
+ d->authenticator.detach();
+ priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
+ priv->hasFailed = true;
+ }
+ else if (d->authenticator.isNull())
d->authenticator.detach();
- QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
+ priv = QAuthenticatorPrivate::getPrivate(d->authenticator);
priv->parseHttpResponse(responseHeader, true);
@@ -639,7 +653,6 @@ void QHttpSocketEngine::slotSocketReadNotification()
if (priv->phase == QAuthenticatorPrivate::Done)
emit proxyAuthenticationRequired(d->proxy, &d->authenticator);
-
// priv->phase will get reset to QAuthenticatorPrivate::Start if the authenticator got modified in the signal above.
if (priv->phase == QAuthenticatorPrivate::Done) {
setError(QAbstractSocket::ProxyAuthenticationRequiredError, tr("Authentication required"));
@@ -796,6 +809,7 @@ QHttpSocketEnginePrivate::QHttpSocketEnginePrivate()
, readNotificationPending(false)
, writeNotificationPending(false)
, connectionNotificationPending(false)
+ , credentialsSent(false)
, pendingResponseData(0)
{
socket = 0;
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index d7cc7c1604..476d689c11 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -182,6 +182,7 @@ public:
bool readNotificationPending;
bool writeNotificationPending;
bool connectionNotificationPending;
+ bool credentialsSent;
uint pendingResponseData;
};
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 872b19cc68..900bfdb2e9 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -1044,10 +1044,17 @@ void QSslSocketBackendPrivate::transmit()
int encryptedBytesRead = q_BIO_read(writeBio, data.data(), pendingBytes);
// Write encrypted data from the buffer to the socket.
- plainSocket->write(data.constData(), encryptedBytesRead);
+ qint64 actualWritten = plainSocket->write(data.constData(), encryptedBytesRead);
#ifdef QSSLSOCKET_DEBUG
- qDebug() << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket";
+ qDebug() << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket" << actualWritten << "actual.";
#endif
+ if (actualWritten < 0) {
+ //plain socket write fails if it was in the pending close state.
+ q->setErrorString(plainSocket->errorString());
+ q->setSocketError(plainSocket->error());
+ emit q->error(plainSocket->error());
+ return;
+ }
transmitting = true;
}
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index df09dfdf6d..89153d9398 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -106,6 +106,10 @@ class QMacWindowChangeEvent;
class QWSGLWindowSurface;
#endif
+#ifdef Q_OS_SYMBIAN
+extern bool qt_initializing_gl_share_widget();
+#endif
+
#ifndef QT_NO_EGL
class QEglContext;
#endif
@@ -183,6 +187,10 @@ public:
#endif
{
isGLWidget = 1;
+#if defined(Q_OS_SYMBIAN)
+ if (qt_initializing_gl_share_widget())
+ isGLGlobalShareWidget = 1;
+#endif
}
~QGLWidgetPrivate() {}
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index a15084b0c9..d512946c01 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -184,28 +184,29 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
class QGLGlobalShareWidget
{
public:
- QGLGlobalShareWidget() : widget(0), initializing(false) {
+ QGLGlobalShareWidget() : widget(0), init(false) {
created = true;
}
QGLWidget *shareWidget() {
- if (!initializing && !widget && !cleanedUp) {
- initializing = true;
+ if (!init && !widget && !cleanedUp) {
+ init = true;
widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer));
#ifdef Q_OS_SYMBIAN
if (!widget->context()->isValid()) {
delete widget;
widget = 0;
- initializing = false;
+ init = false;
return 0;
}
#endif
+
widget->resize(1, 1);
// We don't need this internal widget to appear in QApplication::topLevelWidgets()
if (QWidgetPrivate::allWidgets)
QWidgetPrivate::allWidgets->remove(widget);
- initializing = false;
+ init = false;
}
return widget;
}
@@ -232,12 +233,17 @@ public:
cleanedUp = false;
}
+ bool initializing()
+ {
+ return init;
+ }
+
static bool cleanedUp;
static bool created;
private:
QGLWidget *widget;
- bool initializing;
+ bool init;
};
bool QGLGlobalShareWidget::cleanedUp = false;
@@ -268,6 +274,13 @@ void qt_destroy_gl_share_widget()
_qt_gl_share_widget()->destroy();
}
+bool qt_initializing_gl_share_widget()
+{
+ if (QGLGlobalShareWidget::created)
+ return _qt_gl_share_widget()->initializing();
+ return false;
+}
+
const QGLContext *qt_gl_share_context()
{
QGLWidget *widget = qt_gl_share_widget();
diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h
index 91d1f9e245..6c8b71fe6b 100644
--- a/src/opengl/qwindowsurface_gl_p.h
+++ b/src/opengl/qwindowsurface_gl_p.h
@@ -68,6 +68,7 @@ struct QGLWindowSurfacePrivate;
Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget();
Q_OPENGL_EXPORT void qt_destroy_gl_share_widget();
+bool qt_initializing_gl_share_widget();
class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice
{
diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
index aa4c014d99..cb6b2f6605 100644
--- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
+++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp
@@ -52,7 +52,7 @@
#endif
QT_BEGIN_NAMESPACE
-extern int qt_defaultDpi();
+extern Q_GUI_EXPORT int qt_defaultDpi();
QT_END_NAMESPACE
class tst_qdeclarativevaluetypes : public QObject
diff --git a/tests/auto/qcssparser/qcssparser.pro b/tests/auto/qcssparser/qcssparser.pro
index fc3daa3af6..0600860ce6 100644
--- a/tests/auto/qcssparser/qcssparser.pro
+++ b/tests/auto/qcssparser/qcssparser.pro
@@ -10,8 +10,11 @@ requires(contains(QT_CONFIG,private_tests))
wince*|symbian: {
addFiles.files = testdata
addFiles.path = .
+ DEPLOYMENT += addFiles
+}
+wince* {
timesFont.files = c:/windows/fonts/times.ttf
timesFont.path = .
- DEPLOYMENT += addFiles timesFont
+ DEPLOYMENT += timesFont
}
diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp
index 9c51e026d2..27c8ced106 100644
--- a/tests/auto/qgl/tst_qgl.cpp
+++ b/tests/auto/qgl/tst_qgl.cpp
@@ -648,7 +648,7 @@ void tst_QGL::getSetCheck()
#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
-extern QGLFormat::OpenGLVersionFlags qOpenGLVersionFlagsFromString(const QString &versionString);
+extern Q_AUTOTEST_EXPORT QGLFormat::OpenGLVersionFlags qOpenGLVersionFlagsFromString(const QString &versionString);
QT_END_NAMESPACE
#endif
diff --git a/tests/auto/qlayout/tst_qlayout.cpp b/tests/auto/qlayout/tst_qlayout.cpp
index 96f88634bc..be3998f911 100644
--- a/tests/auto/qlayout/tst_qlayout.cpp
+++ b/tests/auto/qlayout/tst_qlayout.cpp
@@ -60,6 +60,10 @@
# include <QtGui/QMacStyle>
#endif
+#if defined(Q_OS_SYMBIAN)
+# define SRCDIR "."
+#endif
+
//TESTED_CLASS=
//TESTED_FILES=
diff --git a/tests/auto/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/qmdisubwindow/tst_qmdisubwindow.cpp
index 7296f3433b..148f35516e 100644
--- a/tests/auto/qmdisubwindow/tst_qmdisubwindow.cpp
+++ b/tests/auto/qmdisubwindow/tst_qmdisubwindow.cpp
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
extern void qt_x11_wait_for_window_manager(QWidget *w);
#endif
#if !defined(Q_WS_WIN)
-extern bool qt_tab_all_widgets;
+extern Q_GUI_EXPORT bool qt_tab_all_widgets;
#endif
QT_END_NAMESPACE
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
index 371ac5785e..6760b73ef7 100644
--- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp
@@ -380,6 +380,9 @@ private Q_SLOTS:
void httpAbort();
void dontInsertPartialContentIntoTheCache();
+ void authenticationCacheAfterCancel_data();
+ void authenticationCacheAfterCancel();
+ void authenticationWithDifferentRealm();
void synchronousAuthenticationCache();
void pipelining();
@@ -6026,6 +6029,221 @@ void tst_QNetworkReply::qtbug4121unknownAuthentication()
QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError);
}
+void tst_QNetworkReply::authenticationCacheAfterCancel_data()
+{
+ QTest::addColumn<QNetworkProxy>("proxy");
+ QTest::addColumn<bool>("proxyAuth");
+ QTest::addColumn<QUrl>("url");
+ for (int i = 0; i < proxies.count(); ++i) {
+ QTest::newRow("http" + proxies.at(i).tag) << proxies.at(i).proxy << proxies.at(i).requiresAuthentication << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt");
+#ifndef QT_NO_OPENSSL
+ QTest::newRow("https" + proxies.at(i).tag) << proxies.at(i).proxy << proxies.at(i).requiresAuthentication << QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt");
+#endif
+ }
+}
+
+class AuthenticationCacheHelper : public QObject
+{
+ Q_OBJECT
+public:
+ AuthenticationCacheHelper()
+ {}
+public slots:
+ void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
+ {
+ if (!proxyPassword.isNull()) {
+ auth->setUser(proxyUserName);
+ auth->setPassword(proxyPassword);
+ //clear credentials, if they are asked again, they were bad
+ proxyUserName.clear();
+ proxyPassword.clear();
+ }
+ }
+ void authenticationRequired(QNetworkReply*,QAuthenticator *auth)
+ {
+ if (!httpPassword.isNull()) {
+ auth->setUser(httpUserName);
+ auth->setPassword(httpPassword);
+ //clear credentials, if they are asked again, they were bad
+ httpUserName.clear();
+ httpPassword.clear();
+ }
+ }
+public:
+ QString httpUserName;
+ QString httpPassword;
+ QString proxyUserName;
+ QString proxyPassword;
+};
+
+/* Purpose of this test is to check credentials are cached correctly.
+ - If user cancels authentication dialog (i.e. nothing is set to the QAuthenticator by the callback) then this is not cached
+ - if user supplies a wrong password, then this is not cached
+ - if user supplies a correct user/password combination then this is cached
+
+ Test is checking both the proxyAuthenticationRequired and authenticationRequired signals.
+ */
+void tst_QNetworkReply::authenticationCacheAfterCancel()
+{
+ QFETCH(QNetworkProxy, proxy);
+ QFETCH(bool, proxyAuth);
+ QFETCH(QUrl, url);
+ QNetworkAccessManager manager;
+#ifndef QT_NO_OPENSSL
+ connect(&manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
+ SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
+#endif
+ manager.setProxy(proxy);
+ QSignalSpy authSpy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)));
+ QSignalSpy proxyAuthSpy(&manager, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)));
+
+ AuthenticationCacheHelper helper;
+ connect(&manager, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)), &helper, SLOT(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)));
+ connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), &helper, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*)));
+
+ QNetworkRequest request(url);
+ QNetworkReplyPtr reply;
+ if (proxyAuth) {
+ //should fail due to no credentials
+ reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(reply->error(), QNetworkReply::ProxyAuthenticationRequiredError);
+ QCOMPARE(authSpy.count(), 0);
+ QCOMPARE(proxyAuthSpy.count(), 1);
+ proxyAuthSpy.clear();
+
+ //should fail due to bad credentials
+ helper.proxyUserName = "qsockstest";
+ helper.proxyPassword = "badpassword";
+ reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QEXPECT_FAIL("http+socksauth", "QTBUG-23136 - danted accepts bad authentication but blocks the connection", Continue);
+ QEXPECT_FAIL("https+socksauth", "QTBUG-23136 - danted accepts bad authentication but blocks the connection", Continue);
+
+ QCOMPARE(reply->error(), QNetworkReply::ProxyAuthenticationRequiredError);
+ QCOMPARE(authSpy.count(), 0);
+ QVERIFY(proxyAuthSpy.count() > 0);
+ proxyAuthSpy.clear();
+
+ //QTBUG-23136 workaround
+ if (proxy.port() == 1081) {
+#ifdef QT_BUILD_INTERNAL
+ QNetworkAccessManagerPrivate::clearCache(&manager);
+#else
+ return; //XFAIL result above
+#endif
+ }
+
+ //next proxy auth should succeed, due to correct credentials
+ helper.proxyUserName = "qsockstest";
+ helper.proxyPassword = "password";
+ }
+
+ //should fail due to no credentials
+ reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError);
+ QVERIFY(authSpy.count() > 0);
+ authSpy.clear();
+ if (proxyAuth) {
+ QVERIFY(proxyAuthSpy.count() > 0);
+ proxyAuthSpy.clear();
+ }
+
+ //should fail due to bad credentials
+ helper.httpUserName = "baduser";
+ helper.httpPassword = "badpassword";
+ reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError);
+ QVERIFY(authSpy.count() > 0);
+ authSpy.clear();
+ if (proxyAuth) {
+ //should be supplied from cache
+ QCOMPARE(proxyAuthSpy.count(), 0);
+ proxyAuthSpy.clear();
+ }
+
+ //next auth should succeed, due to correct credentials
+ helper.httpUserName = "httptest";
+ helper.httpPassword = "httptest";
+
+ reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+ QVERIFY(authSpy.count() > 0);
+ authSpy.clear();
+ if (proxyAuth) {
+ //should be supplied from cache
+ QCOMPARE(proxyAuthSpy.count(), 0);
+ proxyAuthSpy.clear();
+ }
+
+ //next auth should use cached credentials
+ reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+ //should be supplied from cache
+ QCOMPARE(authSpy.count(), 0);
+ authSpy.clear();
+ if (proxyAuth) {
+ //should be supplied from cache
+ QCOMPARE(proxyAuthSpy.count(), 0);
+ proxyAuthSpy.clear();
+ }
+
+}
+
+void tst_QNetworkReply::authenticationWithDifferentRealm()
+{
+ AuthenticationCacheHelper helper;
+ QNetworkAccessManager manager;
+#ifndef QT_NO_OPENSSL
+ connect(&manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
+ SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
+#endif
+ connect(&manager, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)), &helper, SLOT(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)));
+ connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), &helper, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*)));
+
+ helper.httpUserName = "httptest";
+ helper.httpPassword = "httptest";
+
+ QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt"));
+ QNetworkReply* reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+
+ helper.httpUserName = "httptest";
+ helper.httpPassword = "httptest";
+
+ request.setUrl(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/auth-digest/"));
+ reply = manager.get(request);
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection);
+ QTestEventLoop::instance().enterLoop(10);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+}
+
class QtBug13431Helper : public QObject {
Q_OBJECT
public:
diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp
index b36cf9891a..b5d8887f14 100644
--- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp
+++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp
@@ -499,7 +499,7 @@ void tst_QPixmapCache::pixmapKey()
}
QT_BEGIN_NAMESPACE
-extern int q_QPixmapCache_keyHashSize();
+extern Q_AUTOTEST_EXPORT int q_QPixmapCache_keyHashSize();
QT_END_NAMESPACE
void tst_QPixmapCache::noLeak()
diff --git a/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp b/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp
index 5634285ad4..7b7784c78c 100644
--- a/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp
+++ b/tests/auto/qpixmapfilter/tst_qpixmapfilter.cpp
@@ -425,7 +425,7 @@ void tst_QPixmapFilter::dropShadowBoundingRectFor()
}
QT_BEGIN_NAMESPACE
-void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);
+Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);
QT_END_NAMESPACE
void tst_QPixmapFilter::blurIndexed8()
diff --git a/tests/auto/qregion/tst_qregion.cpp b/tests/auto/qregion/tst_qregion.cpp
index bbc09c9b57..f06d848477 100644
--- a/tests/auto/qregion/tst_qregion.cpp
+++ b/tests/auto/qregion/tst_qregion.cpp
@@ -977,7 +977,7 @@ void tst_QRegion::regionToPath_data()
#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
-extern QPainterPath qt_regionToPath(const QRegion &region);
+extern Q_AUTOTEST_EXPORT QPainterPath qt_regionToPath(const QRegion &region);
QT_END_NAMESPACE
#endif
diff --git a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
index 14c204e6af..435b5e2f6e 100644
--- a/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
+++ b/tests/auto/qscriptcontext/tst_qscriptcontext.cpp
@@ -53,7 +53,7 @@ Q_DECLARE_METATYPE(QScriptValueList)
Q_DECLARE_METATYPE(QScriptContext::Error)
QT_BEGIN_NAMESPACE
-extern bool qt_script_isJITEnabled();
+extern Q_AUTOTEST_EXPORT bool qt_script_isJITEnabled();
QT_END_NAMESPACE
class tst_QScriptContext : public QObject
diff --git a/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro b/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro
index e184ca4ee5..e1701e3f01 100644
--- a/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro
+++ b/tests/auto/qscriptextensionplugin/simpleplugin/simpleplugin.pro
@@ -7,4 +7,5 @@ DESTDIR = ../plugins/script
symbian {
TARGET.EPOCALLOWDLLDATA=1
+ TARGET = qscriptextension_simpleplugin # Too generic target causes conflict on Symbian
}
diff --git a/tests/auto/qscriptextensionplugin/test/test.pro b/tests/auto/qscriptextensionplugin/test/test.pro
index 549bac266c..223dafa356 100644
--- a/tests/auto/qscriptextensionplugin/test/test.pro
+++ b/tests/auto/qscriptextensionplugin/test/test.pro
@@ -3,7 +3,14 @@ load(qttest_p4)
QT = core script
SOURCES = ../tst_qscriptextensionplugin.cpp
CONFIG -= app_bundle
-LIBS += -L../plugins/script -lstaticplugin
+symbian {
+ LIBS += -lstaticplugin.lib
+ simplePlugin.files = qscriptextension_simpleplugin.dll
+ simplePlugin.path = plugins/script
+ DEPLOYMENT += simplePlugin
+} else {
+ LIBS += -L../plugins/script -lstaticplugin
+}
TARGET = tst_qscriptextensionplugin
CONFIG(debug_and_release) {
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index e350d1e749..fc14dbcf60 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -666,7 +666,7 @@ void tst_QSvgRenderer::testGzLoading()
#ifdef QT_BUILD_INTERNAL
QT_BEGIN_NAMESPACE
-QByteArray qt_inflateGZipDataFrom(QIODevice *device);
+Q_AUTOTEST_EXPORT QByteArray qt_inflateGZipDataFrom(QIODevice *device);
QT_END_NAMESPACE
#endif
diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp
index 73d09f4371..186623b91e 100644
--- a/tests/auto/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/qtextedit/tst_qtextedit.cpp
@@ -1968,7 +1968,7 @@ void tst_QTextEdit::setText()
}
QT_BEGIN_NAMESPACE
-extern void qt_setQtEnableTestFont(bool value);
+extern Q_AUTOTEST_EXPORT void qt_setQtEnableTestFont(bool value);
QT_END_NAMESPACE
void tst_QTextEdit::fullWidthSelection_data()
diff --git a/tests/auto/qtextlayout/tst_qtextlayout.cpp b/tests/auto/qtextlayout/tst_qtextlayout.cpp
index 67d8269d79..68f93e1037 100644
--- a/tests/auto/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/qtextlayout/tst_qtextlayout.cpp
@@ -174,7 +174,7 @@ void tst_QTextLayout::getSetCheck()
}
QT_BEGIN_NAMESPACE
-extern void qt_setQtEnableTestFont(bool value);
+extern Q_AUTOTEST_EXPORT void qt_setQtEnableTestFont(bool value);
QT_END_NAMESPACE
tst_QTextLayout::tst_QTextLayout()
@@ -1109,7 +1109,7 @@ void tst_QTextLayout::tabsForRtl()
}
QT_BEGIN_NAMESPACE
-extern int qt_defaultDpiY();
+extern Q_GUI_EXPORT int qt_defaultDpiY();
QT_END_NAMESPACE
void tst_QTextLayout::testTabDPIScale()