Changeset 249035 in webkit


Ignore:
Timestamp:
Aug 22, 2019 4:28:45 PM (5 years ago)
Author:
Chris Dumez
Message:

Try to recover nicely when getting an unexpected schema in the service workers database
https://bugs.webkit.org/show_bug.cgi?id=201002
<rdar://problem/54574991>

Reviewed by Youenn Fablet.

Source/WebCore:

Try to recover nicely when getting an unexpected schema in the service workers database instead
of crashing the network process. To recover, we delete the database file and re-create it.

  • workers/service/server/RegistrationDatabase.cpp:

(WebCore::RegistrationDatabase::openSQLiteDatabase):
(WebCore::RegistrationDatabase::ensureValidRecordsTable):

Tools:

Add API test coverage.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
Location:
trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r249026 r249035  
     12019-08-22  Chris Dumez  <cdumez@apple.com>
     2
     3        Try to recover nicely when getting an unexpected schema in the service workers database
     4        https://bugs.webkit.org/show_bug.cgi?id=201002
     5        <rdar://problem/54574991>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        Try to recover nicely when getting an unexpected schema in the service workers database instead
     10        of crashing the network process. To recover, we delete the database file and re-create it.
     11
     12        * workers/service/server/RegistrationDatabase.cpp:
     13        (WebCore::RegistrationDatabase::openSQLiteDatabase):
     14        (WebCore::RegistrationDatabase::ensureValidRecordsTable):
     15
    1162019-08-22  Said Abou-Hallawa  <sabouhallawa@apple.com>
    217
  • trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp

    r248967 r249035  
    136136    LOG(ServiceWorker, "ServiceWorker RegistrationDatabase opening file %s", fullFilename.utf8().data());
    137137
    138     String errorMessage;
    139     auto scopeExit = makeScopeExit([this, protectedThis = makeRef(*this), errorMessage = &errorMessage] {
    140         ASSERT_UNUSED(errorMessage, !errorMessage->isNull());
    141 
    142 #if RELEASE_LOG_DISABLED
    143         LOG_ERROR("Failed to open Service Worker registration database: %s", errorMessage->utf8().data());
    144 #else
    145         RELEASE_LOG_ERROR(ServiceWorker, "Failed to open Service Worker registration database: %{public}s", errorMessage->utf8().data());
    146 #endif
    147 
    148         m_database = nullptr;
    149         callOnMainThread([protectedThis = protectedThis.copyRef()] {
    150             protectedThis->databaseFailedToOpen();
    151         });
    152     });
    153 
    154138    SQLiteFileSystem::ensureDatabaseDirectoryExists(databaseDirectory);
    155139
    156140    m_database = makeUnique<SQLiteDatabase>();
    157141    if (!m_database->open(fullFilename)) {
    158         errorMessage = "Failed to open registration database";
     142        RELEASE_LOG_ERROR(ServiceWorker, "Failed to open Service Worker registration database");
     143        m_database = nullptr;
     144        callOnMainThread([this, protectedThis = makeRef(*this)] {
     145            databaseFailedToOpen();
     146        });
    159147        return;
    160148    }
     
    165153    m_database->disableThreadingChecks();
    166154   
    167     errorMessage = ensureValidRecordsTable();
    168     if (!errorMessage.isNull())
     155    auto doRecoveryAttempt = [&] {
     156        // Delete the database and re-create it.
     157        m_database = nullptr;
     158        SQLiteFileSystem::deleteDatabaseFile(fullFilename);
     159        openSQLiteDatabase(fullFilename);
     160    };
     161   
     162    String errorMessage = ensureValidRecordsTable();
     163    if (!errorMessage.isNull()) {
     164        RELEASE_LOG_ERROR(ServiceWorker, "ensureValidRecordsTable failed, reason: %{public}s", errorMessage.utf8().data());
     165        doRecoveryAttempt();
    169166        return;
     167    }
    170168   
    171169    errorMessage = importRecords();
    172     if (!errorMessage.isNull())
     170    if (!errorMessage.isNull()) {
     171        RELEASE_LOG_ERROR(ServiceWorker, "importRecords failed, reason: %{public}s", errorMessage.utf8().data());
     172        doRecoveryAttempt();
    173173        return;
    174 
    175     scopeExit.release();
     174    }
    176175}
    177176
     
    221220        return { };
    222221
    223     // This database has a Records table but it is not a schema we expect.
    224     // Trying to recover by deleting the data contained within is dangerous so
    225     // we should consider this an unrecoverable error.
    226     RELEASE_ASSERT_NOT_REACHED();
     222    return makeString("Unexpected schema: ", currentSchema);
    227223}
    228224
  • trunk/Tools/ChangeLog

    r249033 r249035  
     12019-08-22  Chris Dumez  <cdumez@apple.com>
     2
     3        Try to recover nicely when getting an unexpected schema in the service workers database
     4        https://bugs.webkit.org/show_bug.cgi?id=201002
     5        <rdar://problem/54574991>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        Add API test coverage.
     10
     11        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     12        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
     13
    1142019-08-22  Keith Rollin  <krollin@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r248966 r249035  
    219219                46397B951DC2C850009A78AE /* DOMNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 46397B941DC2C850009A78AE /* DOMNode.mm */; };
    220220                4647B1261EBA3B850041D7EF /* ProcessDidTerminate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4647B1251EBA3B730041D7EF /* ProcessDidTerminate.cpp */; };
     221                464C764D230DF85C00AFB020 /* BadServiceWorkerRegistrations-4.sqlite3 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 464C764C230DF83200AFB020 /* BadServiceWorkerRegistrations-4.sqlite3 */; };
    221222                466C3843210637DE006A88DE /* notify-resourceLoadObserver.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 466C3842210637CE006A88DE /* notify-resourceLoadObserver.html */; };
    222223                467C565321B5ED130057516D /* GetSessionCookie.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 467C565121B5ECDF0057516D /* GetSessionCookie.html */; };
     
    11481149                                2E14A5291D3FE96B0010F35B /* autoplaying-video-with-audio.html in Copy Resources */,
    11491150                                F41AB9A01EF4696B0083FA08 /* background-image-link-and-input.html in Copy Resources */,
     1151                                464C764D230DF85C00AFB020 /* BadServiceWorkerRegistrations-4.sqlite3 in Copy Resources */,
    11501152                                2DE71B001D49C3ED00904094 /* blinking-div.html in Copy Resources */,
    11511153                                7C486BA11AA12567003F6F9B /* bundle-file.html in Copy Resources */,
     
    16911693                46397B941DC2C850009A78AE /* DOMNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMNode.mm; sourceTree = "<group>"; };
    16921694                4647B1251EBA3B730041D7EF /* ProcessDidTerminate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessDidTerminate.cpp; sourceTree = "<group>"; };
     1695                464C764C230DF83200AFB020 /* BadServiceWorkerRegistrations-4.sqlite3 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "BadServiceWorkerRegistrations-4.sqlite3"; sourceTree = "<group>"; };
    16931696                4656A75720F9054F0002E21F /* SimpleServiceWorkerRegistrations-4.sqlite3 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SimpleServiceWorkerRegistrations-4.sqlite3"; sourceTree = "<group>"; };
    16941697                466C3842210637CE006A88DE /* notify-resourceLoadObserver.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "notify-resourceLoadObserver.html"; sourceTree = "<group>"; };
     
    31533156                                2E14A5281D3FE8B80010F35B /* autoplaying-video-with-audio.html */,
    31543157                                F41AB9971EF4692C0083FA08 /* background-image-link-and-input.html */,
     3158                                464C764C230DF83200AFB020 /* BadServiceWorkerRegistrations-4.sqlite3 */,
    31553159                                2DE71AFF1D49C2F000904094 /* blinking-div.html */,
    31563160                                2EFF06C41D8867700004BB30 /* change-video-source-on-click.html */,
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm

    r245327 r249035  
    18671867    EXPECT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:swDBPath.path]);
    18681868}
     1869
     1870TEST(WebKit, ServiceWorkerDatabaseWithRecordsTableButUnexpectedSchema)
     1871{
     1872    // Copy the baked database files to the database directory
     1873    NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"BadServiceWorkerRegistrations-4" withExtension:@"sqlite3" subdirectory:@"TestWebKitAPI.resources"];
     1874
     1875    NSURL *swPath = [NSURL fileURLWithPath:[@"~/Library/Caches/TestWebKitAPI/WebKit/ServiceWorkers/" stringByExpandingTildeInPath]];
     1876    [[NSFileManager defaultManager] removeItemAtURL:swPath error:nil];
     1877    EXPECT_FALSE([[NSFileManager defaultManager] fileExistsAtPath:swPath.path]);
     1878
     1879    [[NSFileManager defaultManager] createDirectoryAtURL:swPath withIntermediateDirectories:YES attributes:nil error:nil];
     1880    [[NSFileManager defaultManager] copyItemAtURL:url1 toURL:[swPath URLByAppendingPathComponent:@"ServiceWorkerRegistrations-4.sqlite3"] error:nil];
     1881
     1882    auto websiteDataStoreConfiguration = adoptNS([[_WKWebsiteDataStoreConfiguration alloc] init]);
     1883    websiteDataStoreConfiguration.get()._serviceWorkerRegistrationDirectory = swPath;
     1884    auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:websiteDataStoreConfiguration.get()]);
     1885
     1886    // Fetch SW records
     1887    auto websiteDataTypes = adoptNS([[NSSet alloc] initWithArray:@[WKWebsiteDataTypeServiceWorkerRegistrations]]);
     1888    static bool readyToContinue;
     1889    [dataStore fetchDataRecordsOfTypes:websiteDataTypes.get() completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
     1890        EXPECT_EQ(0U, dataRecords.count);
     1891        readyToContinue = true;
     1892    }];
     1893    TestWebKitAPI::Util::run(&readyToContinue);
     1894    readyToContinue = false;
     1895}
Note: See TracChangeset for help on using the changeset viewer.