From 8f76be2adb3db06597b54ee0803975fdcd9bbc86 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Wed, 23 Oct 2024 15:58:17 +0100 Subject: [PATCH 01/11] target sdk 35 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 27eebf63bd0b..f5d81b18fb4c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,8 +5,8 @@ buildscript { ext { min_sdk = 26 - target_sdk = 34 - compile_sdk = 34 + target_sdk = 35 + compile_sdk = 35 // Calculate lint_version (must always be gradle_plugin + 23) def gradle_plugin_version = versionFor(project, Android.tools.build.gradlePlugin) From d70abeb32f9a00d856371865a9f8eccffe4e7605 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Wed, 7 Aug 2024 14:43:26 +0100 Subject: [PATCH 02/11] Required code changes --- .../java/com/duckduckgo/app/browser/BrowserTabFragment.kt | 2 +- .../certificate/SigningCertificateHashExtractor.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index 8118b1449597..067648e3aa8b 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -2023,7 +2023,7 @@ class BrowserTabFragment : private fun launchDialogForIntent( context: Context, - pm: PackageManager?, + pm: PackageManager, intent: Intent, activities: List, useFirstActivityFound: Boolean, diff --git a/verified-installation/verified-installation-impl/src/main/java/com/duckduckgo/verifiedinstallation/certificate/SigningCertificateHashExtractor.kt b/verified-installation/verified-installation-impl/src/main/java/com/duckduckgo/verifiedinstallation/certificate/SigningCertificateHashExtractor.kt index ebb86791c3b4..0efb7adff202 100644 --- a/verified-installation/verified-installation-impl/src/main/java/com/duckduckgo/verifiedinstallation/certificate/SigningCertificateHashExtractor.kt +++ b/verified-installation/verified-installation-impl/src/main/java/com/duckduckgo/verifiedinstallation/certificate/SigningCertificateHashExtractor.kt @@ -69,11 +69,11 @@ class SigningCertificateHashExtractorImpl @Inject constructor( return null } - if (info.signingInfo.signingCertificateHistory.size != 1) { + if (info.signingInfo!!.signingCertificateHistory.size != 1) { return null } - return info.signingInfo.signingCertificateHistory?.lastOrNull()?.sha256() + return info.signingInfo!!.signingCertificateHistory?.lastOrNull()?.sha256() } private fun Signature.sha256(): String { From 8c59d55b66fea47ba69f706a42f8d0ea188f8920 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Wed, 23 Oct 2024 18:10:49 +0100 Subject: [PATCH 03/11] turn off edgetoedge enforcement we can tackle this at a later date --- .../res/values-v35/design-system-theming.xml | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 common/common-ui/src/main/res/values-v35/design-system-theming.xml diff --git a/common/common-ui/src/main/res/values-v35/design-system-theming.xml b/common/common-ui/src/main/res/values-v35/design-system-theming.xml new file mode 100644 index 000000000000..356887ea163f --- /dev/null +++ b/common/common-ui/src/main/res/values-v35/design-system-theming.xml @@ -0,0 +1,31 @@ + + + + + + + + + From a0d6e46813277ed273f44182155a3d9680607e86 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Fri, 25 Oct 2024 12:26:08 +0100 Subject: [PATCH 04/11] update SQLCipher dependency The dependency has moved to a new repo: https://github.com/sqlcipher/sqlcipher-android --- autofill/autofill-impl/build.gradle | 2 +- versions.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/autofill/autofill-impl/build.gradle b/autofill/autofill-impl/build.gradle index 6e5dc612d6db..4baf934b90dc 100644 --- a/autofill/autofill-impl/build.gradle +++ b/autofill/autofill-impl/build.gradle @@ -71,7 +71,7 @@ dependencies { implementation AndroidX.room.ktx implementation AndroidX.biometric - implementation "net.zetetic:android-database-sqlcipher:_" + implementation "net.zetetic:sqlcipher-android:_" implementation "com.facebook.shimmer:shimmer:_" // Testing dependencies diff --git a/versions.properties b/versions.properties index 0ea6b052d5c3..e1100fc2391d 100644 --- a/versions.properties +++ b/versions.properties @@ -121,9 +121,9 @@ version.mockito=5.13.0 version.moshi=1.8.0 -version.okhttp3=4.12.0 +version.net.zetetic..sqlcipher-android=4.6.1 -version.net.zetetic..android-database-sqlcipher=4.5.4 +version.okhttp3=4.12.0 version.okio=3.9.0 From c688c5f38a650c717501d7d65b285344834e2b2a Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Fri, 25 Oct 2024 12:26:50 +0100 Subject: [PATCH 05/11] migrate SQLCipher code SupportFactory -> SupportOpenHelperFactory --- .../impl/securestorage/SecureStorageDatabaseFactory.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt index 19c2dcc3a87b..650d40e88145 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt @@ -23,8 +23,8 @@ import com.duckduckgo.securestorage.store.db.ALL_MIGRATIONS import com.duckduckgo.securestorage.store.db.SecureStorageDatabase import com.squareup.anvil.annotations.ContributesBinding import dagger.SingleInstanceIn +import net.zetetic.database.sqlcipher.SupportOpenHelperFactory import javax.inject.Inject -import net.sqlcipher.database.SupportFactory interface SecureStorageDatabaseFactory { fun getDatabase(): SecureStorageDatabase? @@ -52,7 +52,7 @@ class RealSecureStorageDatabaseFactory @Inject constructor( context, SecureStorageDatabase::class.java, "secure_storage_database_encrypted.db", - ).openHelperFactory(SupportFactory(keyProvider.getl1Key())) + ).openHelperFactory(SupportOpenHelperFactory(keyProvider.getl1Key())) .addMigrations(*ALL_MIGRATIONS) .build() _database From 8917aaef69fde0f976c7d7c27169730281822e5e Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Fri, 25 Oct 2024 14:43:04 +0100 Subject: [PATCH 06/11] remove deprecated databaseEnabled It's false by default and was only added as protection. Since SQLCipher has supported sqlite 3.26.0 since 4.0.1 (released 2018) this should no longer be a concern in my opinion: https://www.zetetic.net/blog/2018/12/18/sqlcipher-401-release/ --- .../java/com/duckduckgo/app/browser/BrowserTabFragment.kt | 8 -------- .../app/browser/urlextraction/UrlExtractingWebView.kt | 8 -------- .../subscriptions/impl/ui/SubscriptionsWebViewActivity.kt | 1 - 3 files changed, 17 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index 067648e3aa8b..0a56fccef0be 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -2487,7 +2487,6 @@ class BrowserTabFragment : mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE javaScriptCanOpenWindowsAutomatically = appBuildConfig.isTest // only allow when running tests setSupportMultipleWindows(true) - disableWebSql(this) setSupportZoom(true) if (accessibilitySettingsDataStore.overrideSystemFontSize) { textZoom = accessibilitySettingsDataStore.fontSize.toInt() @@ -2872,13 +2871,6 @@ class BrowserTabFragment : binding.swipeRefreshContainer.progressViewStartOffset -= 15 } - /** - * Explicitly disable database to try protect against Magellan WebSQL/SQLite vulnerability - */ - private fun disableWebSql(settings: WebSettings) { - settings.databaseEnabled = false - } - @Suppress("NewApi") // This API and the behaviour described only apply to apps with targetSdkVersion ≥ TIRAMISU. private fun setAlgorithmicDarkeningAllowed(settings: WebSettings) { // https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setAlgorithmicDarkeningAllowed(android.webkit.WebSettings,boolean) diff --git a/app/src/main/java/com/duckduckgo/app/browser/urlextraction/UrlExtractingWebView.kt b/app/src/main/java/com/duckduckgo/app/browser/urlextraction/UrlExtractingWebView.kt index 468bcc0c7d44..1d475ab50e5e 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/urlextraction/UrlExtractingWebView.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/urlextraction/UrlExtractingWebView.kt @@ -40,7 +40,6 @@ class UrlExtractingWebView( javaScriptEnabled = true domStorageEnabled = true mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE - disableWebSql(this) loadsImagesAutomatically = false } setWebViewClient(webViewClient) @@ -54,13 +53,6 @@ class UrlExtractingWebView( } } - /** - * Explicitly disable database to try protect against Magellan WebSQL/SQLite vulnerability - */ - private fun disableWebSql(settings: WebSettings) { - settings.databaseEnabled = false - } - override fun loadUrl(url: String) { initialUrl = url super.loadUrl(url) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt index 2f3154729395..8b16cacd1cdf 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionsWebViewActivity.kt @@ -246,7 +246,6 @@ class SubscriptionsWebViewActivity : DuckDuckGoActivity(), DownloadConfirmationD displayZoomControls = false mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE setSupportMultipleWindows(false) - databaseEnabled = false setSupportZoom(true) } it.setDownloadListener { url, _, contentDisposition, mimeType, _ -> From dbb5f871a594f200fb030ea8f8829b24efd48b00 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Fri, 25 Oct 2024 14:45:11 +0100 Subject: [PATCH 07/11] scouting: remove unused context --- .../mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt index 394ddcd7ea1c..0c69ab97a395 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt @@ -42,7 +42,6 @@ import logcat.logcat ) @SingleInstanceIn(VpnScope::class) class VpnServiceHeartbeat @Inject constructor( - private val context: Context, private val vpnDatabase: VpnDatabase, private val dispatcherProvider: DispatcherProvider, ) : VpnServiceCallbacks { From 4f70752678555d11e3fecaed798201710e2c502c Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Fri, 25 Oct 2024 15:42:51 +0100 Subject: [PATCH 08/11] fix function collisions "The List type in Java is mapped to the MutableList type in Kotlin. Because the List.removeFirst() and List.removeLast() APIs have been introduced in Android 15 (API level 35), the Kotlin compiler resolves function calls, for example list.removeFirst(), statically to the new List APIs instead of to the extension functions in kotlin-stdlib." Robolectric supports 34 right now so easier that we just change these functions. --- .../app/bookmarks/model/SyncSavedSitesRepositoryTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/com/duckduckgo/app/bookmarks/model/SyncSavedSitesRepositoryTest.kt b/app/src/test/java/com/duckduckgo/app/bookmarks/model/SyncSavedSitesRepositoryTest.kt index 75ba9f230a5d..e8733f9c6193 100644 --- a/app/src/test/java/com/duckduckgo/app/bookmarks/model/SyncSavedSitesRepositoryTest.kt +++ b/app/src/test/java/com/duckduckgo/app/bookmarks/model/SyncSavedSitesRepositoryTest.kt @@ -213,7 +213,7 @@ class SyncSavedSitesRepositoryTest { savedSitesRelationsDao.insertList(relation) val removedEntities = entities.toMutableList() - val removedEntity = removedEntities.removeFirst() + val removedEntity = removedEntities.removeAt(0) val removedEntitiesIds = removedEntities.map { it.entityId } val childrenJSON = stringListAdapter.toJson(removedEntitiesIds) @@ -320,7 +320,7 @@ class SyncSavedSitesRepositoryTest { savedSitesRelationsDao.insertList(folderRelation) val updatedChildren = bookmarks.toMutableList() - val removedChildren = updatedChildren.removeFirst() + val removedChildren = updatedChildren.removeAt(0) repository.replaceBookmarkFolder(folder, updatedChildren.map { it.entityId }) From 39982efa3baf47e8f619912bcb02d67101a5200c Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Fri, 25 Oct 2024 15:49:42 +0100 Subject: [PATCH 09/11] rename function and use The function in this class was not used but we can rename it and use it as it uses the removeAt function which we need due to the collision with the stdlib. --- .../com/duckduckgo/app/global/view/ViewChildrenSequences.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/global/view/ViewChildrenSequences.kt b/app/src/main/java/com/duckduckgo/app/global/view/ViewChildrenSequences.kt index 3abba3e768b3..c5c9d6f921aa 100644 --- a/app/src/main/java/com/duckduckgo/app/global/view/ViewChildrenSequences.kt +++ b/app/src/main/java/com/duckduckgo/app/global/view/ViewChildrenSequences.kt @@ -67,7 +67,7 @@ private class ViewChildrenRecursiveSequence(private val view: View) : Sequence { private val sequences = arrayListOf(view.childrenSequence()) - private var current = sequences.removeLast().iterator() + private var current = sequences.removeLastElement().iterator() override fun next(): View { if (!hasNext()) throw NoSuchElementException() @@ -80,13 +80,13 @@ private class ViewChildrenRecursiveSequence(private val view: View) : Sequence MutableList.removeLast(): T { + private inline fun MutableList.removeLastElement(): T { if (isEmpty()) throw NoSuchElementException() return removeAt(size - 1) } From 030138d4ed00895ff3704ca95b711cefc5225a40 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Mon, 28 Oct 2024 16:50:36 +0000 Subject: [PATCH 10/11] formatting --- .../mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt | 1 - .../autofill/impl/securestorage/SecureStorageDatabaseFactory.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt index 0c69ab97a395..06e88fefd47b 100644 --- a/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt +++ b/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/heartbeat/VpnServiceHeartbeat.kt @@ -16,7 +16,6 @@ package com.duckduckgo.mobile.android.vpn.heartbeat -import android.content.Context import android.os.Process import com.duckduckgo.common.utils.ConflatedJob import com.duckduckgo.common.utils.DispatcherProvider diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt index 650d40e88145..9349e508cda4 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/securestorage/SecureStorageDatabaseFactory.kt @@ -23,8 +23,8 @@ import com.duckduckgo.securestorage.store.db.ALL_MIGRATIONS import com.duckduckgo.securestorage.store.db.SecureStorageDatabase import com.squareup.anvil.annotations.ContributesBinding import dagger.SingleInstanceIn -import net.zetetic.database.sqlcipher.SupportOpenHelperFactory import javax.inject.Inject +import net.zetetic.database.sqlcipher.SupportOpenHelperFactory interface SecureStorageDatabaseFactory { fun getDatabase(): SecureStorageDatabase? From ed1c9a8200468aed207fc1381148e5b750d7d352 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Mon, 28 Oct 2024 17:27:19 +0000 Subject: [PATCH 11/11] update robolectric to 4.14 This version supports sdk 35: https://github.com/robolectric/robolectric/releases/tag/robolectric-4.14 --- versions.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.properties b/versions.properties index e1100fc2391d..cea1ac469a0c 100644 --- a/versions.properties +++ b/versions.properties @@ -143,7 +143,7 @@ version.com.jakewharton.retrofit..retrofit2-kotlin-coroutines-adapter=0.9.2 version.androidx.viewpager2=1.1.0 -version.robolectric=4.13 +version.robolectric=4.14 version.com.facebook.shimmer..shimmer=0.5.0