summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Gaist <samuel.gaist@edeltech.ch>2014-03-28 22:52:04 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-31 12:12:21 +0200
commit35a11d6fce6820fa71db7c8b696d25b5de508277 (patch)
tree0d254cc9d6ef702056a1d36c21cec03a80a41be4
parent0c7241ccf2592617b602873aae5f3113ed548215 (diff)
OS X QSettings auto test/writing check update
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 <liang.qi@digia.com>
-rw-r--r--src/corelib/io/qsettings.cpp6
-rw-r--r--src/corelib/io/qsettings_mac.cpp40
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp27
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<CFArrayRef> 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<CFStringRef>(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<CFArrayRef> 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<CFStringRef>(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 <QtCore/QString>
#include <QtCore/QDir>
#include <QtCore/QThread>
+#include <QtCore/QSysInfo>
#include <QtGui/QKeySequence>
#include <cctype>
@@ -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());