Try fixing index OOB issues in Editable.checkSuggestionNeeded (#6303)
- Fix the case where the order for `start` and `end` is reversed. - Fix the case where `start` or `end` may be outside the editable's range (`0..length`).
This commit is contained in:
committed by
GitHub
parent
18e5b47106
commit
28c9bed632
@@ -42,6 +42,7 @@ import io.element.android.libraries.textcomposer.model.SuggestionType
|
||||
import io.element.android.libraries.textcomposer.model.aMarkdownTextEditorState
|
||||
import io.element.android.wysiwyg.compose.RichTextEditorStyle
|
||||
import io.element.android.wysiwyg.compose.internal.applyStyleInCompose
|
||||
import timber.log.Timber
|
||||
|
||||
@Suppress("ModifierMissing")
|
||||
@Composable
|
||||
@@ -149,8 +150,20 @@ fun MarkdownTextInput(
|
||||
|
||||
private fun Editable.checkSuggestionNeeded(): Suggestion? {
|
||||
if (this.isEmpty()) return null
|
||||
val start = Selection.getSelectionStart(this)
|
||||
val end = Selection.getSelectionEnd(this)
|
||||
var start = Selection.getSelectionStart(this)
|
||||
var end = Selection.getSelectionEnd(this)
|
||||
val range = 0..this.length
|
||||
|
||||
if (start !in range || end !in range) {
|
||||
Timber.tag("checkSuggestionNeeded").e("Selection indices are out of bounds: start=$start, end=$end, text length=${this.length}")
|
||||
return null
|
||||
}
|
||||
|
||||
// Make sure the selection order is correct, if not swap them: sometimes we can get the end before the start
|
||||
val tempEnd = end
|
||||
end = maxOf(start, end)
|
||||
start = minOf(start, tempEnd)
|
||||
|
||||
var startOfWord = start
|
||||
while ((startOfWord > 0 || startOfWord == length) && !this[startOfWord - 1].isWhitespace()) {
|
||||
startOfWord--
|
||||
@@ -161,11 +174,16 @@ private fun Editable.checkSuggestionNeeded(): Suggestion? {
|
||||
// If a mention span already exists we don't need suggestions
|
||||
if (getSpans<MentionSpan>(startOfWord, startOfWord + 1).isNotEmpty()) return null
|
||||
|
||||
return if (firstChar in listOf('@', '#', '/')) {
|
||||
return if (firstChar in listOf('@', '#', '/', ':')) {
|
||||
var endOfWord = end
|
||||
while (endOfWord < this.length && !this[endOfWord].isWhitespace()) {
|
||||
endOfWord++
|
||||
}
|
||||
if (startOfWord + 1 > endOfWord) {
|
||||
Timber.tag("checkSuggestionNeeded").e("No need to show suggestions for an invalid range (${startOfWord + 1}..$endOfWord)")
|
||||
return null
|
||||
}
|
||||
|
||||
val text = this.subSequence(startOfWord + 1, endOfWord).toString()
|
||||
val suggestionType = when (firstChar) {
|
||||
'@' -> SuggestionType.Mention
|
||||
|
||||
Reference in New Issue
Block a user