From 74f4d5a134f69a2b9294a74f6babbc7e663e0aee Mon Sep 17 00:00:00 2001 From: AL-Session <160798022+AL-Session@users.noreply.github.com> Date: Mon, 3 Feb 2025 11:16:26 +1100 Subject: [PATCH] Fix/recovery password copies linebreak (#909) * Filtered any control characters or double-spaces from copied recovery password mnemonic * Fix typo in comment * Single char comment alignment adjustment --------- Co-authored-by: alansley --- .../RecoveryPasswordViewModel.kt | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt index 817859b14c..e6af49ff19 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordViewModel.kt @@ -27,14 +27,33 @@ class RecoveryPasswordViewModel @Inject constructor( ): AndroidViewModel(application) { val prefs = AppTextSecurePreferences(application) + // Regex to remove any spurious characters from our recovery password mnemonic. + // The regex matches are: + // - "\r" - carriage return, + // - "\n" - newline, + // - "\u2028" - unicode line separator, + // - "\u2029" - unicode paragraph separator, + // - "|\s{2,}" - two or more consecutive spaces. + val linebreakRemovalRegex = Regex("""[\r\n\u2028\u2029]+|\s{2,}""") + val seed = MutableStateFlow(null) val mnemonic = seed.filterNotNull() - .map { MnemonicCodec { MnemonicUtilities.loadFileContents(application, it) }.encode(it, MnemonicCodec.Language.Configuration.english) } + .map { + MnemonicCodec { + MnemonicUtilities.loadFileContents(application, it) + } + .encode(it, MnemonicCodec.Language.Configuration.english) + .trim() // Remove any leading or trailing whitespace + } .stateIn(viewModelScope, SharingStarted.Eagerly, "") fun copyMnemonic() { prefs.setHasViewedSeed(true) - ClipData.newPlainText("Seed", mnemonic.value) + + // Ensure that our mnemonic words are separated by single spaces only without any control characters + val normalisedMnemonic = mnemonic.value.replace(linebreakRemovalRegex, " ") + + ClipData.newPlainText("Seed", normalisedMnemonic) .let(application.clipboard::setPrimaryClip) }