1
0
mirror of https://github.com/tuskyapp/Tusky synced 2025-01-26 16:55:38 +01:00

Simplify hashtag line checker to avoid infinite loop in android matcher (#4779)

https://masto.nyc/@GetMisch/113557332197065306 causes an infinite loop
in the native matcher with the original pattern, trying a different
approach
This commit is contained in:
Levi Bard 2024-12-04 17:08:05 +01:00 committed by GitHub
parent 96ed6e14b0
commit af5d10cd09
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 3 additions and 6 deletions

View File

@ -119,9 +119,8 @@ fun setClickableText(
}
}
private val trailingHashtagExpression by unsafeLazy {
Pattern.compile("""$WORD_BREAK_EXPRESSION(#$HASHTAG_EXPRESSION$WORD_BREAK_FROM_SPACE_EXPRESSION+)*""", Pattern.CASE_INSENSITIVE)
}
private val hashtagWithHashPattern = Pattern.compile("^#$HASHTAG_EXPRESSION$")
private val whitespacePattern = Regex("""\s+""")
/**
* Find the "trailing" hashtags in spanned content
@ -131,7 +130,7 @@ private val trailingHashtagExpression by unsafeLazy {
internal fun getTrailingHashtags(content: Spanned): Pair<Int, List<HashTag>> {
// split() instead of lines() because we need to be able to account for the length of the removed delimiter
val trailingContentLength = content.split('\r', '\n').asReversed().takeWhile { line ->
line.isBlank() || trailingHashtagExpression.matcher(line).matches()
line.splitToSequence(whitespacePattern).all { it.isBlank() || hashtagWithHashPattern.matcher(it).matches() }
}.sumOf { it.length + 1 } // length + 1 to include the stripped line ending character
return when (trailingContentLength) {

View File

@ -8,8 +8,6 @@ import kotlin.random.Random
private const val POSSIBLE_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const val WORD_BREAK_EXPRESSION = """(^|$|[^\p{L}\p{N}_])"""
const val WORD_BREAK_FROM_SPACE_EXPRESSION = """(^|$|\s)"""
const val HASHTAG_EXPRESSION = "([\\w_]*[\\p{Alpha}_][\\w_]*)"
val hashtagPattern = Pattern.compile(HASHTAG_EXPRESSION, Pattern.CASE_INSENSITIVE or Pattern.MULTILINE)