diff options
50 files changed, 675 insertions, 212 deletions
@@ -4592,12 +4592,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; #mkspecs/default is used as a (gasp!) default mkspec so QMAKESPEC needn't be set once configured rm -rf mkspecs/default - if [ "$XPLATFORM_SYMBIAN_SBSV2" = "yes" ]; then -#Link is not supported for Symbian build system - cp -a mkspecs/`echo $XQMAKESPEC | sed "s,^${relpath}/mkspecs/,,"` mkspecs/default - else - ln -s `echo $XQMAKESPEC | sed "s,^${relpath}/mkspecs/,,"` mkspecs/default - fi + ln -s `echo $XQMAKESPEC | sed "s,^${relpath}/mkspecs/,,"` mkspecs/default # fix makefiles for mkfile in GNUmakefile Makefile; do EXTRA_LFLAGS= @@ -7897,12 +7892,7 @@ else mv "$outpath/src/corelib/global/qconfig.h.new" "$outpath/src/corelib/global/qconfig.h" chmod -w "$outpath/src/corelib/global/qconfig.h" for conf in "$outpath/include/QtCore/qconfig.h" "$outpath/include/Qt/qconfig.h"; do - if [ "$XPLATFORM_SYMBIAN_SBSV2" = "yes" ]; then - [ -e "$conf" ] && rm -rf "$conf" - cp -a "$outpath/src/corelib/global/qconfig.h" "$conf" - elif [ '!' -f "$conf" ]; then - ln -s "$outpath/src/corelib/global/qconfig.h" "$conf" - fi + ln -s "$outpath/src/corelib/global/qconfig.h" "$conf" done fi #------------------------------------------------------------------------------- diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index eab9644..117f332 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -162,28 +162,35 @@ exists($${EPOCROOT}epoc32/tools/qt/mkspecs/features/environment.prf) { } # Try to detect SDK version if it wasn't set by environment.prf -isEmpty(SYMBIAN_VERSION) { - exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/Symbianv4.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/Symbianv4.sis) { - SYMBIAN_VERSION = Symbian4 +isEmpty(SYMBIAN_VERSION)|isEmpty(S60_VERSION) { + exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v5.3.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/series60v5.3.sis) { + isEmpty(SYMBIAN_VERSION): SYMBIAN_VERSION = Symbian3 + isEmpty(S60_VERSION): S60_VERSION = 5.3 } else { # The Symbian^3 PDK does not necessarily contain the required sis files. # However, libstdcppv5 first appeared in Symbian^3 (S60 5.2), so check for that too. exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v5.2.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/series60v5.2.sis)|exists($${EPOCROOT}epoc32/release/armv5/lib/libstdcppv5.dso) { - SYMBIAN_VERSION = Symbian3 + isEmpty(SYMBIAN_VERSION): SYMBIAN_VERSION = Symbian3 + isEmpty(S60_VERSION): S60_VERSION = 5.2 } else { exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v5.1.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/series60v5.1.sis) { - SYMBIAN_VERSION = Symbian2 + isEmpty(SYMBIAN_VERSION): SYMBIAN_VERSION = Symbian2 + isEmpty(S60_VERSION): S60_VERSION = 5.1 } else { exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v5.0.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/series60v5.0.sis) { - SYMBIAN_VERSION = 9.4 + isEmpty(SYMBIAN_VERSION): SYMBIAN_VERSION = 9.4 + isEmpty(S60_VERSION): S60_VERSION = 5.0 } else { exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v3.2.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/series60v3.2.sis) { - SYMBIAN_VERSION = 9.3 + isEmpty(SYMBIAN_VERSION): SYMBIAN_VERSION = 9.3 + isEmpty(S60_VERSION): S60_VERSION = 3.2 } else { exists($${EPOCROOT}epoc32/release/winscw/udeb/z/system/install/series60v3.1.sis)|exists($${EPOCROOT}epoc32/data/z/system/install/series60v3.1.sis) { - SYMBIAN_VERSION = 9.2 + isEmpty(SYMBIAN_VERSION): SYMBIAN_VERSION = 9.2 + isEmpty(S60_VERSION): S60_VERSION = 3.1 } else { - SYMBIAN_VERSION = Unknown + isEmpty(SYMBIAN_VERSION): SYMBIAN_VERSION = Unknown + isEmpty(S60_VERSION): S60_VERSION = Unknown } } } @@ -192,22 +199,6 @@ isEmpty(SYMBIAN_VERSION) { } } -isEmpty(S60_VERSION) { - contains(SYMBIAN_VERSION, "9\\.2") { - S60_VERSION = 3.1 - } else:contains(SYMBIAN_VERSION, "9\\.3") { - S60_VERSION = 3.2 - } else:contains(SYMBIAN_VERSION, "9\\.4") { - S60_VERSION = 5.0 - } else:contains(SYMBIAN_VERSION, "Symbian2") { - S60_VERSION = 5.1 - } else:contains(SYMBIAN_VERSION, "Symbian3") { - S60_VERSION = 5.2 - } else { - S60_VERSION = Unknown - } -} - # pkg_depends_webkit, pkg_depends_core, and pkg_platform_dependencies can be removed by developer # if multiple languages need to be supported by pkg file. In that case the developer should declare # multiple language compatible dependency statements him/herself. diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index a05ff25..ce3453a 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -85,13 +85,13 @@ contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0 isEmpty(TARGET.EPOCSTACKSIZE):TARGET.EPOCSTACKSIZE = 0x14000 isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x020000 0x800000 -# Supports Symbian^3 and Symbian^4 by default and also S60 3.1, 3.2, and 5.0 if built against any of those. +# Supports Symbian^3 platforms by default and also S60 3.1, 3.2, and 5.0 if built against any of those. platform_product_id = S60ProductID platform_product_id = $$addLanguageDependentPkgItem(platform_product_id) pkg_platform_dependencies = \ "; Default HW/platform dependencies" \ "[0x20022E6D],0,0,0,{$$platform_product_id}" \ - "[0x20032DE7],0,0,0,{$$platform_product_id}" + "[0x2003A678],0,0,0,{$$platform_product_id}" contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { pkg_platform_dependencies += \ "[0x102032BE],0,0,0,{$$platform_product_id}" \ diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 65de6e0..8ff423e 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -26,6 +26,9 @@ linux*:!static:!symbian-armcc:!symbian-gcce { } # Compensate for lack of platform defines in Symbian3 and Symbian4 -symbian: DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_)) +symbian { + DEFINES += SYMBIAN_VERSION_$$upper($$replace(SYMBIAN_VERSION,\\.,_)) \ + S60_VERSION_$$upper($$replace(S60_VERSION,\\.,_)) +} include(../../../tools/shared/symbian/epocroot.pri) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 25ddd24..35719b1 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -86,7 +86,6 @@ # include "private/qcore_symbian_p.h" _LIT(qt_S60Filter, "Series60v?.*.sis"); -_LIT(qt_symbianFilter, "Symbianv*.sis"); _LIT(qt_symbianSystemInstallDir, "z:\\system\\install\\"); #endif @@ -1201,7 +1200,7 @@ bool qSharedBuild() \value SV_SF_1 Symbian^1 \value SV_SF_2 Symbian^2 \value SV_SF_3 Symbian^3 - \value SV_SF_4 Symbian^4 + \value SV_SF_4 \e{This enum value is deprecated.} \value SV_Unknown An unknown and currently unsupported platform \sa S60Version, WinVersion, MacVersion @@ -1219,7 +1218,8 @@ bool qSharedBuild() \value SV_S60_3_2 S60 3rd Edition Feature Pack 2 \value SV_S60_5_0 S60 5th Edition \value SV_S60_5_1 S60 5th Edition Feature Pack 1 - \value SV_S60_5_2 S60 5th Edition Feature Pack 2 + \value SV_S60_5_2 Symbian^3 + \value SV_S60_5_3 To be determined - FIXME \value SV_S60_Unknown An unknown and currently unsupported platform \omitvalue SV_S60_None @@ -1815,12 +1815,10 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion() #ifdef Q_OS_SYMBIAN static QSysInfo::SymbianVersion cachedSymbianVersion = QSysInfo::SymbianVersion(-1); +static QSysInfo::S60Version cachedS60Version = QSysInfo::S60Version(-1); -QSysInfo::SymbianVersion QSysInfo::symbianVersion() +static void symbianInitVersions() { - if (cachedSymbianVersion != -1) - return cachedSymbianVersion; - // Use pure Symbian code, because if done using QDir, there will be a call back // to this method, resulting doing this expensive operation twice before the cache kicks in. // Pure Symbian code also makes this method ~10x faster, speeding up the application launch. @@ -1828,21 +1826,8 @@ QSysInfo::SymbianVersion QSysInfo::symbianVersion() TFindFile fileFinder(rfs); CDir* contents; - // Check for Symbian4 - TInt err = fileFinder.FindWildByDir(qt_symbianFilter, qt_symbianSystemInstallDir, contents); - if (err == KErrNone) { - QScopedPointer<CDir> contentsDeleter(contents); - err = contents->Sort(EDescending|ESortByName); - if (err == KErrNone && contents->Count() > 0 && (*contents)[0].iName.Length() >= 9) { - TInt major = (*contents)[0].iName[8] - '0'; - if (major == 4) { - return cachedSymbianVersion = SV_SF_4; - } - } - } - - // Check for S60 and Symbian3 platforms, which use older .sis naming scheme - err = fileFinder.FindWildByDir(qt_S60Filter, qt_symbianSystemInstallDir, contents); + // Check for platform version + TInt err = fileFinder.FindWildByDir(qt_S60Filter, qt_symbianSystemInstallDir, contents); if (err == KErrNone) { QScopedPointer<CDir> contentsDeleter(contents); err = contents->Sort(EDescending|ESortByName); @@ -1851,61 +1836,76 @@ QSysInfo::SymbianVersion QSysInfo::symbianVersion() TInt minor = (*contents)[0].iName[11] - '0'; if (major == 3) { if (minor == 1) { - return cachedSymbianVersion = SV_9_2; + cachedS60Version = QSysInfo::SV_S60_3_1; + cachedSymbianVersion = QSysInfo::SV_9_2; } else if (minor == 2) { - return cachedSymbianVersion = SV_9_3; + cachedS60Version = QSysInfo::SV_S60_3_2; + cachedSymbianVersion = QSysInfo::SV_9_3; } } else if (major == 5) { if (minor == 0) { - return cachedSymbianVersion = SV_9_4; - } - else if (minor == 1) { - return cachedSymbianVersion = SV_SF_2; - } - else if (minor >= 2) { - return cachedSymbianVersion = SV_SF_3; + cachedS60Version = QSysInfo::SV_S60_5_0; + cachedSymbianVersion = QSysInfo::SV_9_4; + } else if (minor == 1) { + cachedS60Version = QSysInfo::SV_S60_5_1; + cachedSymbianVersion = QSysInfo::SV_SF_2; + } else if (minor == 2) { + cachedS60Version = QSysInfo::SV_S60_5_2; + cachedSymbianVersion = QSysInfo::SV_SF_3; + } else if (minor >= 3) { + cachedS60Version = QSysInfo::SV_S60_5_3; + cachedSymbianVersion = QSysInfo::SV_SF_3; } } } } # ifdef Q_CC_NOKIAX86 - // Some emulator environments may not contain the version specific .sis files, so - // simply hardcode the version on those environments. Note that can't use - // SYMBIAN_VERSION_* defines for S60 3.x/5.0 platforms, as they do not define them - // right anyway in case .sis files are not found. + if (cachedS60Version == -1) { + // Some emulator environments may not contain the version specific .sis files, so + // simply hardcode the version on those environments. Note that can't use + // S60_VERSION_* defines for S60 3.x/5.0 platforms, as they do not define them + // right anyway in case .sis files are not found. # if defined(__SERIES60_31__) - return cachedSymbianVersion = SV_9_2; + cachedS60Version = QSysInfo::SV_S60_3_1; + cachedSymbianVersion = QSysInfo::SV_9_2; # elif defined(__S60_32__) - return cachedSymbianVersion = SV_9_3; + cachedS60Version = QSysInfo::SV_S60_3_2; + cachedSymbianVersion = QSysInfo::SV_9_3; # elif defined(__S60_50__) - return cachedSymbianVersion = SV_9_4; -# elif defined(SYMBIAN_VERSION_SYMBIAN3) - return cachedSymbianVersion = SV_SF_3; -# elif defined(SYMBIAN_VERSION_SYMBIAN4) - return cachedSymbianVersion = SV_SF_4; + cachedS60Version = QSysInfo::SV_S60_5_0; + cachedSymbianVersion = QSysInfo::SV_9_4; +# elif defined(S60_VERSION_5_2) + cachedS60Version = QSysInfo::SV_S60_5_2; + cachedSymbianVersion = QSysInfo::SV_SF_3; +# elif defined(S60_VERSION_5_3) + cachedS60Version = QSysInfo::SV_S60_5_3; + cachedSymbianVersion = QSysInfo::SV_SF_3; # endif + } # endif - //If reaching here, it was not possible to determine the version - return cachedSymbianVersion = SV_Unknown; + + if (cachedS60Version == -1) { + //If reaching here, it was not possible to determine the version + cachedS60Version = QSysInfo::SV_S60_Unknown; + cachedSymbianVersion = QSysInfo::SV_Unknown; + } +} + +QSysInfo::SymbianVersion QSysInfo::symbianVersion() +{ + if (cachedSymbianVersion == -1) + symbianInitVersions(); + + return cachedSymbianVersion; } QSysInfo::S60Version QSysInfo::s60Version() { - switch (symbianVersion()) { - case SV_9_2: - return SV_S60_3_1; - case SV_9_3: - return SV_S60_3_2; - case SV_9_4: - return SV_S60_5_0; - case SV_SF_2: - return SV_S60_5_1; - case SV_SF_3: - return SV_S60_5_2; - default: - return SV_S60_Unknown; - } + if (cachedS60Version == -1) + symbianInitVersions(); + + return cachedS60Version; } #endif // ifdef Q_OS_SYMBIAN diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 55c96c6..7768b46 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1524,7 +1524,7 @@ public: SV_SF_1 = SV_9_4, SV_SF_2 = 40, SV_SF_3 = 50, - SV_SF_4 = 60 + SV_SF_4 = 60 // Deprecated }; static SymbianVersion symbianVersion(); enum S60Version { @@ -1533,9 +1533,9 @@ public: SV_S60_3_1 = SV_9_2, SV_S60_3_2 = SV_9_3, SV_S60_5_0 = SV_9_4, - //versions beyond 5.0 are to be confirmed - it is better to use symbian version SV_S60_5_1 = SV_SF_2, - SV_S60_5_2 = SV_SF_3 + SV_S60_5_2 = SV_SF_3, + SV_S60_5_3 = 70 }; static S60Version s60Version(); #endif @@ -2459,6 +2459,10 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); #define Q_SYMBIAN_SUPPORTS_MULTIPLE_SCREENS #endif +#ifdef SYMBIAN_GRAPHICS_FIXNATIVEORIENTATION +#define Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION +#endif + //Symbian does not support data imports from a DLL #define Q_NO_DATA_RELOCATION diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 41abe95..2c70ade 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -416,7 +416,8 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget) int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1)); if (index != -1) disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget())); - QGraphicsItem *rootItem; + + QGraphicsItem *rootItem = 0; foreach (QGraphicsItem *item, gv->scene()->items()) { if (!item->parentItem()) { rootItem = item; @@ -828,7 +829,7 @@ void QCoeFepInputContext::translateInputWidget() return; // Fetch root item (i.e. graphicsitem with no parent) - QGraphicsItem *rootItem; + QGraphicsItem *rootItem = 0; foreach (QGraphicsItem *item, gv->scene()->items()) { if (!item->parentItem()) { rootItem = item; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 2b10d63..0427ae4 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1271,15 +1271,36 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) qwidget->d_func()->setWindowIcon_sys(true); qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 - // If widget is fullscreen/minimized, hide status pane and button container otherwise show them. - QWidget *const window = qwidget->window(); - if (!window->parentWidget()) { // Only top level native windows have control over cba/status pane - const bool decorationsVisible = !(window->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); - const bool statusPaneVisibility = decorationsVisible; - const bool isFullscreen = window->windowState() & Qt::WindowFullScreen; - const bool cbaVisibilityHint = window->windowFlags() & Qt::WindowSoftkeysVisibleHint; - const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaVisibilityHint)); - S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); + if (qwidget->isWindow()) { + QWidget *const window = qwidget->window(); + QWidget *parentWindow = window->parentWidget(); + if (parentWindow) { + while (parentWindow->parentWidget()) + parentWindow = parentWindow->parentWidget(); + } else { + parentWindow = window; + } + + const bool parentDecorationsVisible = !(parentWindow->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool parentIsFullscreen = parentWindow->windowState() & Qt::WindowFullScreen; + const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint; + bool buttonGroupVisibility = (parentDecorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint)); + + // For non-toplevel normal and maximized windows, show cba if window has softkey + // actions even if topmost parent is not showing cba. Do the same for fullscreen + // windows that request it. + if (!buttonGroupVisibility + && window->parentWidget() + && !(window->windowState() & Qt::WindowMinimized) + && ((window->windowFlags() & Qt::WindowSoftkeysVisibleHint) || !(window->windowState() & Qt::WindowFullScreen))) { + for (int i = 0; i < window->actions().size(); ++i) { + if (window->actions().at(i)->softKeyRole() != QAction::NoSoftKey) { + buttonGroupVisibility = true; + break; + } + } + } + S60->setStatusPaneAndButtonGroupVisibility(parentDecorationsVisible, buttonGroupVisibility); } #endif } else if (QApplication::activeWindow() == qwidget->window()) { @@ -1455,6 +1476,35 @@ bool QSymbianControl::isControlActive() return IsActivated() ? true : false; } +void QSymbianControl::ensureFixNativeOrientation() +{ +#if defined(Q_SYMBIAN_SUPPORTS_FIXNATIVEORIENTATION) + // Call FixNativeOrientation() for fullscreen QDeclarativeViews that + // have a locked orientation matching the native orientation of the device. + // This avoids unnecessary window rotation on wserv level. + if (!qwidget->isWindow() || qwidget->windowType() == Qt::Desktop + || !qwidget->inherits("QDeclarativeView") + || S60->screenNumberForWidget(qwidget) > 0) + return; + const bool isFullScreen = qwidget->windowState().testFlag(Qt::WindowFullScreen); + const bool isFixed = qwidget->d_func()->fixNativeOrientationCalled; + const bool matchesNative = qwidget->testAttribute( + S60->nativeOrientationIsPortrait ? Qt::WA_LockPortraitOrientation + : Qt::WA_LockLandscapeOrientation); + if (isFullScreen && matchesNative) { + if (!isFixed) { + Window().FixNativeOrientation(); + qwidget->d_func()->fixNativeOrientationCalled = true; + } + } else if (isFixed) { + qwidget->d_func()->fixNativeOrientationCalled = false; + qwidget->hide(); + qwidget->d_func()->create_sys(0, false, true); + qwidget->show(); + } +#endif +} + /*! \typedef QApplication::QS60MainApplicationFactory \since 4.6 diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 3bb27c3..102c0ca 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -189,6 +189,8 @@ public: int screenHeightInPixelsForScreen[qt_symbian_max_screens]; int screenWidthInTwipsForScreen[qt_symbian_max_screens]; int screenHeightInTwipsForScreen[qt_symbian_max_screens]; + + bool nativeOrientationIsPortrait; }; Q_AUTOTEST_EXPORT QS60Data* qGlobalS60Data(); @@ -233,6 +235,8 @@ public: bool isControlActive(); + void ensureFixNativeOrientation(); + #ifdef Q_WS_S60 void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); } void HandleStatusPaneSizeChange(); @@ -327,9 +331,11 @@ inline QS60Data::QS60Data() inline void QS60Data::updateScreenSize() { + CWsScreenDevice *dev = S60->screenDevice(); + int screenModeCount = dev->NumScreenModes(); + int mode = dev->CurrentScreenMode(); TPixelsTwipsAndRotation params; - int mode = S60->screenDevice()->CurrentScreenMode(); - S60->screenDevice()->GetScreenModeSizeAndRotation(mode, params); + dev->GetScreenModeSizeAndRotation(mode, params); S60->screenWidthInPixels = params.iPixelSize.iWidth; S60->screenHeightInPixels = params.iPixelSize.iHeight; S60->screenWidthInTwips = params.iTwipsSize.iWidth; @@ -352,6 +358,21 @@ inline void QS60Data::updateScreenSize() S60->screenWidthInTwipsForScreen[i] = params.iTwipsSize.iWidth; S60->screenHeightInTwipsForScreen[i] = params.iTwipsSize.iHeight; } + + // Look for a screen mode with rotation 0 + // in order to decide what the native orientation is. + int nativeScreenWidthInPixels = 0; + int nativeScreenHeightInPixels = 0; + for (mode = 0; mode < screenModeCount; ++mode) { + TPixelsAndRotation sizeAndRotation; + dev->GetScreenModeSizeAndRotation(mode, sizeAndRotation); + if (sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationNormal) { + nativeScreenWidthInPixels = sizeAndRotation.iPixelSize.iWidth; + nativeScreenHeightInPixels = sizeAndRotation.iPixelSize.iHeight; + break; + } + } + S60->nativeOrientationIsPortrait = nativeScreenWidthInPixels <= nativeScreenHeightInPixels; } inline RWsSession& QS60Data::wsSession() diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 6a44bcc..fd9deb5 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -306,6 +306,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , qd_hd(0) #elif defined(Q_OS_SYMBIAN) , symbianScreenNumber(0) + , fixNativeOrientationCalled(false) #endif { if (!qApp) { @@ -10868,6 +10869,9 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) } QT_TRAP_THROWING(appUi->SetOrientationL(s60orientation)); S60->orientationSet = true; + QSymbianControl *window = static_cast<QSymbianControl *>(internalWinId()); + if (window) + window->ensureFixNativeOrientation(); #endif break; } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 13e2349..377e3a7 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -883,6 +883,7 @@ public: static QWidget *mouseGrabber; static QWidget *keyboardGrabber; int symbianScreenNumber; // only valid for desktop widget and top-levels + bool fixNativeOrientationCalled; void s60UpdateIsOpaque(); void reparentChildren(); void registerTouchWindow(); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index b65ae4d..e7d5e95 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -278,6 +278,8 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) q->internalWinId()->SetRect(TRect(TPoint(x, y), TSize(w, h))); topData()->normalGeometry = data.crect; } + QSymbianControl *window = static_cast<QSymbianControl *>(q->internalWinId()); + window->ensureFixNativeOrientation(); } else { data.crect.setRect(x, y, w, h); @@ -1204,17 +1206,41 @@ void QWidget::setWindowState(Qt::WindowStates newstate) } #ifdef Q_WS_S60 - bool decorationsVisible(false); - if (!parentWidget()) { // Only top level native windows have control over cba/status pane - // Hide window decoration when switching to fullscreen / minimized otherwise show decoration. - // The window decoration visibility has to be changed before doing actual window state - // change since in that order the availableGeometry will return directly the right size and - // we will avoid unnecessary redraws - decorationsVisible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); - const bool statusPaneVisibility = decorationsVisible; - const bool buttonGroupVisibility = (decorationsVisible || (isFullscreen && cbaRequested)); - S60->setStatusPaneAndButtonGroupVisibility(statusPaneVisibility, buttonGroupVisibility); + // Hide window decoration when switching to fullscreen / minimized otherwise show decoration. + // The window decoration visibility has to be changed before doing actual window state + // change since in that order the availableGeometry will return directly the right size and + // we will avoid unnecessary redraws + Qt::WindowStates comparisonState = newstate; + QWidget *parentWindow = parentWidget(); + if (parentWindow) { + while (parentWindow->parentWidget()) + parentWindow = parentWindow->parentWidget(); + comparisonState = parentWindow->windowState(); + } else { + parentWindow = this; + } + + const bool decorationsVisible = !(comparisonState & (Qt::WindowFullScreen | Qt::WindowMinimized)); + const bool parentIsFullscreen = comparisonState & Qt::WindowFullScreen; + const bool parentCbaVisibilityHint = parentWindow->windowFlags() & Qt::WindowSoftkeysVisibleHint; + bool buttonGroupVisibility = (decorationsVisible || (parentIsFullscreen && parentCbaVisibilityHint)); + + // For non-toplevel normal and maximized windows, show cba if window has softkey + // actions even if topmost parent is not showing cba. Do the same for fullscreen + // windows that request it. + if (!buttonGroupVisibility + && parentWidget() + && !(newstate & Qt::WindowMinimized) + && ((windowFlags() & Qt::WindowSoftkeysVisibleHint) || !(newstate & Qt::WindowFullScreen))) { + for (int i = 0; i < actions().size(); ++i) { + if (actions().at(i)->softKeyRole() != QAction::NoSoftKey) { + buttonGroupVisibility = true; + break; + } + } } + S60->setStatusPaneAndButtonGroupVisibility(decorationsVisible, buttonGroupVisibility); + #endif // Q_WS_S60 // Ensure the initial size is valid, since we store it as normalGeometry below. @@ -1273,6 +1299,12 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowActive) activateWindow(); + if (isWindow()) { + // Now that the new state is set, fix the display memory layout, if needed. + QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId()); + window->ensureFixNativeOrientation(); + } + QWindowStateChangeEvent e(oldstate); QApplication::sendEvent(this, &e); } diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 0948a64..0bb2901 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1863,39 +1863,39 @@ static bool qt_painterpath_isect_line_rect(qreal x1, qreal y1, qreal x2, qreal y return false; } -static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2) +static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1, qreal x2, int depth = 0) { QRectF bounds = bezier.bounds(); if (y >= bounds.top() && y < bounds.bottom() && bounds.right() >= x1 && bounds.left() < x2) { const qreal lower_bound = qreal(.01); - if (bounds.width() < lower_bound && bounds.height() < lower_bound) + if (depth == 32 || bounds.width() < lower_bound && bounds.height() < lower_bound) return true; QBezier first_half, second_half; bezier.split(&first_half, &second_half); - if (qt_isect_curve_horizontal(first_half, y, x1, x2) - || qt_isect_curve_horizontal(second_half, y, x1, x2)) + if (qt_isect_curve_horizontal(first_half, y, x1, x2, depth + 1) + || qt_isect_curve_horizontal(second_half, y, x1, x2, depth + 1)) return true; } return false; } -static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2) +static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qreal y2, int depth = 0) { QRectF bounds = bezier.bounds(); if (x >= bounds.left() && x < bounds.right() && bounds.bottom() >= y1 && bounds.top() < y2) { const qreal lower_bound = qreal(.01); - if (bounds.width() < lower_bound && bounds.height() < lower_bound) + if (depth == 32 || bounds.width() < lower_bound && bounds.height() < lower_bound) return true; QBezier first_half, second_half; bezier.split(&first_half, &second_half); - if (qt_isect_curve_vertical(first_half, x, y1, y2) - || qt_isect_curve_vertical(second_half, x, y1, y2)) + if (qt_isect_curve_vertical(first_half, x, y1, y2, depth + 1) + || qt_isect_curve_vertical(second_half, x, y1, y2, depth + 1)) return true; } return false; diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 1320f5e..aa68c23 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -107,8 +107,8 @@ const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** {5,0,-909,0,0,2,0,2,-1,7,12,22,15,15,7,198,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1,106}, {5,0,-909,0,0,1,0,2,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1,106}, -{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, -{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, +{7,0,-909,0,0,2,0,5,-1,25,69,46,37,37,9,258,-909,-909,-909,23,19,11,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,3,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, +{7,0,-909,0,0,2,0,5,-1,25,68,46,37,37,9,258,-909,-909,-909,31,19,13,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,3,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1,135}, {7,0,-909,0,0,2,0,2,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1,106}, {9,0,-909,0,0,2,0,5,-1,34,99,76,51,51,25,352,-909,-909,-909,29,25,7,0,0,43,34,42,76,7,7,2,-909,-909,0,9,14,0,23,39,30,30,37,37,9,391,40,0,-909,-909,-909,-909,0,0,29,2,-909,0,0,-909,29,-909,-909,-909,-909,115,37,96,48,96,19,19,9,1,25,-909,9,101,24,9,0,7,7,7,16,7,7,-909,3,-909,-909,-909,-909,9,9,3,1,184} // *** End of generated data *** @@ -1743,16 +1743,26 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QStyleOptionMenuItem optionMenuItem = *menuItem; bool drawSubMenuIndicator = false; + bool drawSeparator = false; switch(menuItem->menuItemType) { - case QStyleOptionMenuItem::Scroller: case QStyleOptionMenuItem::Separator: - return; // no separators or scrollers in S60 menus + drawSeparator = true; + break; + case QStyleOptionMenuItem::Scroller: + return; // no scrollers in S60 menus case QStyleOptionMenuItem::SubMenu: drawSubMenuIndicator = true; break; default: break; } + if (drawSeparator) { + painter->save(); + painter->setPen(QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 10, 0)); + painter->drawLine(optionMenuItem.rect.topLeft(), optionMenuItem.rect.bottomRight()); + painter->restore(); + return; + } const bool enabled = optionMenuItem.state & State_Enabled; const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable; bool ignoreCheckMark = false; @@ -1856,20 +1866,26 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, //In Sym^3, native menu items have "lines" between them if (QS60StylePrivate::isSingleClickUi()) { - const QColor lineColorAlpha = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 15, 0); - const int spacing = QS60StylePrivate::pixelMetric(PM_FrameCornerWidth); - //native platform sets each color byte to same value for "line 16" which just defines alpha for - //menuitem lines; lets use first byte "red". - QColor lineColor = optionMenuItem.palette.text().color(); - if (lineColorAlpha.isValid()) - lineColor.setAlpha(lineColorAlpha.red()); - painter->save(); - painter->setPen(lineColor); - - const int lineStartX = optionMenuItem.rect.left() + (QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - 2) + spacing; - const int lineEndX = optionMenuItem.rect.right() - (QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - 2) - spacing; - painter->drawLine(QPoint(lineStartX, optionMenuItem.rect.bottom()), QPoint(lineEndX, optionMenuItem.rect.bottom())); - painter->restore(); + int diff = widget->geometry().bottom() - optionMenuItem.rect.bottom(); + if (const QComboBox *cb = qobject_cast<const QComboBox*>(widget)) + diff = cb->view()->geometry().bottom() - optionMenuItem.rect.bottom(); + + // Skip drawing the horizontal line for the last menu item. + if (diff > optionMenuItem.rect.height()) { + const QColor lineColorAlpha = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnLineColors, 15, 0); + //native platform sets each color byte to same value for "line 16" which just defines alpha for + //menuitem lines; lets use first byte "red". + QColor lineColor = optionMenuItem.palette.text().color(); + if (lineColorAlpha.isValid()) + lineColor.setAlpha(lineColorAlpha.red()); + painter->save(); + painter->setPen(lineColor); + const int horizontalMargin = 2 * QS60StylePrivate::pixelMetric(PM_FrameCornerWidth) - QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth); + const int lineStartX = optionMenuItem.rect.left() + horizontalMargin; + const int lineEndX = optionMenuItem.rect.right() - horizontalMargin; + painter->drawLine(QPoint(lineStartX, optionMenuItem.rect.bottom()), QPoint(lineEndX, optionMenuItem.rect.bottom())); + painter->restore(); + } } if (!enabled) painter->restore(); @@ -2264,13 +2280,15 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti #endif //QT_NO_MENU ) { //Need extra check since dialogs have their own theme background - if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) && - QS60StylePrivate::equalToThemePalette(option->palette.window().texture().cacheKey(), QPalette::Window)) - //todo: for combobox listviews, the background should include area for menu scrollers, - //but this produces drawing issues as we need to turn clipping off. - QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, option->rect, flags); - else + if (QS60StylePrivate::canDrawThemeBackground(option->palette.base(), widget) + && QS60StylePrivate::equalToThemePalette(option->palette.window().texture().cacheKey(), QPalette::Window)) { + // Add margin area to the background, to avoid background being cut for first and last item. + const int verticalMenuAdjustment = QS60StylePrivate::pixelMetric(PM_MenuVMargin); + const QRect adjustedMenuRect = option->rect.adjusted(0, -verticalMenuAdjustment, 0, verticalMenuAdjustment); + QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_PopupBackground, painter, adjustedMenuRect, flags); + } else { commonStyleDraws = true; + } } break; case PE_FrameWindow: @@ -2604,10 +2622,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, sz += QSize(2 * f->lineWidth, 4 * f->lineWidth); break; case CT_TabBarTab: { - const QSize naviPaneSize = QS60StylePrivate::naviPaneSize(); sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget); - if (naviPaneSize.height() > sz.height()) - sz.setHeight(naviPaneSize.height()); // Adjust beginning tabbar item size, if scrollbuttons are used. This is to ensure that the // tabbar item content fits, since scrollbuttons are making beginning tabbar item smaller. int scrollButtonSize = 0; @@ -2627,7 +2642,7 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, case CT_ItemViewItem: if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) { if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { - sz = QSize(); + sz = QSize(menuItem->rect.width(), 1); break; } } diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 3628b27..e146a4e 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -562,8 +562,6 @@ public: void handleSkinChange(); #endif // Q_WS_S60 - static QSize naviPaneSize(); - //Checks that the current brush is transparent or has BrushStyle NoBrush, //so that theme graphic background can be drawn. static bool canDrawThemeBackground(const QBrush &backgroundBrush, const QWidget *widget); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index 64d2ad2..6a7158c 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -158,7 +158,6 @@ public: static bool disabledPartGraphic(QS60StyleEnums::SkinParts &part); static bool disabledFrameGraphic(QS60StylePrivate::SkinFrameElements &frame); static QPixmap generateMissingThemeGraphic(QS60StyleEnums::SkinParts &part, const QSize &size, QS60StylePrivate::SkinElementFlags flags); - static QSize naviPaneSize(); static TAknsItemID partSpecificThemeId(int part); static QVariant themeDefinition(QS60StyleEnums::ThemeDefinitions definition, QS60StyleEnums::SkinParts part); @@ -1478,23 +1477,6 @@ void QS60StylePrivate::handleSkinChange() #endif } -QSize QS60StylePrivate::naviPaneSize() -{ - return QS60StyleModeSpecifics::naviPaneSize(); -} - -QSize QS60StyleModeSpecifics::naviPaneSize() -{ - CAknNavigationControlContainer* naviContainer; - if (S60->statusPane()) { - TRAPD(err, naviContainer = static_cast<CAknNavigationControlContainer*> - (S60->statusPane()->ControlL(TUid::Uid(EEikStatusPaneUidNavi)))); - if (err==KErrNone) - return QSize(naviContainer->Size().iWidth, naviContainer->Size().iHeight); - } - return QSize(0,0); -} - int QS60StylePrivate::currentAnimationFrame(QS60StyleEnums::SkinParts part) { QS60StyleAnimation *animation = animationDefinition(part); diff --git a/src/gui/styles/qs60style_simulated.cpp b/src/gui/styles/qs60style_simulated.cpp index 7223c6b..a5aeac3 100644 --- a/src/gui/styles/qs60style_simulated.cpp +++ b/src/gui/styles/qs60style_simulated.cpp @@ -318,11 +318,6 @@ QPixmap QS60StylePrivate::backgroundTexture(bool /*skipCreation*/) return *m_background; } -QSize QS60StylePrivate::naviPaneSize() -{ - return QSize(0, 0); -} - bool QS60StylePrivate::isTouchSupported() { #ifdef QT_KEYPAD_NAVIGATION diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 6babca1..1a81394 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1551,7 +1551,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con extendBlockwiseSelection(cursorPos); else if (selectedWordOnDoubleClick.hasSelection()) extendWordwiseSelection(cursorPos, pos.x()); - else if (wordSelectionEnabled) + else if (!wordSelectionEnabled) setCursorPosition(cursorPos, QTextCursor::KeepAnchor); } else { diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 8aeef50..c1ae3f9 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -2456,12 +2456,7 @@ void QComboBox::showPopup() // available screen geometry.This may override the vertical position, but it is more // important to show as much as possible of the popup. const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height()); -#ifdef Q_WS_S60 - //popup needs to be stretched with screen minimum dimension - listRect.setHeight(qMin(screen.height(), screen.width())); -#else listRect.setHeight(height); -#endif if (boundToScreen) { if (listRect.top() < screen.top()) diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index ccc20e6..69e59d1 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -363,9 +363,9 @@ qint64 QFtpDTP::read(char *data, qint64 maxlen) if (socket && socket->state() == QTcpSocket::ConnectedState) { read = socket->read(data, maxlen); } else { - read = bytesFromSocket.size(); + read = qMin(maxlen, qint64(bytesFromSocket.size())); memcpy(data, bytesFromSocket.data(), read); - bytesFromSocket.clear(); + bytesFromSocket.remove(0, read); } bytesDone += read; diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 618ac79..a5cdf01 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -219,17 +219,19 @@ bool QSslCertificate::isNull() const Returns true if this certificate is valid; otherwise returns false. - Note: Currently, this function only checks that the current + Note: Currently, this function checks that the current data-time is within the date-time range during which the - certificate is considered valid. No other checks are - currently performed. + certificate is considered valid, and checks that the + certificate is not in a blacklist of fraudulent certificates. \sa isNull() */ bool QSslCertificate::isValid() const { const QDateTime currentTime = QDateTime::currentDateTime(); - return currentTime >= d->notValidBefore && currentTime <= d->notValidAfter; + return currentTime >= d->notValidBefore && + currentTime <= d->notValidAfter && + ! QSslCertificatePrivate::isBlacklisted(*this); } /*! @@ -798,6 +800,30 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteAr return certificates; } +// These certificates are known to be fraudulent and were created during the comodo +// compromise. See http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html +static const char *certificate_blacklist[] = { + "04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e", + "f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06", + "d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3", + "39:2a:43:4f:0e:07:df:1f:8a:a3:05:de:34:e0:c2:29", + "3e:75:ce:d4:6b:69:30:21:21:88:30:ae:86:a8:2a:71", + "e9:02:8b:95:78:e4:15:dc:1a:71:0a:2b:88:15:44:47", + "92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43", + "b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0", + "d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0", + 0 +}; + +bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate) +{ + for (int a = 0; certificate_blacklist[a] != 0; a++) { + if (certificate.serialNumber() == certificate_blacklist[a]) + return true; + } + return false; +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const QSslCertificate &certificate) { diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h index cdceb0f..1ce33d3 100644 --- a/src/network/ssl/qsslcertificate_p.h +++ b/src/network/ssl/qsslcertificate_p.h @@ -96,6 +96,7 @@ public: static QSslCertificate QSslCertificate_from_X509(X509 *x509); static QList<QSslCertificate> certificatesFromPem(const QByteArray &pem, int count = -1); static QList<QSslCertificate> certificatesFromDer(const QByteArray &der, int count = -1); + static bool isBlacklisted(const QSslCertificate &certificate); friend class QSslSocketBackendPrivate; diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 0866534..2427193 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1193,6 +1193,13 @@ bool QSslSocketBackendPrivate::startHandshake() X509 *x509 = q_SSL_get_peer_certificate(ssl); configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509); q_X509_free(x509); + if (QSslCertificatePrivate::isBlacklisted(configuration.peerCertificate)) { + q->setErrorString(QSslSocket::tr("The peer certificate is blacklisted")); + q->setSocketError(QAbstractSocket::SslHandshakeFailedError); + emit q->error(QAbstractSocket::SslHandshakeFailedError); + plainSocket->disconnectFromHost(); + return false; + } // Start translating errors. QList<QSslError> errors; diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp index 7caaabd..1b41db4 100644 --- a/src/opengl/qgl_symbian.cpp +++ b/src/opengl/qgl_symbian.cpp @@ -48,6 +48,7 @@ #include <private/qgl_p.h> #include <private/qpaintengine_opengl_p.h> #include <private/qwidget_p.h> // to access QWExtra +#include <private/qnativeimagehandleprovider_p.h> #include "qgl_egl_p.h" #include "qpixmapdata_gl_p.h" #include "qgltexturepool_p.h" @@ -411,6 +412,11 @@ void QGLPixmapData::fromNativeType(void* pixmap, NativeType type) m_hasAlpha = m_source.hasAlphaChannel(); m_hasFillColor = false; m_dirty = true; + } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) { + destroyTexture(); + nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap); + // Cannot defer the retrieval, we need at least the size right away. + createFromNativeImageHandleProvider(); } } @@ -425,4 +431,42 @@ void* QGLPixmapData::toNativeType(NativeType type) return 0; } +bool QGLPixmapData::initFromNativeImageHandle(void *handle, const QString &type) +{ + if (type == QLatin1String("RSgImage")) { + fromNativeType(handle, QPixmapData::SgImage); + return true; + } else if (type == QLatin1String("CFbsBitmap")) { + fromNativeType(handle, QPixmapData::FbsBitmap); + return true; + } + return false; +} + +void QGLPixmapData::createFromNativeImageHandleProvider() +{ + void *handle = 0; + QString type; + nativeImageHandleProvider->get(&handle, &type); + if (handle) { + if (initFromNativeImageHandle(handle, type)) { + nativeImageHandle = handle; + nativeImageType = type; + } else { + qWarning("QGLPixmapData: Unknown native image type '%s'", qPrintable(type)); + } + } else { + qWarning("QGLPixmapData: Native handle is null"); + } +} + +void QGLPixmapData::releaseNativeImageHandle() +{ + if (nativeImageHandleProvider && nativeImageHandle) { + nativeImageHandleProvider->release(nativeImageHandle, nativeImageType); + nativeImageHandle = 0; + nativeImageType = QString(); + } +} + QT_END_NAMESPACE diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 41740dd..8855c20 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -76,6 +76,10 @@ void qt_gl_unregister_pixmap(QGLPixmapData *pd); void qt_gl_hibernate_pixmaps(); #endif +#ifdef Q_OS_SYMBIAN +class QNativeImageHandleProvider; +#endif + class QGLFramebufferObjectPool { public: @@ -160,6 +164,9 @@ public: QImage::Format idealFormat(QImage &image, Qt::ImageConversionFlags flags); void* toNativeType(NativeType type); void fromNativeType(void* pixmap, NativeType type); + bool initFromNativeImageHandle(void *handle, const QString &type); + void createFromNativeImageHandleProvider(); + void releaseNativeImageHandle(); #endif private: @@ -191,6 +198,9 @@ private: mutable QGLContext *m_ctx; #ifdef Q_OS_SYMBIAN mutable QVolatileImage m_source; + mutable QNativeImageHandleProvider *nativeImageHandleProvider; + void *nativeImageHandle; + QString nativeImageType; #else mutable QImage m_source; #endif diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_poolgl.cpp index 64de29e..44d9c84 100644 --- a/src/opengl/qpixmapdata_poolgl.cpp +++ b/src/opengl/qpixmapdata_poolgl.cpp @@ -49,6 +49,7 @@ #include <private/qgl_p.h> #include <private/qdrawhelper_p.h> #include <private/qimage_p.h> +#include <private/qnativeimagehandleprovider_p.h> #include <private/qpaintengineex_opengl2_p.h> @@ -254,6 +255,8 @@ QGLPixmapData::QGLPixmapData(PixelType type) , m_renderFbo(0) , m_engine(0) , m_ctx(0) + , nativeImageHandleProvider(0) + , nativeImageHandle(0) , m_dirty(false) , m_hasFillColor(false) , m_hasAlpha(false) @@ -292,6 +295,8 @@ void QGLPixmapData::destroyTexture() } m_texture.id = 0; inTexturePool = false; + + releaseNativeImageHandle(); } QPixmapData *QGLPixmapData::createCompatiblePixmapData() const @@ -342,6 +347,9 @@ void QGLPixmapData::ensureCreated() const m_dirty = false; + if (nativeImageHandleProvider && !nativeImageHandle) + const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider(); + QGLShareContextScope ctx(qt_gl_share_widget()->context()); m_ctx = ctx; @@ -860,9 +868,16 @@ void QGLPixmapData::detachTextureFromPool() void QGLPixmapData::hibernate() { - // If the texture was imported (e.g, from an SgImage under Symbian), - // then we cannot copy it back to main memory for storage. - if (m_texture.id && m_source.isNull()) + // If the image was imported (e.g, from an SgImage under Symbian), then + // skip the hibernation, there is no sense in copying it back to main + // memory because the data is most likely shared between several processes. + bool skipHibernate = (m_texture.id && m_source.isNull()); +#if defined(Q_OS_SYMBIAN) + // However we have to proceed normally if the image was retrieved via + // a handle provider. + skipHibernate &= !nativeImageHandleProvider; +#endif + if (skipHibernate) return; forceToImage(); diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 3f67c79..80f5b2f 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -458,7 +458,7 @@ void QVGPixmapData::hibernate() if (skipHibernate) return; - forceToImage(); + forceToImage(false); // no readback allowed here destroyImageAndContext(); } @@ -502,12 +502,13 @@ int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const // Ensures that the pixmap is backed by some valid data and forces the data to // be re-uploaded to the VGImage when toVGImage() is called next time. -void QVGPixmapData::forceToImage() +void QVGPixmapData::forceToImage(bool allowReadback) { if (!isValid()) return; - ensureReadback(false); + if (allowReadback) + ensureReadback(false); if (source.isNull()) source = QVolatileImage(w, h, sourceFormat()); diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h index 15ff889..c284596 100644 --- a/src/openvg/qpixmapdata_vg_p.h +++ b/src/openvg/qpixmapdata_vg_p.h @@ -188,7 +188,7 @@ protected: QString nativeImageType; #endif - void forceToImage(); + void forceToImage(bool allowReadback = true); QImage::Format sourceFormat() const; QImage::Format idealFormat(QImage *image, Qt::ImageConversionFlags flags) const; void updateSerial(); diff --git a/src/s60installs/bwins/QtOpenGLu.def b/src/s60installs/bwins/QtOpenGLu.def index f52932c..d7c8394 100644 --- a/src/s60installs/bwins/QtOpenGLu.def +++ b/src/s60installs/bwins/QtOpenGLu.def @@ -719,4 +719,7 @@ EXPORTS ?serialNumber@QGLTextureGlyphCache@@QBEHXZ @ 718 NONAME ; int QGLTextureGlyphCache::serialNumber(void) const ?forceToImage@QGLPixmapData@@QAEXXZ @ 719 NONAME ; void QGLPixmapData::forceToImage(void) ?idealFormat@QGLPixmapData@@QAE?AW4Format@QImage@@AAV3@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 720 NONAME ; enum QImage::Format QGLPixmapData::idealFormat(class QImage &, class QFlags<enum Qt::ImageConversionFlag>) + ?releaseNativeImageHandle@QGLPixmapData@@QAEXXZ @ 721 NONAME ; void QGLPixmapData::releaseNativeImageHandle(void) + ?createFromNativeImageHandleProvider@QGLPixmapData@@QAEXXZ @ 722 NONAME ; void QGLPixmapData::createFromNativeImageHandleProvider(void) + ?initFromNativeImageHandle@QGLPixmapData@@QAE_NPAXABVQString@@@Z @ 723 NONAME ; bool QGLPixmapData::initFromNativeImageHandle(void *, class QString const &) diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def index 18f576b..f2433d6 100644 --- a/src/s60installs/bwins/QtOpenVGu.def +++ b/src/s60installs/bwins/QtOpenVGu.def @@ -134,7 +134,7 @@ EXPORTS ?drawTextItem@QVGPaintEngine@@UAEXABVQPointF@@ABVQTextItem@@@Z @ 133 NONAME ; void QVGPaintEngine::drawTextItem(class QPointF const &, class QTextItem const &) ?clearScissor@QVGCompositionHelper@@QAEXXZ @ 134 NONAME ; void QVGCompositionHelper::clearScissor(void) ?fill@QVGPaintEngine@@UAEXABVQVectorPath@@ABVQBrush@@@Z @ 135 NONAME ; void QVGPaintEngine::fill(class QVectorPath const &, class QBrush const &) - ?forceToImage@QVGPixmapData@@IAEXXZ @ 136 NONAME ; void QVGPixmapData::forceToImage(void) + ?forceToImage@QVGPixmapData@@IAEXXZ @ 136 NONAME ABSENT ; void QVGPixmapData::forceToImage(void) ?drawPoints@QVGPaintEngine@@UAEXPBVQPoint@@H@Z @ 137 NONAME ; void QVGPaintEngine::drawPoints(class QPoint const *, int) ??_EQVGPaintEngine@@UAE@I@Z @ 138 NONAME ; QVGPaintEngine::~QVGPaintEngine(unsigned int) ?clip@QVGPaintEngine@@UAEXABVQPainterPath@@W4ClipOperation@Qt@@@Z @ 139 NONAME ; void QVGPaintEngine::clip(class QPainterPath const &, enum Qt::ClipOperation) @@ -183,4 +183,5 @@ EXPORTS ?initFromNativeImageHandle@QVGPixmapData@@QAE_NPAXABVQString@@@Z @ 182 NONAME ; bool QVGPixmapData::initFromNativeImageHandle(void *, class QString const &) ?createFromNativeImageHandleProvider@QVGPixmapData@@QAEXXZ @ 183 NONAME ; void QVGPixmapData::createFromNativeImageHandleProvider(void) ?releaseNativeImageHandle@QVGPixmapData@@QAEXXZ @ 184 NONAME ; void QVGPixmapData::releaseNativeImageHandle(void) + ?forceToImage@QVGPixmapData@@IAEX_N@Z @ 185 NONAME ; void QVGPixmapData::forceToImage(bool) diff --git a/src/s60installs/eabi/QtOpenGLu.def b/src/s60installs/eabi/QtOpenGLu.def index f7a7f71..488c6cd 100644 --- a/src/s60installs/eabi/QtOpenGLu.def +++ b/src/s60installs/eabi/QtOpenGLu.def @@ -721,4 +721,7 @@ EXPORTS _ZN13QGLPixmapData9hibernateEv @ 720 NONAME _ZN17QGLGraphicsSystem22releaseCachedResourcesEv @ 721 NONAME _ZN13QGLPixmapData11idealFormatER6QImage6QFlagsIN2Qt19ImageConversionFlagEE @ 722 NONAME + _ZN13QGLPixmapData24releaseNativeImageHandleEv @ 723 NONAME + _ZN13QGLPixmapData25initFromNativeImageHandleEPvRK7QString @ 724 NONAME + _ZN13QGLPixmapData35createFromNativeImageHandleProviderEv @ 725 NONAME diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def index 25c53b8..08afd61 100644 --- a/src/s60installs/eabi/QtOpenVGu.def +++ b/src/s60installs/eabi/QtOpenVGu.def @@ -8,7 +8,7 @@ EXPORTS _Z25qt_vg_create_paint_enginev @ 7 NONAME _Z26qt_vg_destroy_paint_engineP14QVGPaintEngine @ 8 NONAME _Z28qt_vg_config_to_image_formatP11QEglContext @ 9 NONAME - _ZN13QVGPixmapData12forceToImageEv @ 10 NONAME + _ZN13QVGPixmapData12forceToImageEv @ 10 NONAME ABSENT _ZN13QVGPixmapData12toNativeTypeEN11QPixmapData10NativeTypeE @ 11 NONAME _ZN13QVGPixmapData14fromNativeTypeEPvN11QPixmapData10NativeTypeE @ 12 NONAME _ZN13QVGPixmapData15setAlphaChannelERK7QPixmap @ 13 NONAME @@ -213,4 +213,5 @@ EXPORTS _ZN13QVGPixmapData24releaseNativeImageHandleEv @ 212 NONAME _ZN13QVGPixmapData25initFromNativeImageHandleEPvRK7QString @ 213 NONAME _ZN13QVGPixmapData35createFromNativeImageHandleProviderEv @ 214 NONAME + _ZN13QVGPixmapData12forceToImageEb @ 215 NONAME diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 76f1dda..d1bb48b 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -42,7 +42,7 @@ symbian: { contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { qts60plugindeployment = \ - "IF package(0x20022E6D)" \ + "IF package(0x2003A678) OR package(0x20022E6D)" \ " \"$$pluginLocations/qts60plugin_5_0$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qts60plugin_5_0$${QT_LIBINFIX}.dll\"" \ " \"$$bearerPluginLocation/qsymbianbearer$${QT_LIBINFIX}.dll\" - \"c:\\sys\\bin\\qsymbianbearer$${QT_LIBINFIX}.dll\"" \ "ELSEIF package(0x1028315F)" \ diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 5a2591f..2ce493b 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -174,7 +174,7 @@ private: QVERIFY(component.errors().isEmpty()); \ } else { \ QFile file(QLatin1String(SRCDIR) + QLatin1String("/data/") + QLatin1String(errorfile)); \ - QVERIFY(file.open(QIODevice::ReadOnly)); \ + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \ QByteArray data = file.readAll(); \ file.close(); \ QList<QByteArray> expected = data.split('\n'); \ diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp index dc104e2..9d1c609 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp @@ -85,7 +85,7 @@ private slots: QVERIFY(component.errors().isEmpty()); \ } else { \ QFile file(QLatin1String("data/") + QLatin1String(errorfile)); \ - QVERIFY(file.open(QIODevice::ReadOnly)); \ + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); \ QByteArray data = file.readAll(); \ file.close(); \ QList<QByteArray> expected = data.split('\n'); \ diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index f62c2c5..04ecf91 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -1340,6 +1340,12 @@ void tst_qdeclarativetextedit::mouseSelection() else QVERIFY(str.isEmpty()); + // Clicking and shift to clicking between the same points should select the same text. + textEditObject->setCursorPosition(0); + QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::NoModifier, canvas->mapFromScene(QPoint(x1,y))); + QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::ShiftModifier, canvas->mapFromScene(QPoint(x2,y))); + QCOMPARE(textEditObject->selectedText(), str); + delete canvas; } @@ -1436,6 +1442,12 @@ void tst_qdeclarativetextedit::mouseSelectionMode() QVERIFY(str != text); } + // Clicking and shift to clicking between the same points should select the same text. + textEditObject->setCursorPosition(0); + QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::NoModifier, canvas->mapFromScene(QPoint(x1,y))); + QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::ShiftModifier, canvas->mapFromScene(QPoint(x2,y))); + QCOMPARE(textEditObject->selectedText(), str); + delete canvas; } diff --git a/tests/auto/qpainterpath/tst_qpainterpath.cpp b/tests/auto/qpainterpath/tst_qpainterpath.cpp index 4ade9ad..bc3b5d9 100644 --- a/tests/auto/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/qpainterpath/tst_qpainterpath.cpp @@ -411,6 +411,10 @@ void tst_QPainterPath::intersects_QRectF_data() QTest::newRow("horizontal line") << linePath(0, 0, 10, 0) << QRectF(1, -1, 2, 2) << true; QTest::newRow("vertical line") << linePath(0, 0, 0, 10) << QRectF(-1, 1, 2, 2) << true; + + path = QPainterPath(); + path.addEllipse(QRectF(-5000.0, -5000.0, 1500000.0, 1500000.0)); + QTest::newRow("huge ellipse, qreal=float crash") << path << QRectF(1100000.35, 1098000.2, 1500000.0, 1500000.0) << true; } void tst_QPainterPath::intersects_QRectF() diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted1.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted1.pem new file mode 100644 index 0000000..3945aea --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted1.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAnigAwIBAgIQBH7L6fylX3vQnq424QyuHjANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRgwFgYDVQQDEw9tYWlsLmdvb2dsZS5jb20w +HhcNMTEwMzI0MTMwNjI1WhcNMTEwNDIzMTMwNjI1WjBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9tYWlsLmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBAOeAGV2FbGnT4rLjTvCNEEDjj0/iIUATa6RT8WKF2PVaOzbE +oceiODx6hTStvBnCgs+h/d3eVKgp+uAyBde5sW/HlOwHrNgKF3ZDvxegzIOEHaVI +ndNtBpFS3UyOEkO0NxfioBatNRYpeTRU/DVmazu3yvzgrV1V2mDsrNngVWxJAgMB +AAGjgcswgcgwHQYDVR0OBBYEFHcF1eqRpm7B78aY8ZjseN6zSYbvMIGYBgNVHSME +gZAwgY2AFHcF1eqRpm7B78aY8ZjseN6zSYbvoWOkYTBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9tYWlsLmdvb2dsZS5jb22CEAR+y+n8pV970J6uNuEM +rh4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBEb1iF+EbhAJli5Sj2 ++iEdJ5xMP8R6FtgqAYknqXD8+tyEyXxJXdN186qdAWuTD9N22AUqi61BPWxUkufW +xH8FYMEHdFCkitvYE0321+GT5pJz6ON/d5Co+wusumt7T5oSjzj8Ax9V+nmo3Nkb +dSANM4/Lnc6moijcpJZq+GC1ng== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted2.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted2.pem new file mode 100644 index 0000000..4b8d059 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRAPXIavNhYvE6ZPVPbclYfAYwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMOd3d3Lmdvb2dsZS5jb20w +HhcNMTEwMzI0MTMwNzExWhcNMTEwNDIzMTMwNzExWjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAy1fNDFl65Njfcd1EUJeaxvyiKln+JKlqUmk1x4mrE1BQoa0C +QZaiXAF21rDhivWejZWBiEQ4IWbg3b12ANY74G1KqAfLC4BNKS9UP94hy18vezRA +pFc+m/HAClwc8AdACpl8eZpQW8cMgdvnMBMZTrQkgV0JYykX+uDD9Tb+QNUCAwEA +AaOByzCByDAdBgNVHQ4EFgQUSelG6IVRj2ZQbp049zkQ0X/Po9wwgZgGA1UdIwSB +kDCBjYAUSelG6IVRj2ZQbp049zkQ0X/Po9yhYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDnd3dy5nb29nbGUuY29tghEA9chq82Fi8Tpk9U9tyVh8 +BjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBALQyDC/AMQMNj2fa6E8L +umILCklWJwG1K1p/1bUAgm0CB8zm94n1xrh/ZK4+HS+k2a9OQmvLRbFyJn8Wua8p +3UU0267UNkCanA1FKHuO3Mo18wLvjMLWjjCQ4g1C9IvJx6P+8EFDQFG+MJBV/w2k +gJXXVl3q1T1dvahIgfav9QBL +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted3.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted3.pem new file mode 100644 index 0000000..e47ece6 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted3.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAnqgAwIBAgIRANdVj9r18RBbshMoK3B3KaMwDQYJKoZIhvcNAQEFBQAw +XzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4ueWFob28uY29t +MB4XDTExMDMyNDEzMDg0MloXDTExMDQyMzEzMDg0MlowXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4ueWFob28uY29tMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCosFLKRvGtxjvdAjWdEAHYycFTa4VtdpXmCNhNHf2xbeLn +xzde10KjEe44pQxNI+UUD1rJkyuH6wUfloyefn0D2Mu+MvusmvOEzFosa4EDbK9s +BAAlsSiyJgrp/GgbEPq/XOl4XJRBIVP1WC6LllduNbskFCipDqS+HQwifXmmwQID +AQABo4HMMIHJMB0GA1UdDgQWBBSEgWnsoYtd5GEx/MGJvKxuIuROJzCBmQYDVR0j +BIGRMIGOgBSEgWnsoYtd5GEx/MGJvKxuIuROJ6FjpGEwXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4ueWFob28uY29tghEA11WP2vXxEFuyEygr +cHcpozAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAKNpIrzTOxIykKZt +EE6HU2nW1lrWUkIMjwjL8ntw7QI4JLMDN1ADVIxWaGTeQ+U/eXFou6dDNAYVAijK +ONDXgOItxW2YvSw0wOZsZj6INX2x88/0yRH+19TqaL/r+Y1D1h/0zefkHgfXufnY +Ex7BHju/rGBTp6R1mr+Tlh1tewva +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted4.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted4.pem new file mode 100644 index 0000000..64c7d41 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted4.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAnigAwIBAgIQOSpDTw4H3x+KowXeNODCKTANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20w +HhcNMTEwMzI0MTMwOTE1WhcNMTEwNDIzMTMwOTE1WjBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBANO2gz9x2H92xz5OvZSEul9gHxqqd+kdjeoS2exyvjC9wzqb +gYXqNmAsbtNp4WmieEQFd0riCAEkIAn8JpHTCsMHN4rHhS+W+4D5a/drI2jfnZEF +orNYJG1PHSQV/rvh6d7wkVdT+0SYOjrFTAA2biGWaK3W9ztf2yX577w+uQtBAgMB +AAGjgcswgcgwHQYDVR0OBBYEFJjDp8Prs7oReRmskIeFixp0vDkGMIGYBgNVHSME +gZAwgY2AFJjDp8Prs7oReRmskIeFixp0vDkGoWOkYTBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb22CEDkqQ08OB98fiqMF3jTg +wikwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAZyo0Q3leeM1+lxeCd +Wp0ZYHMSW11ANc6nuMWOmJC+nIQGlyGiP3IqeUvIfekwboV638bahVPwcl2HYWsS +/l01Bgyd25Zn6VTQBfMK01dILyxscjVwdHuojzYBN05sl+qkVoqQr5EroQQbgDc9 +6I88p6Kjajv3IusCwfK6wlqISw== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted5.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted5.pem new file mode 100644 index 0000000..c7ddbf2 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted5.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAnigAwIBAgIQPnXO1GtpMCEhiDCuhqgqcTANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20w +HhcNMTEwMzI0MTMwOTQ4WhcNMTEwNDIzMTMwOTQ4WjBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb20wgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBALkiHG9TgTw/00CMW8D23NBDAa3331AL5kTkAaXbAWg2R/1o +yKQfXq3hgHbyWGPccUT+tU6FmaBf3bIndLK7iGx81RGzGgXeoQ5mpgnJ50iCeW73 +G99VlVwutPia7d9qqui84YdcG9t+P2Fuxv+xRqAB6lKOaa4qTPIbH50PgwOvAgMB +AAGjgcswgcgwHQYDVR0OBBYEFBWJrs8bnZ5fikfaLbTxK0ssj69MMIGYBgNVHSME +gZAwgY2AFBWJrs8bnZ5fikfaLbTxK0ssj69MoWOkYTBfMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRgwFgYDVQQDEw9sb2dpbi55YWhvby5jb22CED51ztRraTAhIYgwroao +KnEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCIfqqs1a7RzdmV8U00 +v/xAsxscKvQvmu6BK+HwvY5iL2pSwXTYgRLJLoj5QGOd3mmgOFsyW3BPSCP1+fVE +M1ROhU2u8wHub+hGGds18Fx6F4yZjdh8pNUoOUR9A0Ym+VDJr2p50oUNTTy0RbH8 +9ns/gbemx84cjF9DD2G5stQhYg== +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted6.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted6.pem new file mode 100644 index 0000000..bc2be2a --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted6.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAnqgAwIBAgIRAOkCi5V45BXcGnEKK4gVREcwDQYJKoZIhvcNAQEFBQAw +XzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4uc2t5cGUuY29t +MB4XDTExMDMyNDEzMTAxNloXDTExMDQyMzEzMTAxNlowXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4uc2t5cGUuY29tMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDFq06qqRl86pP7GRX3m7FMMSaSU6zlNGAo+WPoRfYAzB6x +5KpvlfxMCo3T/nWtInX3Bw9TBWCZSweQ2GEjggO0irjw5UX3MiToLxK+rwzWztm9 +H3LBxTWR0cOOa78kRFvNQ1onvNHbs8fJzXjG7b2IJDOIwG1HAT1LK80oPXZc1wID +AQABo4HMMIHJMB0GA1UdDgQWBBTiGNxw0ImW/wfW0mD3eA65PY5CAzCBmQYDVR0j +BIGRMIGOgBTiGNxw0ImW/wfW0mD3eA65PY5CA6FjpGEwXzELMAkGA1UEBhMCQVUx +EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDEYMBYGA1UEAxMPbG9naW4uc2t5cGUuY29tghEA6QKLlXjkFdwacQor +iBVERzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAHdb1QY/oxuro/4x +GX9jbm930ysoeXkWZSKVtVxoxrPIferu8jVpb1SLRjGcMnmjJoNWNFpvnbZgoYei +f3wdSWun7ndyQBh61k8eM7UABDOUXUHOsHuHj7s1koMKtet4gykmMfd6VxBkwBvN +ZXOll4X+TKe8nrxbnGUByIwQaRM+ +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted7.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted7.pem new file mode 100644 index 0000000..19d4353 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted7.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGjCCAoOgAwIBAgIRAJI51TSPQNFpWnRUcOHyP0MwDQYJKoZIhvcNAQEFBQAw +YjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEbMBkGA1UEAxMSYWRkb25zLm1vemlsbGEu +b3JnMB4XDTExMDMyNDEzMTA0NFoXDTExMDQyMzEzMTA0NFowYjELMAkGA1UEBhMC +QVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdp +dHMgUHR5IEx0ZDEbMBkGA1UEAxMSYWRkb25zLm1vemlsbGEub3JnMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQC1lsoAcZTwF8Pf0E9do5avLdobB/O7EhhrCMs2 +/EMO07aIlrLwl3UP/Fmu/cAkKuX8Mx+Eif9x+XT3ZqGKGYKiqPTJcNfeZvgwbn0j +wXDtEo4DuURrwtBU9okS+v4dF6F4RtHQKAGcsXoOjhR7ah71kve+PG2GG0sJ167V +klK1xwIDAQABo4HPMIHMMB0GA1UdDgQWBBRgGDJ4Qp0WFyLIzm4Nz5wgqDSSxjCB +nAYDVR0jBIGUMIGRgBRgGDJ4Qp0WFyLIzm4Nz5wgqDSSxqFmpGQwYjELMAkGA1UE +BhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp +ZGdpdHMgUHR5IEx0ZDEbMBkGA1UEAxMSYWRkb25zLm1vemlsbGEub3JnghEAkjnV +NI9A0WladFRw4fI/QzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACeE +DHMQ+LWEuoa/6z2EgrgM1k9rvBbUtCR+rjTuyzVW4OLXdpiVwZPOAiKphpq7q8Sb +TQ3zwsCoPLLJk5VolwcPfcD8Y2/tYK3NCYl+HzGxxnzPDFVaZM5Jh8RI861Hc00D +hVoQaptPK/V/lr0KEevqjhusAdFZbwlWA923zASa +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted8.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted8.pem new file mode 100644 index 0000000..aedf3f7 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted8.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRALC3Ez7Qlvm1b66RyHS9OsAwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMObG9naW4ubGl2ZS5jb20w +HhcNMTEwMzI0MTMxMTA2WhcNMTEwNDIzMTMxMTA2WjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw5sb2dpbi5saXZlLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEA3OVNj9ijzMewvDeZYzgCWoKtyjclyIHxrQfHZpcexaKbxUap +1MtF6L0ayjtRWpiBYuPteUSy/Ja4Oh6zZz8K6z5rVgXhmy3xPIYuOoWaTKEOhb0Z +oHTBtGh8aWWai1XWw37HIm2FP8cmfgdH4lZwVvpTZIUxYidsyqyjB9IrhiMCAwEA +AaOByzCByDAdBgNVHQ4EFgQU4CcQcIvEhJC0tqHlNFMkv6MlDN4wgZgGA1UdIwSB +kDCBjYAU4CcQcIvEhJC0tqHlNFMkv6MlDN6hYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDmxvZ2luLmxpdmUuY29tghEAsLcTPtCW+bVvrpHIdL06 +wDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAMNzIStXDNSNQ8ayxrcj +4RrUMsHWUG/6XPrgfYqCP5TfPGAa5qBfNb9LfUbiS4b0flJVN1RlHVwwRo0yf9v4 +LGg0dSuPQAOWlLeUR1GminO1jHZw7E4dYfR7QEmiiOgaQU+CbxLsf5vCaKInN9Gu +jv/5xytVCbMoLoZ4EBVb0tka +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/more-certificates/blacklisted9.pem b/tests/auto/qsslcertificate/more-certificates/blacklisted9.pem new file mode 100644 index 0000000..d179b29 --- /dev/null +++ b/tests/auto/qsslcertificate/more-certificates/blacklisted9.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRANjzX063hystqwaS4xU4L7AwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMOZ2xvYmFsIHRydXN0ZWUw +HhcNMTEwMzI0MTMxMTM3WhcNMTEwNDIzMTMxMTM3WjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw5nbG9iYWwgdHJ1c3RlZTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEArHCVym7AEZDBhDkrUSG3Q94a+caNcCk5fE6ltZHiZHv096xr +cixHYvSGvms780bkI+oot2xI/e9awwkV+7VjWNvr0HrajzBWeimwk+myjP+3ddMY +Kmr0eI6bmvmPHtOFJE5Ar8/62FwD0wlLogRIx56JtXcCpkiUQktJVPz2gtMCAwEA +AaOByzCByDAdBgNVHQ4EFgQUUJwC/qSGBmcB+DVrd43ovRLdLmQwgZgGA1UdIwSB +kDCBjYAUUJwC/qSGBmcB+DVrd43ovRLdLmShYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDmdsb2JhbCB0cnVzdGVlghEA2PNfTreHKy2rBpLjFTgv +sDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACAYxI+r3+JNelL6SBB0 +Pda3LkbCm+schP64NBYDdGl2Kus2b2QZ83T7xENBFEhyNoXvc6pRI4/Oh6JDxmG1 +7WmqOVStS/4JeAu6ygiyI1ImRKq2/MvJx/kaKh6IiXanB5nW1U+fhDV6kMOEfpwV +i6FBibpHboPQoqzPPRe7qHSL +-----END CERTIFICATE----- diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index 1e3a8dd..57f2fa8 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -111,6 +111,8 @@ private slots: void nulInSan(); void largeSerialNumber(); void largeExpirationDate(); + void blacklistedCertificates(); + // ### add tests for certificate bundles (multiple certificates concatenated into a single // structure); both PEM and DER formatted #endif @@ -817,6 +819,15 @@ void tst_QSslCertificate::largeExpirationDate() // QTBUG-12489 QCOMPARE(cert.expiryDate().toUTC(), QDateTime(QDate(2051, 8, 29), QTime(9, 53, 41), Qt::UTC)); } +void tst_QSslCertificate::blacklistedCertificates() +{ + QList<QSslCertificate> blacklistedCerts = QSslCertificate::fromPath("more-certificates/blacklisted*.pem", QSsl::Pem, QRegExp::Wildcard); + QVERIFY2(blacklistedCerts.count() > 0, "Please run this test from the source directory"); + for (int a = 0; a < blacklistedCerts.count(); a++) { + QVERIFY(! blacklistedCerts.at(a).isValid()); + } +} + #endif // QT_NO_OPENSSL QTEST_MAIN(tst_QSslCertificate) diff --git a/tests/auto/qsslsocket/certs/fake-login.live.com.key b/tests/auto/qsslsocket/certs/fake-login.live.com.key new file mode 100644 index 0000000..692a7bd --- /dev/null +++ b/tests/auto/qsslsocket/certs/fake-login.live.com.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDOtxdvMa0VHUQYG5q7Tsi1Jj4qKEJppyZEkmuRXOi0fDbd1SwE +bwHrLGMvDO6OMrYBbq3WDNrtnIfF9CvzUOEch+gjr4hEVQqecU5fb45Wor7yNel3 +/C/gxfbzuXHrsj/gUjNghL2i10+c2NW+hUo/sWO6OusaBT6d6s7ee+YBcQIDAQAB +AoGAb8cVhu0HuLkgjyCuJMbPRRUu3ED02Iin6sB6JhplQuNAD+grayJTmUVhRJnr +jTziqhedLHe7Em1oBaSo92MutfMpXvWiccSlbNygI61VgmrJpVB+qIN5H9cQc9ql +Zymc+nIPa1+i5rsrOzlpUytTh7AsbZ27QG4tQXR/kQejEiECQQD6BgTxBeT8D7x9 +DuukoBaSCkLwx7U7P1NXx15EI3lA1nO51t6UHfvk/jGPp8Sl4wv4alJ7AQxr5uQ/ +vC3kzA/1AkEA06gNu10se8pe3n8qL2RRt+FmVjHkQdD9Mm2Dx9oWCs2A4wOSOrlo +6/nKYF1CaQNYn9HgsNbHVEUpnICVO18qDQJBALEw/uOJ1+TDikPfBSWgxx4s45Ad +GNWqZXh6NNZ5hX9r/IwiOZAjR9fcRmeW8IjYRi2BvH6sGY+HDRAWXzgdXtkCQCma +dOiJTf8fLjqp4E7kdzOfuI/kyqstOze4Uxjrgz2oW1dEEnA8laUcumzqp+0gXUE8 +7d+UuCWWWrGKjMrYz9kCQQDh5E5+b6Djn082Jo6gvyuXWC5eXju6IdmihlJ2SMzD +s2y3IDjOUtTeQQRDymLneteMz0ha79KeUp6VnAvZCOVe +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/qsslsocket/certs/fake-login.live.com.pem b/tests/auto/qsslsocket/certs/fake-login.live.com.pem new file mode 100644 index 0000000..429f951 --- /dev/null +++ b/tests/auto/qsslsocket/certs/fake-login.live.com.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAnegAwIBAgIRALC3Ez7Qlvm1b66RyHS9OsAwDQYJKoZIhvcNAQEFBQAw +XjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMObG9naW4ubGl2ZS5jb20w +HhcNMTEwMzI1MTMyODUwWhcNMTEwNDI0MTMyODUwWjBeMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ +dHkgTHRkMRcwFQYDVQQDEw5sb2dpbi5saXZlLmNvbTCBnzANBgkqhkiG9w0BAQEF +AAOBjQAwgYkCgYEAzrcXbzGtFR1EGBuau07ItSY+KihCaacmRJJrkVzotHw23dUs +BG8B6yxjLwzujjK2AW6t1gza7ZyHxfQr81DhHIfoI6+IRFUKnnFOX2+OVqK+8jXp +d/wv4MX287lx67I/4FIzYIS9otdPnNjVvoVKP7FjujrrGgU+nerO3nvmAXECAwEA +AaOByzCByDAdBgNVHQ4EFgQUpSOEcmtkQITvBdM2IDfcXnJ0FCAwgZgGA1UdIwSB +kDCBjYAUpSOEcmtkQITvBdM2IDfcXnJ0FCChYqRgMF4xCzAJBgNVBAYTAkFVMRMw +EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0 +eSBMdGQxFzAVBgNVBAMTDmxvZ2luLmxpdmUuY29tghEAsLcTPtCW+bVvrpHIdL06 +wDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAD+2HT4GSHHKCdbl9VkX +zsl+D+drMm2b0ksxz9SgPihP7aW50EEIJDEEihNMTa27mhpeOXHc/sLqDi4ECUao +/0Ns/5uoVuAIrAKCydmtPsonVFh9XWjyrfUzPOHAc9p2bmJ1i9a3kTsLB6jlrVDO +VufGzsowHlHZ0TtKf5omojU5 +-----END CERTIFICATE----- diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index 8177d29..bf7dae5 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -183,6 +183,7 @@ private slots: void ignoreSslErrorsListWithSlot(); void readFromClosedSocket(); void writeBigChunk(); + void blacklist(); void setEmptyDefaultConfiguration(); static void exitLoop() @@ -868,8 +869,13 @@ class SslServer : public QTcpServer { Q_OBJECT public: - SslServer() : socket(0) { } + SslServer(const QString &keyFile = SRCDIR "certs/fluke.key", const QString &certFile = SRCDIR "certs/fluke.cert") + : socket(0), + m_keyFile(keyFile), + m_certFile(certFile) { } QSslSocket *socket; + QString m_keyFile; + QString m_certFile; protected: void incomingConnection(int socketDescriptor) @@ -877,13 +883,13 @@ protected: socket = new QSslSocket(this); connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot())); - QFile file(SRCDIR "certs/fluke.key"); + QFile file(m_keyFile); QVERIFY(file.open(QIODevice::ReadOnly)); QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); QVERIFY(!key.isNull()); socket->setPrivateKey(key); - QList<QSslCertificate> localCert = QSslCertificate::fromPath(SRCDIR "certs/fluke.cert"); + QList<QSslCertificate> localCert = QSslCertificate::fromPath(m_certFile); QVERIFY(!localCert.isEmpty()); QVERIFY(localCert.first().handle()); socket->setLocalCertificate(localCert.first()); @@ -1837,6 +1843,37 @@ void tst_QSslSocket::writeBigChunk() socket->close(); } +void tst_QSslSocket::blacklist() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + SslServer server(SRCDIR "certs/fake-login.live.com.key", SRCDIR "certs/fake-login.live.com.pem"); + QSslSocket *receiver = new QSslSocket(this); + connect(receiver, SIGNAL(readyRead()), SLOT(exitLoop())); + + // connect two sockets to each other: + QVERIFY(server.listen(QHostAddress::LocalHost)); + receiver->connectToHost("127.0.0.1", server.serverPort()); + QVERIFY(receiver->waitForConnected(5000)); + QVERIFY(server.waitForNewConnection(0)); + + QSslSocket *sender = server.socket; + QVERIFY(sender); + QVERIFY(sender->state() == QAbstractSocket::ConnectedState); + receiver->setObjectName("receiver"); + sender->setObjectName("sender"); + receiver->ignoreSslErrors(); + receiver->startClientEncryption(); + + connect(receiver, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(exitLoop())); + connect(receiver, SIGNAL(encrypted()), SLOT(exitLoop())); + enterLoop(1); + QCOMPARE(receiver->error(), QAbstractSocket::SslHandshakeFailedError); + QCOMPARE(receiver->errorString(), QString("The peer certificate is blacklisted")); +} + void tst_QSslSocket::setEmptyDefaultConfiguration() { // used to produce a crash in QSslConfigurationPrivate::deepCopyDefaultConfiguration, QTBUG-13265 |