aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--detekt-baselines/app.xml146
-rw-r--r--detekt-baselines/autofill-parser.xml54
-rw-r--r--detekt-baselines/coroutine-utils.xml8
-rw-r--r--detekt-baselines/crypto-pgpainless.xml15
-rw-r--r--detekt-baselines/format-common.xml19
-rw-r--r--detekt-baselines/random.xml21
-rw-r--r--detekt-baselines/sentry-stub.xml8
-rw-r--r--detekt-baselines/ui-compose.xml44
8 files changed, 315 insertions, 0 deletions
diff --git a/detekt-baselines/app.xml b/detekt-baselines/app.xml
new file mode 100644
index 00000000..0f5ba452
--- /dev/null
+++ b/detekt-baselines/app.xml
@@ -0,0 +1,146 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>ComplexCondition:AutofillFilterView.kt$AutofillFilterView$(list.isEmpty() &amp;&amp; rvPasswordSwitcher.nextView.id == rvPasswordEmpty.id) || (list.isNotEmpty() &amp;&amp; rvPasswordSwitcher.nextView.id == rvPassword.id)</ID>
+ <ID>ComplexCondition:BaseGitActivity.kt$BaseGitActivity$(rootCause is org.eclipse.jgit.errors.TransportException || rootCause is org.eclipse.jgit.api.errors.TransportException || rootCause is org.eclipse.jgit.api.errors.InvalidRemoteException || (rootCause is UserAuthException &amp;&amp; rootCause.message == "Exhausted available authentication methods"))</ID>
+ <ID>ComplexCondition:GitServerConfigActivity.kt$GitServerConfigActivity$localDir.exists() &amp;&amp; localDirFiles.isNotEmpty() &amp;&amp; !(localDirFiles.size == 1 &amp;&amp; localDirFiles[0].name == ".git")</ID>
+ <ID>ComplexCondition:PasswordCreationActivity.kt$PasswordCreationActivity$(!editing || (editing &amp;&amp; suggestedName != file.nameWithoutExtension)) &amp;&amp; file.exists()</ID>
+ <ID>ComplexCondition:PasswordStore.kt$PasswordStore$(keyCode == KeyEvent.KEYCODE_SEARCH || keyCode == KeyEvent.KEYCODE_F &amp;&amp; event.isCtrlPressed) &amp;&amp; !searchItem.isActionViewExpanded</ID>
+ <ID>ComplexMethod:AutofillFilterView.kt$AutofillFilterView$private fun bindUI()</ID>
+ <ID>ComplexMethod:GitCommandExecutor.kt$GitCommandExecutor$suspend fun execute(): Result&lt;Unit, Throwable></ID>
+ <ID>ComplexMethod:GitServerConfigActivity.kt$GitServerConfigActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
+ <ID>ComplexMethod:Migrations.kt$private fun migrateToGitUrlBasedConfig(sharedPrefs: SharedPreferences, gitSettings: GitSettings)</ID>
+ <ID>ComplexMethod:PasswordCreationActivity.kt$PasswordCreationActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
+ <ID>ComplexMethod:PasswordCreationActivity.kt$PasswordCreationActivity$private fun encrypt()</ID>
+ <ID>ComplexMethod:PasswordFragment.kt$PasswordFragment$private fun initializePasswordList()</ID>
+ <ID>EmptyDoWhileBlock:PasswordDialog.kt$PasswordDialog${}</ID>
+ <ID>EmptyFunctionBlock:BasicBottomSheet.kt$BasicBottomSheet.&lt;no name provided>${}</ID>
+ <ID>EmptyFunctionBlock:ItemCreationBottomSheet.kt$ItemCreationBottomSheet.&lt;no name provided>${}</ID>
+ <ID>EmptyFunctionBlock:PasswordFragment.kt$PasswordFragment.&lt;no name provided>.&lt;no name provided>${}</ID>
+ <ID>ForbiddenComment:Api30AutofillResponseBuilder.kt$Api30AutofillResponseBuilder$// TODO: Support multi-step authentication flows in apps via FLAG_DELAY_SAVE</ID>
+ <ID>ForbiddenComment:AutofillResponseBuilder.kt$AutofillResponseBuilder$// TODO: Support multi-step authentication flows in apps via FLAG_DELAY_SAVE</ID>
+ <ID>ForbiddenComment:AutofillResponseBuilder.kt$AutofillResponseBuilder.Companion$// FIXME: We should clone the original dataset here and add the credentials to be filled</ID>
+ <ID>ForbiddenComment:OreoAutofillService.kt$OreoAutofillService.Companion$// TODO: Provide a user-configurable denylist</ID>
+ <ID>ImplicitDefaultLocale:PasswordExportService.kt$PasswordExportService$String.format("%tFT%&lt;tRZ", Calendar.getInstance(TimeZone.getTimeZone("Z")))</ID>
+ <ID>LongMethod:AutofillFilterView.kt$AutofillFilterView$private fun bindUI()</ID>
+ <ID>LongMethod:CredentialFinder.kt$CredentialFinder$override fun askForPassword(cont: Continuation&lt;String?>, isRetry: Boolean)</ID>
+ <ID>LongMethod:GeneralSettings.kt$GeneralSettings$override fun provideSettings(builder: PreferenceScreen.Builder)</ID>
+ <ID>LongMethod:GitCommandExecutor.kt$GitCommandExecutor$suspend fun execute(): Result&lt;Unit, Throwable></ID>
+ <ID>LongMethod:GitServerConfigActivity.kt$GitServerConfigActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
+ <ID>LongMethod:GitServerConfigActivity.kt$GitServerConfigActivity$private fun cloneRepository()</ID>
+ <ID>LongMethod:PasswordCreationActivity.kt$PasswordCreationActivity$override fun onCreate(savedInstanceState: Bundle?)</ID>
+ <ID>LongMethod:PasswordCreationActivity.kt$PasswordCreationActivity$private fun encrypt()</ID>
+ <ID>LongMethod:PasswordFragment.kt$PasswordFragment$private fun initializePasswordList()</ID>
+ <ID>LongMethod:RepositorySettings.kt$RepositorySettings$override fun provideSettings(builder: PreferenceScreen.Builder)</ID>
+ <ID>LoopWithTooManyJumpStatements:AutofillMatcher.kt$AutofillMatcher.Companion$for ((key, value) in prefs.all) { if (!key.startsWith(PREFERENCE_PREFIX_MATCHES)) continue // We know that preferences starting with `PREFERENCE_PREFIX_MATCHES` were // created with `putStringSet`. @Suppress("UNCHECKED_CAST") val oldMatches = value as? Set&lt;String> if (oldMatches == null) { logcat(WARN) { "Failed to read matches for $key" } continue } // Delete all matches for file locations that are going to be overwritten, then // transfer matches over to the files at their new locations. val newMatches = oldMatches .asSequence() .minus(deletePathList) .minus(oldNewPathMap.values) .map { match -> val newPath = oldNewPathMap[match] ?: return@map match logcat { "Updating match for $key: $match --> $newPath" } newPath } .toSet() if (newMatches != oldMatches) prefs.edit { putStringSet(key, newMatches) } }</ID>
+ <ID>LoopWithTooManyJumpStatements:ErrorMessages.kt$ErrorMessages$while (cause.cause != null) { if (cause is GitException) break val nextCause = cause.cause!! if (nextCause is RemoteException) break cause = nextCause }</ID>
+ <ID>MagicNumber:AndroidExtensions.kt$26</ID>
+ <ID>MagicNumber:Api30AutofillResponseBuilder.kt$Api30AutofillResponseBuilder$30</ID>
+ <ID>MagicNumber:AutofillDecryptActivity.kt$AutofillDecryptActivity$26</ID>
+ <ID>MagicNumber:AutofillDecryptActivity.kt$AutofillDecryptActivity.Companion$31</ID>
+ <ID>MagicNumber:AutofillFilterView.kt$AutofillFilterView$26</ID>
+ <ID>MagicNumber:AutofillFilterView.kt$AutofillFilterView.Companion$31</ID>
+ <ID>MagicNumber:AutofillPreferences.kt$DirectoryStructure$26</ID>
+ <ID>MagicNumber:AutofillPublisherChangedActivity.kt$AutofillPublisherChangedActivity$26</ID>
+ <ID>MagicNumber:AutofillPublisherChangedActivity.kt$AutofillPublisherChangedActivity.Companion$31</ID>
+ <ID>MagicNumber:AutofillResponseBuilder.kt$AutofillResponseBuilder$26</ID>
+ <ID>MagicNumber:AutofillResponseBuilder.kt$AutofillResponseBuilder$28</ID>
+ <ID>MagicNumber:AutofillResponseBuilder.kt$AutofillResponseBuilder.Companion$28</ID>
+ <ID>MagicNumber:AutofillSaveActivity.kt$AutofillSaveActivity$26</ID>
+ <ID>MagicNumber:AutofillSettings.kt$AutofillSettings$26</ID>
+ <ID>MagicNumber:AutofillViewUtils.kt$30</ID>
+ <ID>MagicNumber:AutofillViewUtils.kt$31</ID>
+ <ID>MagicNumber:BasePgpActivity.kt$BasePgpActivity$26</ID>
+ <ID>MagicNumber:BasePgpActivity.kt$BasePgpActivity$45</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$1000</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$1000L</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$23</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$24</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$26</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$31</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$45</ID>
+ <ID>MagicNumber:ClipboardService.kt$ClipboardService$500</ID>
+ <ID>MagicNumber:DicewareModule.kt$DicewareModule$6</ID>
+ <ID>MagicNumber:DicewarePasswordGeneratorDialogFragment.kt$DicewarePasswordGeneratorDialogFragment$5</ID>
+ <ID>MagicNumber:Extensions.kt$1000</ID>
+ <ID>MagicNumber:GeneralSettings.kt$GeneralSettings$25</ID>
+ <ID>MagicNumber:GitConfigActivity.kt$GitConfigActivity$0.5f</ID>
+ <ID>MagicNumber:GitConfigActivity.kt$GitConfigActivity$500</ID>
+ <ID>MagicNumber:GitConfigActivity.kt$GitConfigActivity$8</ID>
+ <ID>MagicNumber:GitLogAdapter.kt$8</ID>
+ <ID>MagicNumber:GitServerConfigActivity.kt$GitServerConfigActivity$500</ID>
+ <ID>MagicNumber:LaunchActivity.kt$LaunchActivity$500L</ID>
+ <ID>MagicNumber:MiscSettings.kt$MiscSettings$26</ID>
+ <ID>MagicNumber:OreoAutofillService.kt$OreoAutofillService$26</ID>
+ <ID>MagicNumber:OreoAutofillService.kt$OreoAutofillService$28</ID>
+ <ID>MagicNumber:OreoAutofillService.kt$OreoAutofillService$30</ID>
+ <ID>MagicNumber:PasswordCreationActivity.kt$PasswordCreationActivity$28</ID>
+ <ID>MagicNumber:PasswordExportService.kt$PasswordExportService$1024</ID>
+ <ID>MagicNumber:PasswordExportService.kt$PasswordExportService$26</ID>
+ <ID>MagicNumber:PasswordFragment.kt$PasswordFragment.&lt;no name provided>$100</ID>
+ <ID>MagicNumber:PasswordFragment.kt$PasswordFragment.&lt;no name provided>$90f</ID>
+ <ID>MagicNumber:PasswordGeneratorDialogFragment.kt$PasswordGeneratorDialogFragment$20</ID>
+ <ID>MagicNumber:PasswordItemRecyclerAdapter.kt$PasswordItemRecyclerAdapter.PasswordItemViewHolder$0.7f</ID>
+ <ID>MagicNumber:ProxySelectorActivity.kt$ProxySelectorActivity$29</ID>
+ <ID>MagicNumber:ProxySelectorActivity.kt$ProxySelectorActivity$500</ID>
+ <ID>MagicNumber:RepositorySettings.kt$RepositorySettings$25</ID>
+ <ID>MagicNumber:ShortcutHandler.kt$ShortcutHandler$25</ID>
+ <ID>MagicNumber:ShortcutHandler.kt$ShortcutHandler$26</ID>
+ <ID>MagicNumber:SshKey.kt$SshKey$100_000</ID>
+ <ID>MagicNumber:SshKey.kt$SshKey$15</ID>
+ <ID>MagicNumber:SshKey.kt$SshKey$28</ID>
+ <ID>MagicNumber:SshKey.kt$SshKey$30</ID>
+ <ID>MagicNumber:SshKey.kt$SshKey.Algorithm.Ecdsa$256</ID>
+ <ID>MagicNumber:SshKey.kt$SshKey.Algorithm.Ecdsa$28</ID>
+ <ID>MagicNumber:SshKey.kt$SshKey.Algorithm.Rsa$3072</ID>
+ <ID>MagicNumber:SshjSessionFactory.kt$SshjSession$22</ID>
+ <ID>MagicNumber:UriTotpFinder.kt$UriTotpFinder$30</ID>
+ <ID>MatchingDeclarationName:AutofillViewUtils.kt$DatasetMetadata</ID>
+ <ID>MaxLineLength:BaseGitActivity.kt$BaseGitActivity$"The server does not support multiple Git operations per SSH session. Please try again, a slower fallback mode will be used."</ID>
+ <ID>MaxLineLength:BaseGitActivity.kt$BaseGitActivity$"WARNING: The remote host key has changed. If this is expected, please go to Git server settings and clear the saved host key."</ID>
+ <ID>MaxLineLength:UriTotpFinderTest.kt$UriTotpFinderTest.Companion$"otpauth://totp/ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&amp;issuer=ACME%20Co&amp;algorithm=SHA256&amp;digits=12&amp;period=25"</ID>
+ <ID>NestedBlockDepth:FieldItemAdapter.kt$FieldItemAdapter.FieldItemViewHolder$fun bind(fieldItem: FieldItem, showPassword: Boolean, copyTextToClipboard: (String?) -> Unit)</ID>
+ <ID>NestedBlockDepth:GitOperation.kt$GitOperation$suspend fun executeAfterAuthentication(authMode: AuthMode): Result&lt;Unit, Throwable></ID>
+ <ID>NestedBlockDepth:PasswordExportService.kt$PasswordExportService$override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int</ID>
+ <ID>ReturnCount:Api30AutofillResponseBuilder.kt$Api30AutofillResponseBuilder$private fun makeFillOtpFromSmsDataset( context: Context, imeSpec: InlinePresentationSpec? ): Dataset?</ID>
+ <ID>ReturnCount:Api30AutofillResponseBuilder.kt$Api30AutofillResponseBuilder$private fun makeSaveInfo(): SaveInfo?</ID>
+ <ID>ReturnCount:AutofillDecryptActivity.kt$AutofillDecryptActivity$private suspend fun decryptCredential(file: File, password: String): Credentials?</ID>
+ <ID>ReturnCount:AutofillResponseBuilder.kt$AutofillResponseBuilder$private fun makeFillOtpFromSmsDataset(context: Context): Dataset?</ID>
+ <ID>ReturnCount:AutofillResponseBuilder.kt$AutofillResponseBuilder$private fun makeSaveInfo(): SaveInfo?</ID>
+ <ID>ReturnCount:AutofillViewUtils.kt$@SuppressLint("RestrictedApi") fun makeInlinePresentation( context: Context, imeSpec: InlinePresentationSpec, metadata: DatasetMetadata ): InlinePresentation?</ID>
+ <ID>ReturnCount:BaseGitActivity.kt$BaseGitActivity$suspend fun launchGitOperation(operation: GitOp): Result&lt;Unit, Throwable></ID>
+ <ID>ReturnCount:ClipboardService.kt$ClipboardService$override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int</ID>
+ <ID>ReturnCount:Extensions.kt$fun File.contains(other: File): Boolean</ID>
+ <ID>ReturnCount:GitOperation.kt$GitOperation$suspend fun executeAfterAuthentication(authMode: AuthMode): Result&lt;Unit, Throwable></ID>
+ <ID>ReturnCount:GitSettings.kt$GitSettings$fun updateConnectionSettingsIfValid( newAuthMode: AuthMode, newUrl: String, newBranch: String ): UpdateConnectionSettingsResult</ID>
+ <ID>ReturnCount:OreoAutofillService.kt$OreoAutofillService$override fun onFillRequest( request: FillRequest, cancellationSignal: CancellationSignal, callback: FillCallback )</ID>
+ <ID>ReturnCount:OreoAutofillService.kt$OreoAutofillService$override fun onSaveRequest(request: SaveRequest, callback: SaveCallback)</ID>
+ <ID>ReturnCount:PasswordStore.kt$PasswordStore$override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean</ID>
+ <ID>ReturnCount:ShortcutHandler.kt$ShortcutHandler$fun addPinnedShortcut(item: PasswordItem, intent: Intent)</ID>
+ <ID>ReturnCount:UriTotpFinder.kt$UriTotpFinder$override fun findSecret(content: String): String?</ID>
+ <ID>SpreadOperator:Api30AutofillResponseBuilder.kt$Api30AutofillResponseBuilder$(*ignoredIds.toTypedArray())</ID>
+ <ID>SpreadOperator:AutofillResponseBuilder.kt$AutofillResponseBuilder$(*ignoredIds.toTypedArray())</ID>
+ <ID>SpreadOperator:BreakOutOfDetached.kt$BreakOutOfDetached$( // abort the rebase git.rebase().setOperation(RebaseCommand.Operation.ABORT), *resetCommands, )</ID>
+ <ID>SpreadOperator:BreakOutOfDetached.kt$BreakOutOfDetached$( // reset hard back to our local HEAD git.reset().setMode(ResetCommand.ResetType.HARD), *resetCommands, )</ID>
+ <ID>SpreadOperator:ErrorMessages.kt$GitException$(res, *fmt)</ID>
+ <ID>SpreadOperator:ErrorMessages.kt$GitException.PullException$(res, *fmt)</ID>
+ <ID>SpreadOperator:ErrorMessages.kt$GitException.PushException$(res, *fmt)</ID>
+ <ID>ThrowsCount:GitCommandExecutor.kt$GitCommandExecutor$suspend fun execute(): Result&lt;Unit, Throwable></ID>
+ <ID>ThrowsCount:SshKey.kt$SshKey$fun import(uri: Uri)</ID>
+ <ID>TooManyFunctions:PasswordStore.kt$PasswordStore : BaseGitActivity</ID>
+ <ID>TooManyFunctions:SearchableRepositoryViewModel.kt$SearchableRepositoryViewModel : AndroidViewModel</ID>
+ <ID>TooManyFunctions:SshjConfig.kt$AbstractLogger : Logger</ID>
+ <ID>TooManyFunctions:SshjConfig.kt$LogcatLoggerFactory$LogcatLogger : AbstractLogger</ID>
+ <ID>UnusedPrivateMember:PasswordStore.kt$PasswordStore$private val directorySelectAction = registerForActivityResult(StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { checkLocalRepository() } }</ID>
+ <ID>UnusedPrivateMember:PasswordStore.kt$PasswordStore$private val storagePermissionRequest = registerForActivityResult(RequestPermission()) { granted -> if (granted) checkLocalRepository() }</ID>
+ <ID>UseCheckOrError:CredentialFinder.kt$CredentialFinder$throw IllegalStateException("Only SshKey and Password connection mode ask for passwords")</ID>
+ <ID>UseCheckOrError:FragmentViewBindingDelegate.kt$FragmentViewBindingDelegate$throw IllegalStateException( "Should not attempt to get bindings when Fragment views are destroyed." )</ID>
+ <ID>UseCheckOrError:GitOperation.kt$GitOperation$throw IllegalStateException("Biometric authentication failures should be ignored")</ID>
+ <ID>UseCheckOrError:PGPKeyImportActivity.kt$PGPKeyImportActivity$throw IllegalStateException("Failed to open selected file")</ID>
+ <ID>UseCheckOrError:SshKey.kt$SshKey$throw IllegalStateException("SSH key does not exist in Keystore")</ID>
+ <ID>UseCheckOrError:SshKeyGenActivity.kt$SshKeyGenActivity$throw IllegalStateException("Impossible key type selection")</ID>
+ <ID>UtilityClassWithPublicConstructor:AutofillMatcher.kt$AutofillMatcher</ID>
+ <ID>WildcardImport:GitOperation.kt$import app.passwordstore.util.auth.BiometricAuthenticator.Result.*</ID>
+ </CurrentIssues>
+</SmellBaseline>
diff --git a/detekt-baselines/autofill-parser.xml b/detekt-baselines/autofill-parser.xml
new file mode 100644
index 00000000..80d2ae0f
--- /dev/null
+++ b/detekt-baselines/autofill-parser.xml
@@ -0,0 +1,54 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>ComplexMethod:AutofillStrategyDsl.kt$AutofillRule$fun match( allPassword: List&lt;FormField>, allUsername: List&lt;FormField>, allOtp: List&lt;FormField>, singleOriginMode: Boolean, isManualRequest: Boolean ): AutofillScenario&lt;FormField>?</ID>
+ <ID>DestructuringDeclarationWithTooManyEntries:AutofillStrategyDsl.kt$AutofillRule$(type, matcher, optional, matchHidden)</ID>
+ <ID>ForbiddenComment:AutofillFormParser.kt$AutofillFormParser$// TODO: Support WebViews in apps via Digital Asset Links</ID>
+ <ID>ForbiddenComment:AutofillStrategy.kt$// TODO: Introduce a custom fill/generate/update flow for this scenario</ID>
+ <ID>ForbiddenComment:FormField.kt$FormField$// TODO: Revisit this decision in the future</ID>
+ <ID>LongMethod:ByteArray.kt$@Suppress("ComplexMethod", "NestedBlockDepth") internal fun ByteArray.binarySearch(labels: List&lt;ByteArray>, labelIndex: Int): String?</ID>
+ <ID>LoopWithTooManyJumpStatements:AutofillStrategyDsl.kt$PairOfFieldsMatcher$for ((i, tieBreaker) in tieBreakers.withIndex()) { val new = current.filter { tieBreaker(it, alreadyMatched) } if (new.isEmpty()) { logcat { "Tie breaker #${i + 1}: Didn't match any pair of fields; skipping" } continue } // and return if the available options have been narrowed to a single field. if (new.size == 1) { logcat { "Tie breaker #${i + 1}: Success" } current = new break } logcat { "Tie breaker #${i + 1}: Matched ${new.size} pairs of fields; continuing" } current = new }</ID>
+ <ID>LoopWithTooManyJumpStatements:AutofillStrategyDsl.kt$SingleFieldMatcher$for ((i, tieBreaker) in tieBreakers.withIndex()) { // Successively filter matched fields via tie breakers... val new = current.filter { tieBreaker(it, alreadyMatched) } // skipping those tie breakers that are not satisfied for any remaining field... if (new.isEmpty()) { logcat { "Tie breaker #${i + 1}: Didn't match any field; skipping" } continue } // and return if the available options have been narrowed to a single field. if (new.size == 1) { logcat { "Tie breaker #${i + 1}: Success" } current = new break } logcat { "Tie breaker #${i + 1}: Matched ${new.size} fields; continuing" } current = new }</ID>
+ <ID>LoopWithTooManyJumpStatements:ByteArray.kt$while (true) { val byte0 = if (expectDot) { expectDot = false '.'.code.toByte() } else { labels[currentLabelIndex][currentLabelByteIndex] and BITMASK } val byte1 = this[start + publicSuffixByteIndex] and BITMASK // Compare the bytes. Note that the file stores UTF-8 encoded bytes, so we must compare // the // unsigned bytes. compareResult = (byte0.toUByte() - byte1.toUByte()).toInt() if (compareResult != 0) { break } publicSuffixByteIndex++ currentLabelByteIndex++ if (publicSuffixByteIndex == publicSuffixLength) { break } if (labels[currentLabelIndex].size == currentLabelByteIndex) { // We've exhausted our current label. Either there are more labels to compare, in // which // case we expect a dot as the next character. Otherwise, we've checked all our // labels. if (currentLabelIndex == labels.size - 1) { break } else { currentLabelIndex++ currentLabelByteIndex = -1 expectDot = true } } }</ID>
+ <ID>MagicNumber:AutofillFormParser.kt$AutofillFormParser$26</ID>
+ <ID>MagicNumber:AutofillFormParser.kt$FillableForm$26</ID>
+ <ID>MagicNumber:AutofillHelper.kt$26</ID>
+ <ID>MagicNumber:AutofillHelper.kt$28</ID>
+ <ID>MagicNumber:AutofillHelper.kt$FixedSaveCallback$26</ID>
+ <ID>MagicNumber:AutofillHelper.kt$FixedSaveCallback$28</ID>
+ <ID>MagicNumber:AutofillHelper.kt$FixedSaveCallback$29</ID>
+ <ID>MagicNumber:AutofillScenario.kt$26</ID>
+ <ID>MagicNumber:AutofillScenario.kt$4</ID>
+ <ID>MagicNumber:AutofillScenario.kt$5</ID>
+ <ID>MagicNumber:AutofillScenario.kt$AutofillScenario$26</ID>
+ <ID>MagicNumber:AutofillScenario.kt$ClassifiedAutofillScenario$26</ID>
+ <ID>MagicNumber:AutofillScenario.kt$GenericAutofillScenario$26</ID>
+ <ID>MagicNumber:AutofillStrategy.kt$26</ID>
+ <ID>MagicNumber:AutofillStrategyDsl.kt$26</ID>
+ <ID>MagicNumber:AutofillStrategyDsl.kt$AutofillRule$26</ID>
+ <ID>MagicNumber:AutofillStrategyDsl.kt$AutofillStrategy$26</ID>
+ <ID>MagicNumber:AutofillStrategyDsl.kt$FieldMatcher$26</ID>
+ <ID>MagicNumber:AutofillStrategyDsl.kt$PairOfFieldsMatcher$26</ID>
+ <ID>MagicNumber:AutofillStrategyDsl.kt$SingleFieldMatcher$26</ID>
+ <ID>MagicNumber:FeatureAndTrustDetection.kt$26</ID>
+ <ID>MagicNumber:FeatureAndTrustDetection.kt$28</ID>
+ <ID>MagicNumber:FormField.kt$FormField$26</ID>
+ <ID>MagicNumber:FormField.kt$FormField$6</ID>
+ <ID>MagicNumber:FormField.kt$FormField$8</ID>
+ <ID>MagicNumber:FormField.kt$FormField.Companion$26</ID>
+ <ID>MagicNumber:PublicSuffixListCache.kt$29</ID>
+ <ID>MaxLineLength:FeatureAndTrustDetection.kt$/* In order to add a new browser, do the following: 1. Obtain the .apk from a trusted source. For example, download it from the Play Store on your phone and use adb pull to get it onto your computer. We will assume that it is called browser.apk. 2. Run aapt dump badging browser.apk | grep package: | grep -Eo " name='[a-zA-Z0-9_\.]*" | cut -c8- to obtain the package name (actually, the application ID) of the app in the .apk. 3. Run apksigner verify --print-certs browser.apk | grep "#1 certificate SHA-256" | grep -Eo "[a-f0-9]{64}" | tr -d '\n' | xxd -r -p | base64 to calculate the hash of browser.apk's first signing certificate. Note: This will only work if the apk has a single signing certificate. Apps with multiple signers are very rare, so there is probably no need to add them. Refer to computeCertificatesHash to learn how the hash would be computed in this case. 4. Verify the package name and the hash, for example by asking other people to repeat the steps above. 5. Add an entry with the browser apps's package name and the hash to TRUSTED_BROWSER_CERTIFICATE_HASH. 6. Optionally, try adding the browser's package name to BROWSERS_WITH_SAVE_SUPPORT and check whether a save request to Password Store is triggered when you submit a registration form. 7. Optionally, try adding the browser's package name to BROWSERS_WITH_MULTI_ORIGIN_SUPPORT and check whether it correctly distinguishes web origins even if iframes are present on the page. You can use https://fabianhenneke.github.io/Android-Password-Store/ as a test form. */</ID>
+ <ID>MaxLineLength:FormField.kt$FormField$"\"$hint\", \"$fieldId\"${if (isFocused) ", focused" else ""}${if (isVisible) ", visible" else ""}, $webOrigin, $htmlAttributesDebug, $autofillHints"</ID>
+ <ID>ReturnCount:AutofillFormParser.kt$AutofillFormParser$private fun determineFormOrigin(context: Context): FormOrigin?</ID>
+ <ID>ReturnCount:AutofillFormParser.kt$AutofillFormParser$private fun webOriginToFormOrigin(context: Context, origin: String): FormOrigin?</ID>
+ <ID>ReturnCount:AutofillFormParser.kt$FormOrigin.Companion$public fun fromBundle(bundle: Bundle): FormOrigin?</ID>
+ <ID>ReturnCount:AutofillStrategyDsl.kt$AutofillRule$fun match( allPassword: List&lt;FormField>, allUsername: List&lt;FormField>, allOtp: List&lt;FormField>, singleOriginMode: Boolean, isManualRequest: Boolean ): AutofillScenario&lt;FormField>?</ID>
+ <ID>ReturnCount:PublicSuffixListCache.kt$private fun getSuffixPlusUpToOne(domain: String, suffix: String): String?</ID>
+ <ID>ReturnCount:PublicSuffixListData.kt$PublicSuffixListData$private fun findExceptionMatch(labels: List&lt;ByteArray>, wildcardMatch: String?): String?</ID>
+ <ID>ReturnCount:PublicSuffixListData.kt$PublicSuffixListData$private fun findMatchingRule(domainLabels: List&lt;String>): List&lt;String></ID>
+ <ID>TooGenericExceptionCaught:AutofillScenario.kt$AutofillScenario.Companion$e: Throwable</ID>
+ <ID>UnusedPrivateMember:AutofillStrategy.kt$private inline fun &lt;T> Pair&lt;T, T>.none(predicate: T.() -> Boolean)</ID>
+ <ID>UnusedPrivateMember:FormField.kt$FormField$// Ignored for now, see excludedByHints private val excludedByAutocompleteHint = htmlAutocomplete == "off"</ID>
+ </CurrentIssues>
+</SmellBaseline>
diff --git a/detekt-baselines/coroutine-utils.xml b/detekt-baselines/coroutine-utils.xml
new file mode 100644
index 00000000..1d920d34
--- /dev/null
+++ b/detekt-baselines/coroutine-utils.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>InstanceOfCheckForException:RunSuspendCatching.kt$e is CancellationException</ID>
+ <ID>TooGenericExceptionCaught:RunSuspendCatching.kt$e: Throwable</ID>
+ </CurrentIssues>
+</SmellBaseline>
diff --git a/detekt-baselines/crypto-pgpainless.xml b/detekt-baselines/crypto-pgpainless.xml
new file mode 100644
index 00000000..5f6cad27
--- /dev/null
+++ b/detekt-baselines/crypto-pgpainless.xml
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>ForbiddenComment:PGPKeyManager.kt$PGPKeyManager$// TODO: This is a temp hack for now and in future it should check that the GPGKeyManager can</ID>
+ <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.Companion$16</ID>
+ <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.Companion$3</ID>
+ <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$0xffffffffL</ID>
+ <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$32</ID>
+ <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$8</ID>
+ <ID>NestedBlockDepth:GpgIdentifier.kt$GpgIdentifier.Companion$private fun splitUserId(userId: String): String?</ID>
+ <ID>ReturnCount:GpgIdentifier.kt$GpgIdentifier.Companion$public fun fromString(identifier: String): GpgIdentifier?</ID>
+ <ID>ReturnCount:KeyUtils.kt$KeyUtils$public fun tryParseKeyring(key: PGPKey): PGPKeyRing?</ID>
+ </CurrentIssues>
+</SmellBaseline>
diff --git a/detekt-baselines/format-common.xml b/detekt-baselines/format-common.xml
new file mode 100644
index 00000000..42e17ed0
--- /dev/null
+++ b/detekt-baselines/format-common.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>MagicNumber:Otp.kt$Otp$0x7f</ID>
+ <ID>MagicNumber:Otp.kt$Otp$10</ID>
+ <ID>MagicNumber:Otp.kt$Otp$26</ID>
+ <ID>MagicNumber:Otp.kt$Otp$4</ID>
+ <ID>MagicNumber:Otp.kt$Otp$5</ID>
+ <ID>MagicNumber:Otp.kt$Otp$6</ID>
+ <ID>MagicNumber:Otp.kt$Otp$8</ID>
+ <ID>MagicNumber:PasswordEntry.kt$PasswordEntry$1000</ID>
+ <ID>MagicNumber:PasswordEntry.kt$PasswordEntry$1000L</ID>
+ <ID>MatchingDeclarationName:Clocks.kt$UserClock : Clock</ID>
+ <ID>MatchingDeclarationName:TestClocks.kt$TestUserClock : UserClock</ID>
+ <ID>MaxLineLength:PasswordEntryTest.kt$PasswordEntryTest.Companion$"otpauth://totp/ACME%20Co:john@example.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&amp;issuer=ACME%20Co&amp;algorithm=SHA1&amp;digits=6&amp;period=30"</ID>
+ <ID>ReturnCount:PasswordEntry.kt$PasswordEntry$private fun findAndStripPassword(passContent: List&lt;String>): Pair&lt;String?, List&lt;String>></ID>
+ </CurrentIssues>
+</SmellBaseline>
diff --git a/detekt-baselines/random.xml b/detekt-baselines/random.xml
new file mode 100644
index 00000000..345a7f94
--- /dev/null
+++ b/detekt-baselines/random.xml
@@ -0,0 +1,21 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>ComplexCondition:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$!candidate.flags.hasFlag(nextBasicType) || (isStartOfPart &amp;&amp; candidate.flags hasFlag NOT_FIRST) || // Don't let a diphthong that starts with a vowel follow a vowel. (previousFlags hasFlag VOWEL &amp;&amp; candidate.flags hasFlag VOWEL &amp;&amp; candidate.flags hasFlag DIPHTHONG) || // Don't add multi-character candidates if we would go over the targetLength. (password.length + candidate.length > targetLength) || (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS &amp;&amp; candidate.isAmbiguous)</ID>
+ <ID>ComplexMethod:PasswordGenerator.kt$PasswordGenerator$@Throws(PasswordGeneratorException::class) public fun generate(passwordOptions: List&lt;PasswordOption>, length: Int = DEFAULT_LENGTH): String</ID>
+ <ID>ComplexMethod:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$fun generate(targetLength: Int, pwFlags: Int): String?</ID>
+ <ID>LongMethod:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$fun generate(targetLength: Int, pwFlags: Int): String?</ID>
+ <ID>LoopWithTooManyJumpStatements:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$while (password.length &lt; targetLength) { // First part: Add a single letter or pronounceable pair of letters in varying case. val candidate = elements.secureRandomElement() // Reroll if the candidate does not fulfill the current requirements. if ( !candidate.flags.hasFlag(nextBasicType) || (isStartOfPart &amp;&amp; candidate.flags hasFlag NOT_FIRST) || // Don't let a diphthong that starts with a vowel follow a vowel. (previousFlags hasFlag VOWEL &amp;&amp; candidate.flags hasFlag VOWEL &amp;&amp; candidate.flags hasFlag DIPHTHONG) || // Don't add multi-character candidates if we would go over the targetLength. (password.length + candidate.length > targetLength) || (pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS &amp;&amp; candidate.isAmbiguous) ) { continue } // At this point the candidate could be appended to the password, but we still have // to determine the case. If no upper case characters are required, we don't add // any. val useUpperIfBothCasesAllowed = (isStartOfPart || candidate.flags hasFlag CONSONANT) &amp;&amp; secureRandomBiasedBoolean(20) password += if ( pwFlags hasFlag PasswordGenerator.UPPERS &amp;&amp; (!(pwFlags hasFlag PasswordGenerator.LOWERS) || useUpperIfBothCasesAllowed) ) { candidate.upperCase } else { candidate.lowerCase } // We ensured above that we will not go above the target length. check(password.length &lt;= targetLength) if (password.length == targetLength) break // Second part: Add digits and symbols with a certain probability (if requested) if // they would not directly follow the first character in a pronounceable part. if ( !isStartOfPart &amp;&amp; pwFlags hasFlag PasswordGenerator.DIGITS &amp;&amp; secureRandomBiasedBoolean(30) ) { var randomDigit: Char do { randomDigit = secureRandomNumber(10).toString(10).first() } while ( pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS &amp;&amp; randomDigit in PasswordGenerator.AMBIGUOUS_STR ) password += randomDigit // Begin a new pronounceable part after every digit. isStartOfPart = true nextBasicType = if (secureRandomBoolean()) VOWEL else CONSONANT previousFlags = 0 continue } if ( !isStartOfPart &amp;&amp; pwFlags hasFlag PasswordGenerator.SYMBOLS &amp;&amp; secureRandomBiasedBoolean(20) ) { var randomSymbol: Char do { randomSymbol = PasswordGenerator.SYMBOLS_STR.secureRandomCharacter() } while ( pwFlags hasFlag PasswordGenerator.NO_AMBIGUOUS &amp;&amp; randomSymbol in PasswordGenerator.AMBIGUOUS_STR ) password += randomSymbol // Continue the password generation as if nothing was added. } // Third part: Determine the basic type of the next character depending on the letter // we just added. nextBasicType = when { candidate.flags.hasFlag(CONSONANT) -> VOWEL previousFlags.hasFlag(VOWEL) || candidate.flags.hasFlag(DIPHTHONG) || secureRandomBiasedBoolean(60) -> CONSONANT else -> VOWEL } previousFlags = candidate.flags isStartOfPart = false }</ID>
+ <ID>MagicNumber:PasswordGenerator.kt$PasswordGenerator$1000</ID>
+ <ID>MagicNumber:PasswordGenerator.kt$PasswordGenerator$6</ID>
+ <ID>MagicNumber:RandomNumberGenerator.kt$100</ID>
+ <ID>MagicNumber:RandomNumberGenerator.kt$99</ID>
+ <ID>MagicNumber:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$10</ID>
+ <ID>MagicNumber:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$20</ID>
+ <ID>MagicNumber:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$30</ID>
+ <ID>MagicNumber:RandomPhonemesGenerator.kt$RandomPhonemesGenerator$60</ID>
+ <ID>ReturnCount:PasswordGenerator.kt$PasswordGenerator$internal fun isValidPassword(password: String, pwFlags: Int): Boolean</ID>
+ <ID>ThrowsCount:PasswordGenerator.kt$PasswordGenerator$@Throws(PasswordGeneratorException::class) public fun generate(passwordOptions: List&lt;PasswordOption>, length: Int = DEFAULT_LENGTH): String</ID>
+ </CurrentIssues>
+</SmellBaseline>
diff --git a/detekt-baselines/sentry-stub.xml b/detekt-baselines/sentry-stub.xml
new file mode 100644
index 00000000..9bebfb65
--- /dev/null
+++ b/detekt-baselines/sentry-stub.xml
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>EmptyFunctionBlock:Scope.kt$Scope${}</ID>
+ <ID>EmptyFunctionBlock:Sentry.kt$Sentry${}</ID>
+ </CurrentIssues>
+</SmellBaseline>
diff --git a/detekt-baselines/ui-compose.xml b/detekt-baselines/ui-compose.xml
new file mode 100644
index 00000000..684196b9
--- /dev/null
+++ b/detekt-baselines/ui-compose.xml
@@ -0,0 +1,44 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<SmellBaseline>
+ <ManuallySuppressedIssues/>
+ <CurrentIssues>
+ <ID>FunctionNaming:Theme.kt$@Composable public fun APSTheme( useDarkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit, )</ID>
+ <ID>MagicNumber:Color.kt$0xFF001e30</ID>
+ <ID>MagicNumber:Color.kt$0xFF001e31</ID>
+ <ID>MagicNumber:Color.kt$0xFF00344e</ID>
+ <ID>MagicNumber:Color.kt$0xFF003450</ID>
+ <ID>MagicNumber:Color.kt$0xFF003e5b</ID>
+ <ID>MagicNumber:Color.kt$0xFF004b70</ID>
+ <ID>MagicNumber:Color.kt$0xFF004c6f</ID>
+ <ID>MagicNumber:Color.kt$0xFF006494</ID>
+ <ID>MagicNumber:Color.kt$0xFF006591</ID>
+ <ID>MagicNumber:Color.kt$0xFF0b1d29</ID>
+ <ID>MagicNumber:Color.kt$0xFF1a1c1e</ID>
+ <ID>MagicNumber:Color.kt$0xFF21323e</ID>
+ <ID>MagicNumber:Color.kt$0xFF2e3133</ID>
+ <ID>MagicNumber:Color.kt$0xFF384956</ID>
+ <ID>MagicNumber:Color.kt$0xFF410001</ID>
+ <ID>MagicNumber:Color.kt$0xFF41474d</ID>
+ <ID>MagicNumber:Color.kt$0xFF4f606e</ID>
+ <ID>MagicNumber:Color.kt$0xFF680003</ID>
+ <ID>MagicNumber:Color.kt$0xFF72787e</ID>
+ <ID>MagicNumber:Color.kt$0xFF85ceff</ID>
+ <ID>MagicNumber:Color.kt$0xFF8aceff</ID>
+ <ID>MagicNumber:Color.kt$0xFF8b9197</ID>
+ <ID>MagicNumber:Color.kt$0xFF930006</ID>
+ <ID>MagicNumber:Color.kt$0xFFb7c9d9</ID>
+ <ID>MagicNumber:Color.kt$0xFFba1b1b</ID>
+ <ID>MagicNumber:Color.kt$0xFFc1c7ce</ID>
+ <ID>MagicNumber:Color.kt$0xFFc7e6ff</ID>
+ <ID>MagicNumber:Color.kt$0xFFc8e6ff</ID>
+ <ID>MagicNumber:Color.kt$0xFFd3e5f5</ID>
+ <ID>MagicNumber:Color.kt$0xFFdde3ea</ID>
+ <ID>MagicNumber:Color.kt$0xFFe1e2e5</ID>
+ <ID>MagicNumber:Color.kt$0xFFf0f0f3</ID>
+ <ID>MagicNumber:Color.kt$0xFFfcfcff</ID>
+ <ID>MagicNumber:Color.kt$0xFFffb4a9</ID>
+ <ID>MagicNumber:Color.kt$0xFFffdad4</ID>
+ <ID>MagicNumber:Color.kt$0xFFffffff</ID>
+ <ID>MagicNumber:Type.kt$0.25</ID>
+ </CurrentIssues>
+</SmellBaseline>