mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-10 16:33:27 +00:00
Merge pull request #3656 from davotoula/fix/bidi-control-literals
Replace raw bidi/invisible Unicode characters in source with \u escapes
This commit is contained in:
@@ -302,6 +302,21 @@ Do this before considering the task complete.
|
||||
`forEach`/`map`/`filter`/`any` — the `fast*` variants allocate no iterator,
|
||||
no intermediate list, and no lambda object. Don't "modernize" those into
|
||||
stdlib collection calls; match the surrounding hot-path style.
|
||||
- **Never put raw invisible/bidirectional Unicode characters in source files**
|
||||
— write them as `\uXXXX` escapes instead (`'\u202E'`, `Regex("[\u200B-\u200D\uFEFF]")`).
|
||||
This covers the bidi family Sonar's Trojan-Source rule (CVE-2021-42574)
|
||||
flags — U+202A–U+202E, the isolates U+2066–U+2069, U+200E/U+200F, U+061C —
|
||||
plus zero-width characters (U+200B–U+200D, U+FEFF, U+2060). The escape
|
||||
compiles to the identical codepoint, so behaviour is unchanged; the point is
|
||||
that the file on disk stays visually unambiguous. Applies even when the
|
||||
character is *intentional* (sanitizer strip-lists, adversarial test
|
||||
payloads) — that's data, and escapes express it just as well. Exceptions:
|
||||
U+200D as part of a real emoji ZWJ sequence in test data (👩👧 — functional,
|
||||
not a bidi control), and LRM/RLM inside Crowdin-managed `strings.xml`
|
||||
translations (legitimate RTL typography; don't touch those files by hand
|
||||
anyway). Note the tooling trap: the Edit tool may normalise a typed
|
||||
`\uXXXX` back into the raw character — if that happens, do the replacement
|
||||
at byte level (`perl -CSD -pe 's/\x{202E}/\\u202E/g'`).
|
||||
|
||||
### Navigation Shell
|
||||
- **Desktop**: Sidebar + main content area
|
||||
|
||||
+3
-3
@@ -215,9 +215,9 @@ class BlossomPaymentSafetyTest {
|
||||
|
||||
@Test
|
||||
fun reasonBidiOverridesAreRemoved() {
|
||||
val clean = challenge(invoice1000Sats, reason = "fee reversed text").sanitizedReason()!!
|
||||
assertFalse(clean.contains(''))
|
||||
assertFalse(clean.contains(''))
|
||||
val clean = challenge(invoice1000Sats, reason = "fee \u202Ereversed\u202C text").sanitizedReason()!!
|
||||
assertFalse(clean.contains('\u202E'))
|
||||
assertFalse(clean.contains('\u202C'))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@
|
||||
package com.vitorpamplona.amethyst.commons.moderation.notifications
|
||||
|
||||
private val CONTROL_CHARS = Regex("\\p{Cntrl}")
|
||||
private val RTL_OVERRIDES = Regex("[--]")
|
||||
private val ZERO_WIDTH = Regex("[-]")
|
||||
private val RTL_OVERRIDES = Regex("[\u202A-\u202E\u2066-\u2069]")
|
||||
private val ZERO_WIDTH = Regex("[\u200B-\u200D\uFEFF]")
|
||||
private val WHITESPACE = Regex("\\s+")
|
||||
private val URL_PATTERN = Regex("https?://\\S+")
|
||||
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ data class BlossomPaymentRequired(
|
||||
const val MAX_REASON_LENGTH = 200
|
||||
|
||||
/** LRE/RLE/PDF/LRO/RLO and the isolate family — invisible, and they reorder what follows. */
|
||||
private val BIDI_OVERRIDES = charArrayOf('', '', '', '', '', '', '', '', '', '', '')
|
||||
private val BIDI_OVERRIDES = charArrayOf('\u202A', '\u202B', '\u202C', '\u202D', '\u202E', '\u2066', '\u2067', '\u2068', '\u2069', '\u200F', '\u200E')
|
||||
|
||||
private val WHITESPACE_RUN = Regex("\\s+")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user