mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-02 06:09:39 +02:00
fix(download): stop crashing native finalization on Android regex
Android's regex engine rejects Pattern.UNICODE_CHARACTER_CLASS, so NativeFinalizationPolicy failed to initialize and every native download crashed while writing metadata. List Unicode spaces explicitly and cover the separator with a device test.
This commit is contained in:
1 parent
ceb98eb766
commit
fbf479c102
3 files changed
+43
-7
No files matched your search
+30
@@ -0,0 +1,30 @@
|
||||
package com.zarz.spotiflac
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/**
|
||||
* Runs on Android's own regex engine: the JVM accepts regex flags that the
|
||||
* device rejects when NativeFinalizationPolicy initializes during finalization.
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class NativeFinalizationPolicyDeviceTest {
|
||||
@Test
|
||||
fun primaryArtistSeparatorCompilesAndSplitsOnDevice() {
|
||||
for ((input, expected) in listOf(
|
||||
"Calle 24, Chino Pacas" to "Calle 24",
|
||||
"Artist A feat. Artist B" to "Artist A",
|
||||
"Artist A\u00A0feat.\u00A0Artist B" to "Artist A",
|
||||
"Artist A\u3000x\u3000Artist B" to "Artist A",
|
||||
"Malcolm X" to "Malcolm X",
|
||||
)) {
|
||||
assertEquals(input, expected, NativeFinalizationPolicy.artistTagValue(input, "primary"))
|
||||
}
|
||||
assertEquals(
|
||||
"Artist A, Artist B",
|
||||
NativeFinalizationPolicy.artistTagValue("Artist A, Artist B", "joined"),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.zarz.spotiflac
|
||||
|
||||
import java.util.Locale
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@@ -374,12 +373,17 @@ internal object NativeFinalizationPolicy {
|
||||
?: ""
|
||||
}
|
||||
|
||||
// Same separator set as the Rust writer and Dart's primaryArtistTagValue;
|
||||
// Unicode classes keep \s aligned with their whitespace handling.
|
||||
private val primaryArtistSeparator = Pattern.compile(
|
||||
"\\s*[,;&]\\s*|\\s+x\\s+|\\s+(?:feat(?:uring)?|ft|with)\\.?(?:\\s+|$)",
|
||||
Pattern.CASE_INSENSITIVE or Pattern.UNICODE_CHARACTER_CLASS,
|
||||
).toRegex()
|
||||
// Same separator set as the Rust writer and Dart's primaryArtistTagValue.
|
||||
// Android's regex engine rejects Pattern.UNICODE_CHARACTER_CLASS when this
|
||||
// object initializes, so Unicode spaces are listed explicitly instead.
|
||||
private const val PRIMARY_ARTIST_SPACE = "[\\s\\p{Z}]"
|
||||
private val primaryArtistSeparator = Regex(
|
||||
"$PRIMARY_ARTIST_SPACE*[,;&]$PRIMARY_ARTIST_SPACE*" +
|
||||
"|$PRIMARY_ARTIST_SPACE+x$PRIMARY_ARTIST_SPACE+" +
|
||||
"|$PRIMARY_ARTIST_SPACE+(?:feat(?:uring)?|ft|with)\\.?" +
|
||||
"(?:$PRIMARY_ARTIST_SPACE+|$)",
|
||||
RegexOption.IGNORE_CASE,
|
||||
)
|
||||
|
||||
/**
|
||||
* Artist tag value for [mode]. Only "primary" changes the value: the first
|
||||
|
||||
@@ -21,6 +21,8 @@ class NativeFinalizationPolicyTest {
|
||||
"Artist A with Artist B" to "Artist A",
|
||||
"Artist A x Artist B" to "Artist A",
|
||||
"Artist A X Artist B" to "Artist A",
|
||||
"Artist A\u00A0feat.\u00A0Artist B" to "Artist A",
|
||||
"Artist A\u3000x\u3000Artist B" to "Artist A",
|
||||
" , Artist A, Artist B" to "Artist A",
|
||||
"Malcolm X" to "Malcolm X",
|
||||
"Artist Without Fear" to "Artist Without Fear",
|
||||
|
||||
Reference in new issue
Block a user