Diff
Modified: trunk/LayoutTests/ChangeLog (236347 => 236348)
--- trunk/LayoutTests/ChangeLog 2018-09-21 19:55:57 UTC (rev 236347)
+++ trunk/LayoutTests/ChangeLog 2018-09-21 19:59:40 UTC (rev 236348)
@@ -1,3 +1,16 @@
+2018-09-21 Chris Dumez <[email protected]>
+
+ WebSQL: User cannot grant quota increase if the JS provides an expected usage value that is too low
+ https://bugs.webkit.org/show_bug.cgi?id=189801
+ <rdar://problem/43592498>
+
+ Reviewed by Youenn Fablet.
+
+ Add layout test coverage.
+
+ * storage/websql/transaction-database-expand-quota-expected.txt: Added.
+ * storage/websql/transaction-database-expand-quota.html: Added.
+
2018-09-21 Youenn Fablet <[email protected]>
Add RTCCodecStats support
Added: trunk/LayoutTests/storage/websql/transaction-database-expand-quota-expected.txt (0 => 236348)
--- trunk/LayoutTests/storage/websql/transaction-database-expand-quota-expected.txt (rev 0)
+++ trunk/LayoutTests/storage/websql/transaction-database-expand-quota-expected.txt 2018-09-21 19:59:40 UTC (rev 236348)
@@ -0,0 +1,14 @@
+UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{file, , 0} database:ExpandedQuotaTransaction
+UI DELEGATE DATABASE CALLBACK: increased quota to 6291456
+UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{file, , 0} database:ExpandedQuotaTransaction
+UI DELEGATE DATABASE CALLBACK: increased quota to 11534336
+Check that a quota increase is granted, even if the provided expected size is too low.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Successfully wrote data
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/storage/websql/transaction-database-expand-quota.html (0 => 236348)
--- trunk/LayoutTests/storage/websql/transaction-database-expand-quota.html (rev 0)
+++ trunk/LayoutTests/storage/websql/transaction-database-expand-quota.html 2018-09-21 19:59:40 UTC (rev 236348)
@@ -0,0 +1,68 @@
+<html>
+<head>
+<script src=""
+</head>
+<body _onload_="runTest()">
+<script>
+description("Check that a quota increase is granted, even if the provided expected size is too low.");
+jsTestIsAsync = true;
+
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.clearAllDatabases();
+ testRunner.dumpDatabaseCallbacks();
+ testRunner.databaseDefaultQuota = 5 * 1024 * 1024;
+ testRunner.databaseMaxQuota = 50 * 1024 * 1024;
+}
+
+let db;
+
+const dataSize = 8 * 1024 * 1024; // 8 MB.
+let largeData = "";
+for (let i = 0; i < dataSize; i++)
+ largeData += "x";
+
+let isFirstAttempt = true;
+
+function writeData()
+{
+ db.transaction((tx) => {
+ let id = 1;
+ tx.executeSql('INSERT INTO foo (id, text) VALUES (?, ?)', [id, largeData]);
+ }, (error) => {
+ if (isFirstAttempt && error.code == SQLError.QUOTA_ERR) {
+ isFirstAttempt = false;
+ setTimeout(writeData, 0);
+ return;
+ }
+ testFailed("Failed to write data: " + error.code + ": " + error.message);
+ finishJSTest();
+ }, () => {
+ testPassed("Successfully wrote data");
+ finishJSTest();
+ });
+}
+
+function runTest() {
+ try {
+ db = openDatabase('ExpandedQuotaTransaction', '', '', 6 * 1024 * 1024);
+ } catch (err) {
+ testFailed("Failed to open the database");
+ finishJSTest();
+ return;
+ }
+
+ db.transaction((tx) => {
+ tx.executeSql('CREATE TABLE foo (id unique, text)');
+ }, (error) => {
+ testFailed("Failed to create table: " + error.code + ": " + error.message);
+ finishJSTest();
+ }, () => {
+ writeData();
+ });
+}
+
+_onload_ = runTest;
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (236347 => 236348)
--- trunk/Source/WebCore/ChangeLog 2018-09-21 19:55:57 UTC (rev 236347)
+++ trunk/Source/WebCore/ChangeLog 2018-09-21 19:59:40 UTC (rev 236348)
@@ -1,3 +1,29 @@
+2018-09-21 Chris Dumez <[email protected]>
+
+ WebSQL: User cannot grant quota increase if the JS provides an expected usage value that is too low
+ https://bugs.webkit.org/show_bug.cgi?id=189801
+ <rdar://problem/43592498>
+
+ Reviewed by Youenn Fablet.
+
+ User was unable to grant a quota increase for WebSQL if the JS provided an expected usage value that
+ is too low. This is because WebKit was passing this provided expectedUsage value to the client for
+ the purpose of quota increase, even when this expectedUsage value does not make any sense (i.e. it
+ is lower than the current database size). As a result, the client would grant a quota that is equal
+ to the previous quota and the JS would not be able to insert any data.
+
+ In order to address the issue, when the current quota is exceeded and Database::didExceedQuota()
+ is called, we now make sure that the expectedUsage value is greater than the current quota. If it
+ is not, we provide `current quota + 5MB` as expected usage to the client. This way, the client will
+ grant a quota that is actually increased (provided that the user accepts).
+
+ Test: storage/websql/transaction-database-expand-quota.html
+
+ * Modules/webdatabase/Database.cpp:
+ (WebCore::Database::setEstimatedSize):
+ (WebCore::Database::didExceedQuota):
+ * Modules/webdatabase/Database.h:
+
2018-09-21 Youenn Fablet <[email protected]>
Use biplanar CVPixelBuffer for black frames sent to libwebrtc
Modified: trunk/Source/WebCore/Modules/webdatabase/Database.cpp (236347 => 236348)
--- trunk/Source/WebCore/Modules/webdatabase/Database.cpp 2018-09-21 19:55:57 UTC (rev 236347)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.cpp 2018-09-21 19:59:40 UTC (rev 236348)
@@ -90,6 +90,7 @@
static const char versionKey[] = "WebKitDatabaseVersionKey";
static const char unqualifiedInfoTableName[] = "__WebKitDatabaseInfoTable__";
+const unsigned long long quotaIncreaseSize = 5 * 1024 * 1024;
static const char* fullyQualifiedInfoTableName()
{
@@ -191,7 +192,7 @@
}).iterator->value;
}
-Database::Database(DatabaseContext& context, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize)
+Database::Database(DatabaseContext& context, const String& name, const String& expectedVersion, const String& displayName, unsigned long long estimatedSize)
: m_scriptExecutionContext(*context.scriptExecutionContext())
, m_contextThreadSecurityOrigin(m_scriptExecutionContext->securityOrigin()->isolatedCopy())
, m_databaseThreadSecurityOrigin(m_scriptExecutionContext->securityOrigin()->isolatedCopy())
@@ -617,11 +618,17 @@
return m_displayName.isolatedCopy();
}
-unsigned Database::estimatedSize() const
+unsigned long long Database::estimatedSize() const
{
return m_estimatedSize;
}
+void Database::setEstimatedSize(unsigned long long estimatedSize)
+{
+ m_estimatedSize = estimatedSize;
+ DatabaseTracker::singleton().setDatabaseDetails(securityOrigin(), m_name, m_displayName, m_estimatedSize);
+}
+
String Database::fileName() const
{
// Return a deep copy for ref counting thread safety
@@ -788,6 +795,11 @@
ASSERT(databaseContext().scriptExecutionContext()->isContextThread());
auto& tracker = DatabaseTracker::singleton();
auto oldQuota = tracker.quota(securityOrigin());
+ if (estimatedSize() <= oldQuota) {
+ // The expected usage provided by the page is now smaller than the actual database size so we bump the expected usage to
+ // oldQuota + 5MB so that the client actually increases the quota.
+ setEstimatedSize(oldQuota + quotaIncreaseSize);
+ }
databaseContext().databaseExceededQuota(stringIdentifier(), details());
return tracker.quota(securityOrigin()) > oldQuota;
}
Modified: trunk/Source/WebCore/Modules/webdatabase/Database.h (236347 => 236348)
--- trunk/Source/WebCore/Modules/webdatabase/Database.h 2018-09-21 19:55:57 UTC (rev 236347)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.h 2018-09-21 19:59:40 UTC (rev 236348)
@@ -88,7 +88,7 @@
// Internal engine support
String stringIdentifier() const;
String displayName() const;
- unsigned estimatedSize() const;
+ unsigned long long estimatedSize() const;
String fileName() const;
DatabaseDetails details() const;
SQLiteDatabase& sqliteDatabase() { return m_sqliteDatabase; }
@@ -126,7 +126,7 @@
void performClose();
private:
- Database(DatabaseContext&, const String& name, const String& expectedVersion, const String& displayName, unsigned estimatedSize);
+ Database(DatabaseContext&, const String& name, const String& expectedVersion, const String& displayName, unsigned long long estimatedSize);
void closeDatabase();
@@ -137,6 +137,7 @@
String getCachedVersion() const;
void setCachedVersion(const String&);
bool getActualVersionForTransaction(String& version);
+ void setEstimatedSize(unsigned long long);
void scheduleTransaction();
@@ -157,7 +158,7 @@
String m_name;
String m_expectedVersion;
String m_displayName;
- unsigned m_estimatedSize;
+ unsigned long long m_estimatedSize;
String m_filename;
DatabaseGUID m_guid;
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp (236347 => 236348)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp 2018-09-21 19:55:57 UTC (rev 236347)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp 2018-09-21 19:59:40 UTC (rev 236348)
@@ -136,7 +136,7 @@
}
}
-ExceptionOr<void> DatabaseTracker::hasAdequateQuotaForOrigin(const SecurityOriginData& origin, unsigned estimatedSize)
+ExceptionOr<void> DatabaseTracker::hasAdequateQuotaForOrigin(const SecurityOriginData& origin, unsigned long long estimatedSize)
{
ASSERT(!m_databaseGuard.tryLock());
auto usage = this->usage(origin);
@@ -152,7 +152,7 @@
return { };
}
-ExceptionOr<void> DatabaseTracker::canEstablishDatabase(DatabaseContext& context, const String& name, unsigned estimatedSize)
+ExceptionOr<void> DatabaseTracker::canEstablishDatabase(DatabaseContext& context, const String& name, unsigned long long estimatedSize)
{
LockHolder lockDatabase(m_databaseGuard);
@@ -200,7 +200,7 @@
// hasAdequateQuotaForOrigin() simple and correct (i.e. bug free), and just
// re-use it. Also note that the path for opening a database involves IO, and
// hence should not be a performance critical path anyway.
-ExceptionOr<void> DatabaseTracker::retryCanEstablishDatabase(DatabaseContext& context, const String& name, unsigned estimatedSize)
+ExceptionOr<void> DatabaseTracker::retryCanEstablishDatabase(DatabaseContext& context, const String& name, unsigned long long estimatedSize)
{
LockHolder lockDatabase(m_databaseGuard);
@@ -476,7 +476,7 @@
return DatabaseDetails(name, displayName, expectedUsage, SQLiteFileSystem::getDatabaseFileSize(path), SQLiteFileSystem::databaseCreationTime(path), SQLiteFileSystem::databaseModificationTime(path));
}
-void DatabaseTracker::setDatabaseDetails(const SecurityOriginData& origin, const String& name, const String& displayName, unsigned estimatedSize)
+void DatabaseTracker::setDatabaseDetails(const SecurityOriginData& origin, const String& name, const String& displayName, unsigned long long estimatedSize)
{
String originIdentifier = origin.databaseIdentifier();
int64_t guid = 0;
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h (236347 => 236348)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h 2018-09-21 19:55:57 UTC (rev 236347)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseTracker.h 2018-09-21 19:59:40 UTC (rev 236348)
@@ -66,10 +66,10 @@
// m_databaseGuard and m_openDatabaseMapGuard currently don't overlap.
// notificationMutex() is currently independent of the other locks.
- ExceptionOr<void> canEstablishDatabase(DatabaseContext&, const String& name, unsigned estimatedSize);
- ExceptionOr<void> retryCanEstablishDatabase(DatabaseContext&, const String& name, unsigned estimatedSize);
+ ExceptionOr<void> canEstablishDatabase(DatabaseContext&, const String& name, unsigned long long estimatedSize);
+ ExceptionOr<void> retryCanEstablishDatabase(DatabaseContext&, const String& name, unsigned long long estimatedSize);
- void setDatabaseDetails(const SecurityOriginData&, const String& name, const String& displayName, unsigned estimatedSize);
+ void setDatabaseDetails(const SecurityOriginData&, const String& name, const String& displayName, unsigned long long estimatedSize);
WEBCORE_EXPORT String fullPathForDatabase(const SecurityOriginData&, const String& name, bool createIfDoesNotExist);
void addOpenDatabase(Database&);
@@ -117,7 +117,7 @@
private:
explicit DatabaseTracker(const String& databasePath);
- ExceptionOr<void> hasAdequateQuotaForOrigin(const SecurityOriginData&, unsigned estimatedSize);
+ ExceptionOr<void> hasAdequateQuotaForOrigin(const SecurityOriginData&, unsigned long long estimatedSize);
bool hasEntryForOriginNoLock(const SecurityOriginData&);
String fullPathForDatabaseNoLock(const SecurityOriginData&, const String& name, bool createIfDoesNotExist);