r255318 introduced a change to how IDB Indexes are stored in the SQLite backing store. It moves from per-ObjectStore index IDs to per-Database index IDs, and attempts to perform a migration. This migration is run on iOS 14 when launching an app whose WKWebView IndexedDB databases were created on iOS 13.
There's a flaw in the migration process that can result in multiple indexes being updated to have the same ID, and corrupting the associated IndexRecords data. Once this happens, it appears to be impossible to recover the correct indexes.
A detailed walkthrough of how this happens to the IDB indices in our app can be found here: https://gist.github.com/dpogue/53d529310355697a0bfdf17644a17840
It only happens in some pretty specific situations, but it's a pretty serious problem.
Thanks for reporting! This is pretty bad since the corrupted records cannot be recovered.
Created attachment 409726 [details]
Here's a testcase file which can be used to demonstrate the problem.
I ran this in an iOS simulator on iOS 13.5 and opened it in Safari, then used `xcrun simctl upgrade` to upgrade the simulator to iOS 14.0 and opened it again. Looking at it with the Safari Inspector shows that one of the indexes is now missing.
Created attachment 409900 [details]
Created attachment 409924 [details]
Comment on attachment 409924 [details]
View in context: https://bugs.webkit.org/attachment.cgi?id=409924&action=review
> +static String indexInfoTableSchema(const String& tableName)
This argument should be ASCIILiteral or const char*, not const String&. It’s wastefully inefficient to turn an ASCII literal into a String and then destroy that string.
I tested this patch in both Safari and in my WKWebView-based app on the iOS simulator, and the corruption was fixed in both cases.
Thanks Sihui for jumping on this! :)
Created attachment 409928 [details]
(In reply to Darin Adler from comment #6)
> Comment on attachment 409924 [details]
> View in context:
> > Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:242
> > +static String indexInfoTableSchema(const String& tableName)
> This argument should be ASCIILiteral or const char*, not const String&. It’s
> wastefully inefficient to turn an ASCII literal into a String and then
> destroy that string.
Right, changed to use ASCIILiteral.
Committed r267753: <https://trac.webkit.org/changeset/267753>
All reviewed patches have been landed. Closing bug and clearing flags on attachment 409928 [details].