From 35a11d6fce6820fa71db7c8b696d25b5de508277 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Fri, 28 Mar 2014 22:52:04 +0100 Subject: OS X QSettings auto test/writing check update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch aims to provide an updated test that follows changes started in 10.7: new rule is that only root can access SystemScope settings. It also disables the sync() workaround code path which is at least not executed during the tst_QSettings execution and returns wrong value to the test. From Apple's documentation: "Note that modification of some preferences domains (those not belonging to the “Current User”) requires root privileges (or Admin privileges prior to OS X v10.6)—see Authorization Services Programming Guide for information on how to gain suitable privileges" https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFPreferencesUtils/Reference/reference.html [ChangeLog][QtCore][QSettings] QSettings now returns the correct value for isWritable() when using SystemScope settings. Task-number: QTBUG-9824 Task-number: QTBUG-21062 Task-number: QTBUG-22745 Change-Id: Ib6a1490ec596b99d189ec4de9a0f28ecfd684172 Reviewed-by: Liang Qi --- src/corelib/io/qsettings.cpp | 6 ++++ src/corelib/io/qsettings_mac.cpp | 40 ++++++++++++----------- tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 27 +++++++++++++-- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 0406aeb501..321525ca18 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -2496,6 +2496,12 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, \snippet code/src_corelib_io_qsettings.cpp 7 + \li On Mac OS X, permissions to access settings not belonging to the + current user (i.e. SystemScope) have changed with 10.7 (Lion). Prior to + that version, users having admin rights could access these. For 10.7 and + 10.8 (Mountain Lion), only root can. However, 10.9 (Mavericks) changes + that rule again but only for the native format (plist files). + \li On Unix and Mac OS X systems, the advisory file locking is disabled if NFS (or AutoFS or CacheFS) is detected to work around a bug in the NFS fcntl() implementation, which hangs forever if statd or lockd aren't diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp index 23cff6af27..7d1fb1a7c5 100644 --- a/src/corelib/io/qsettings_mac.cpp +++ b/src/corelib/io/qsettings_mac.cpp @@ -405,7 +405,6 @@ QMacSettingsPrivate::QMacSettingsPrivate(QSettings::Scope scope, const QString & } // if no bundle identifier yet. use a hard coded string. if (domainName.isEmpty()) { - setStatus(QSettings::AccessError); domainName = QLatin1String("unknown-organization.trolltech.com"); } @@ -540,27 +539,30 @@ void QMacSettingsPrivate::sync() // only report failures for the primary file (the one we write to) if (!ok && i == 0 && hostNames[j] == hostName && status == QSettings::NoError) { #if 1 - // work around what seems to be a bug in CFPreferences: - // don't report an error if there are no preferences for the application - QCFType appIds = CFPreferencesCopyApplicationList(domains[i].userName, - hostNames[j]); - - // iterate through all the applications and see if we're there - CFIndex size = CFArrayGetCount(appIds); - for (CFIndex k = 0; k < size; ++k) { - const void *cfvalue = CFArrayGetValueAtIndex(appIds, k); - if (CFGetTypeID(cfvalue) == CFStringGetTypeID()) { - if (CFStringCompare(static_cast(cfvalue), - domains[i].applicationOrSuiteId, - kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - setStatus(QSettings::AccessError); - break; + if (QSysInfo::macVersion() < QSysInfo::MV_10_7) { + // work around what seems to be a bug in CFPreferences: + // don't report an error if there are no preferences for the application + QCFType appIds = CFPreferencesCopyApplicationList(domains[i].userName, + hostNames[j]); + + // iterate through all the applications and see if we're there + CFIndex size = CFArrayGetCount(appIds); + for (CFIndex k = 0; k < size; ++k) { + const void *cfvalue = CFArrayGetValueAtIndex(appIds, k); + if (CFGetTypeID(cfvalue) == CFStringGetTypeID()) { + if (CFStringCompare(static_cast(cfvalue), + domains[i].applicationOrSuiteId, + kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + setStatus(QSettings::AccessError); + break; + } } } - } -#else - setStatus(QSettings::AccessError); + } else #endif + { + setStatus(QSettings::AccessError); + } } } } diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 12c89b1cf4..501ad6f415 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -2797,10 +2798,30 @@ void tst_QSettings::isWritable() QSettings s1(format, QSettings::SystemScope, "software.org", "KillerAPP"); QSettings s2(format, QSettings::SystemScope, "software.org", "Something Different"); QSettings s3(format, QSettings::SystemScope, "foo.org", "Something Different"); + if (s1.contains("foo")) { - QVERIFY(s1.isWritable()); - QVERIFY(s2.isWritable()); - QVERIFY(s3.isWritable()); +#if defined(Q_OS_MACX) + if (QSysInfo::macVersion() >= QSysInfo::MV_10_9) { + QVERIFY(s1.isWritable()); + if (format == QSettings::NativeFormat) { + QVERIFY(!s2.isWritable()); + QVERIFY(!s3.isWritable()); + } else { + QVERIFY(s2.isWritable()); + QVERIFY(s3.isWritable()); + } + } else if (QSysInfo::macVersion() >= QSysInfo::MV_10_7 && + format == QSettings::NativeFormat) { + QVERIFY(!s1.isWritable()); + QVERIFY(!s2.isWritable()); + QVERIFY(!s3.isWritable()); + } else +#endif + { + QVERIFY(s1.isWritable()); + QVERIFY(s2.isWritable()); + QVERIFY(s3.isWritable()); + } } else { QVERIFY(!s1.isWritable()); QVERIFY(!s2.isWritable()); -- cgit v1.2.3