Changeset 260840 in webkit


Ignore:
Timestamp:
Apr 28, 2020 12:29:07 PM (4 years ago)
Author:
pvollan@apple.com
Message:

[Cocoa] Global preferences are not accessible in the WebContent process when CFPrefs direct mode is enabled
https://bugs.webkit.org/show_bug.cgi?id=211075
Source/WebKit:

<rdar://problem/61866711>

Reviewed by Brent Fulgham.

Global preferences in the domain 'kCFPreferencesAnyApplication' are not readable in the WebContent process when CFPrefs direct mode
is enabled. Fix this by transferring a select set of global preferences to the WebContent process on startup.

API test: WebKit.GlobalPreferences

  • Shared/WebProcessCreationParameters.cpp:

(WebKit::WebProcessCreationParameters::encode const):
(WebKit::WebProcessCreationParameters::decode):

  • Shared/WebProcessCreationParameters.h:
  • UIProcess/Cocoa/WebProcessPoolCocoa.mm:

(WebKit::WebProcessPool::platformInitializeWebProcess):

  • WebProcess/cocoa/WebProcessCocoa.mm:

(WebKit::setGlobalPreferences):
(WebKit::WebProcess::platformInitializeWebProcess):

Tools:

Reviewed by Brent Fulgham.

  • TestWebKitAPI/Tests/WebKit/PreferenceChanges.mm:

(TEST):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r260838 r260840  
     12020-04-28  Per Arne Vollan  <pvollan@apple.com>
     2
     3        [Cocoa] Global preferences are not accessible in the WebContent process when CFPrefs direct mode is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=211075
     5        <rdar://problem/61866711>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Global preferences in the domain 'kCFPreferencesAnyApplication' are not readable in the WebContent process when CFPrefs direct mode
     10        is enabled. Fix this by transferring a select set of global preferences to the WebContent process on startup.
     11
     12        API test: WebKit.GlobalPreferences
     13
     14        * Shared/WebProcessCreationParameters.cpp:
     15        (WebKit::WebProcessCreationParameters::encode const):
     16        (WebKit::WebProcessCreationParameters::decode):
     17        * Shared/WebProcessCreationParameters.h:
     18        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
     19        (WebKit::WebProcessPool::platformInitializeWebProcess):
     20        * WebProcess/cocoa/WebProcessCocoa.mm:
     21        (WebKit::setGlobalPreferences):
     22        (WebKit::WebProcess::platformInitializeWebProcess):
     23
    1242020-04-28  Peng Liu  <peng.liu6@apple.com>
    225
  • trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp

    r260798 r260840  
    195195#if ENABLE(CFPREFS_DIRECT_MODE)
    196196    encoder << preferencesExtensionHandles;
     197    encoder << encodedGlobalPreferences;
    197198#endif
    198199#endif
     
    543544        return false;
    544545    parameters.preferencesExtensionHandles = WTFMove(*preferencesExtensionHandles);
     546
     547    Optional<String> encodedGlobalPreferences;
     548    decoder >> encodedGlobalPreferences;
     549    if (!encodedGlobalPreferences)
     550        return false;
     551    parameters.encodedGlobalPreferences = WTFMove(*encodedGlobalPreferences);
    545552#endif
    546553#endif
  • trunk/Source/WebKit/Shared/WebProcessCreationParameters.h

    r260798 r260840  
    232232#if ENABLE(CFPREFS_DIRECT_MODE)
    233233    Optional<SandboxExtension::HandleArray> preferencesExtensionHandles;
     234    String encodedGlobalPreferences;
    234235#endif
    235236#endif
  • trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm

    r260832 r260840  
    455455    }
    456456
    457 #if ENABLE(CFPREFS_DIRECT_MODE) && PLATFORM(IOS_FAMILY)
     457#if ENABLE(CFPREFS_DIRECT_MODE)
     458#if PLATFORM(IOS_FAMILY)
    458459    if (_AXSApplicationAccessibilityEnabled()) {
    459460        SandboxExtension::HandleArray preferencesExtensionHandles;
     
    473474    }
    474475#endif
     476
     477    auto globalPreferencesDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr));
     478    static CFStringRef keys[] = {
     479        CFSTR("AppleLanguages"),
     480        CFSTR("AppleLanguagesSchemaVersion"),
     481        CFSTR("AppleLocale")
     482    };
     483    for (size_t i = 0; i < std::size(keys); ++i) {
     484        auto value = adoptCF(CFPreferencesCopyAppValue(keys[i], CFSTR("kCFPreferencesAnyApplication")));
     485        if (!value)
     486            continue;
     487        CFDictionaryAddValue(globalPreferencesDictionary.get(), keys[i], value.get());
     488    }
     489    if (CFDictionaryGetCount(globalPreferencesDictionary.get()) > 0) {
     490        NSError *e = nil;
     491        auto data = retainPtr([NSKeyedArchiver archivedDataWithRootObject:(__bridge NSMutableDictionary *)globalPreferencesDictionary.get() requiringSecureCoding:YES error:&e]);
     492        if (e) {
     493            ASSERT_NOT_REACHED();
     494            WTFLogAlways("Failed to archive global preferences dictionary with NSKeyedArchiver.");
     495        } else
     496            parameters.encodedGlobalPreferences = String([data base64EncodedStringWithOptions:0]);
     497    }
     498#endif
    475499}
    476500
  • trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm

    r260798 r260840  
    166166#endif
    167167
     168#if ENABLE(CFPREFS_DIRECT_MODE)
     169static void setGlobalPreferences(const String& encodedGlobalPreferences)
     170{
     171    if (encodedGlobalPreferences.isEmpty())
     172        return;
     173
     174    auto encodedData = adoptNS([[NSData alloc] initWithBase64EncodedString:encodedGlobalPreferences options:0]);
     175    if (!encodedData)
     176        return;
     177
     178    NSError *err = nil;
     179    auto classes = [NSSet setWithArray:@[[NSString class], [NSNumber class], [NSDate class], [NSDictionary class], [NSArray class], [NSData class]]];
     180    id globalPreferencesDictionary = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:encodedData.get() error:&err];
     181    if (err) {
     182        ASSERT_NOT_REACHED();
     183        WTFLogAlways("Failed to unarchive global preferences dictionary with NSKeyedUnarchiver.");
     184        return;
     185    }
     186    [globalPreferencesDictionary enumerateKeysAndObjectsUsingBlock: ^(NSString *key, id value, BOOL* stop) {
     187        if (value)
     188            CFPreferencesSetAppValue(static_cast<CFStringRef>(key), static_cast<CFPropertyListRef>(value), CFSTR("kCFPreferencesAnyApplication"));
     189    }];
     190}
     191#endif
     192
    168193void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
    169194{
     195#if ENABLE(CFPREFS_DIRECT_MODE)
     196    setGlobalPreferences(parameters.encodedGlobalPreferences);
     197#endif
     198
    170199    // Map Launch Services database. This should be done as early as possible, as the mapping will fail
    171200    // if 'com.apple.lsd.mapdb' is being accessed before this.
     
    179208        ASSERT_UNUSED(ok, ok);
    180209    }
    181 
    182210
    183211#if PLATFORM(IOS_FAMILY)
  • trunk/Tools/ChangeLog

    r260837 r260840  
     12020-04-28  Per Arne Vollan  <pvollan@apple.com>
     2
     3        [Cocoa] Global preferences are not accessible in the WebContent process when CFPrefs direct mode is enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=211075
     5
     6        Reviewed by Brent Fulgham.
     7
     8        * TestWebKitAPI/Tests/WebKit/PreferenceChanges.mm:
     9        (TEST):
     10
    1112020-04-28  Jonathan Bedard  <jbedard@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/PreferenceChanges.mm

    r260366 r260840  
    277277}
    278278
     279TEST(WebKit, GlobalPreferences)
     280{
     281    NSString *globalDomain = @"kCFPreferencesAnyApplication";
     282    NSString *globalKey = @"AppleLanguages";
     283
     284    NSArray *languages = @[@"en-US", @"nb-US"];
     285
     286    CFPreferencesSetAppValue(static_cast<CFStringRef>(globalKey), static_cast<CFArrayRef>(languages), static_cast<CFStringRef>(globalDomain));
     287
     288    auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:globalDomain]);
     289    [userDefaults.get() setObject:languages forKey:globalKey];
     290
     291    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     292    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     293    configuration.get().processPool = (WKProcessPool *)context.get();
     294    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     295
     296    auto preferenceValue = [&] {
     297        NSString *js = [NSString stringWithFormat:@"window.internals.encodedPreferenceValue(\"%@\",\"%@\")", globalDomain, globalKey];
     298        return [webView stringByEvaluatingJavaScript:js];
     299    };
     300
     301    auto encodedString = preferenceValue();
     302    auto encodedData = adoptNS([[NSData alloc] initWithBase64EncodedString:encodedString options:0]);
     303    ASSERT_TRUE(encodedData);
     304    NSError *err = nil;
     305    auto object = retainPtr([NSKeyedUnarchiver unarchivedObjectOfClass:[NSObject class] fromData:encodedData.get() error:&err]);
     306    ASSERT_TRUE(!err);
     307    ASSERT_TRUE(object);
     308    ASSERT_TRUE([object isEqual:languages]);
     309}
     310
    279311#endif // WK_HAVE_C_SPI
Note: See TracChangeset for help on using the changeset viewer.