summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/corelib.pro4
-rw-r--r--src/corelib/io/qsettings_mac.cpp82
2 files changed, 84 insertions, 2 deletions
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 9673861..d7306e0 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -22,10 +22,10 @@ include(xml/xml.pri)
!qpa:mac|darwin:LIBS_PRIVATE += -framework ApplicationServices
qpa {
contains(QT_CONFIG, coreservices) {
- LIBS_PRIVATE += -framework CoreServices
+ LIBS_PRIVATE += -framework CoreServices -framework Security
}
} else:mac|darwin {
- LIBS_PRIVATE += -framework CoreFoundation
+ LIBS_PRIVATE += -framework CoreFoundation -framework Security
}
mac:lib_bundle:DEFINES += QT_NO_DEBUG_PLUGIN_CHECK
win32:DEFINES-=QT_NO_CAST_TO_ASCII
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp
index 6d0af2a..3e3189e 100644
--- a/src/corelib/io/qsettings_mac.cpp
+++ b/src/corelib/io/qsettings_mac.cpp
@@ -45,6 +45,13 @@
#include "qdir.h"
#include "qvarlengtharray.h"
#include "private/qcore_mac_p.h"
+#ifndef QT_BOOTSTRAPPED
+#include "qcoreapplication.h"
+#endif
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+#include <Security/SecCode.h>
+#include <Security/SecRequirement.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -343,6 +350,7 @@ class QMacSettingsPrivate : public QSettingsPrivate
public:
QMacSettingsPrivate(QSettings::Scope scope, const QString &organization,
const QString &application);
+ QMacSettingsPrivate(CFStringRef bundleIdentifier);
~QMacSettingsPrivate();
void remove(const QString &key);
@@ -423,6 +431,22 @@ QMacSettingsPrivate::QMacSettingsPrivate(QSettings::Scope scope, const QString &
sync();
}
+QMacSettingsPrivate::QMacSettingsPrivate(CFStringRef bundleIdentifier)
+ : QSettingsPrivate(QSettings::NativeFormat, QSettings::UserScope, QString(), QString())
+{
+ // applicationId and suiteId are QCFStrings and take ownership, retain to prevent double deletes.
+ CFRetain(bundleIdentifier);
+ applicationId = bundleIdentifier;
+ CFRetain(bundleIdentifier);
+ suiteId = bundleIdentifier;
+
+ numDomains = 1;
+ domains[0].userName = kCFPreferencesCurrentUser;
+ domains[0].applicationOrSuiteId = bundleIdentifier;
+ hostName = kCFPreferencesAnyHost;
+ sync();
+}
+
QMacSettingsPrivate::~QMacSettingsPrivate()
{
}
@@ -579,6 +603,64 @@ QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format,
const QString &organization,
const QString &application)
{
+#ifndef QT_BOOTSTRAPPED
+ static bool useAppLocalStorage = false;
+ static bool initialized = false;
+
+ if (!initialized) {
+ bool inSandbox = false;
+
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ // If we are running on at least 10.7.0 and have the com.apple.security.app-sandbox
+ // entitlement, we are in a sandbox
+ SInt32 version = 0;
+ Gestalt(gestaltSystemVersion, &version);
+ SecCodeRef secCodeSelf;
+ if (version >= 0x1070 && SecCodeCopySelf(kSecCSDefaultFlags, &secCodeSelf) == errSecSuccess) {
+ SecRequirementRef sandboxReq;
+ CFStringRef entitlement = CFSTR("entitlement [\"com.apple.security.app-sandbox\"]");
+ if (SecRequirementCreateWithString(entitlement, kSecCSDefaultFlags, &sandboxReq) == errSecSuccess) {
+ if (SecCodeCheckValidity(secCodeSelf, kSecCSDefaultFlags, sandboxReq) == errSecSuccess)
+ inSandbox = true;
+ CFRelease(sandboxReq);
+ }
+ CFRelease(secCodeSelf);
+ }
+#endif
+
+ bool forAppStore = false;
+ if (!inSandbox) {
+ CFTypeRef val = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("ForAppStore"));
+ forAppStore = (val &&
+ CFGetTypeID(val) == CFStringGetTypeID() &&
+ CFStringCompare(CFStringRef(val), CFSTR("yes"), kCFCompareCaseInsensitive) == 0);
+ }
+
+ useAppLocalStorage = inSandbox || forAppStore;
+ initialized = true;
+ }
+
+ if (useAppLocalStorage) {
+ // Ensure that the global and app-local settings go to the same file, since that's
+ // what we really want
+ if (organization == QLatin1String("Trolltech") ||
+ organization.isEmpty() ||
+ (organization == qApp->organizationDomain() && application == qApp->applicationName()) ||
+ (organization == qApp->organizationName()) && application == qApp->applicationName())
+ {
+ CFStringRef bundleIdentifier = CFBundleGetIdentifier(CFBundleGetMainBundle());
+ if (!bundleIdentifier) {
+ qWarning("QSettingsPrivate::create: You must set the bundle identifier when using ForAppStore");
+ } else {
+ QSettingsPrivate* settings = new QMacSettingsPrivate(bundleIdentifier);
+ if (organization == QLatin1String("Trolltech"))
+ settings->beginGroupOrArray(QSettingsGroup("QtLibrarySettings"));
+ return settings;
+ }
+ }
+ }
+#endif
+
if (format == QSettings::NativeFormat) {
return new QMacSettingsPrivate(scope, organization, application);
} else {