mirror of
https://github.com/modrinth/code.git
synced 2026-08-30 19:46:33 +00:00
feat: hook up validators with input fields
This commit is contained in:
@@ -47,6 +47,7 @@ const PRIVATE_USE_PATTERN = /\p{Co}/u
|
||||
const UNASSIGNED_PATTERN = /\p{Cn}/u
|
||||
const LETTER_PATTERN = /\p{L}/u
|
||||
const EXTENDED_PICTOGRAPHIC_PATTERN = /\p{Extended_Pictographic}/u
|
||||
const EMOJI_PRESENTATION_PATTERN = /\p{Emoji_Presentation}/u
|
||||
const UNIFIED_IDEOGRAPH_PATTERN = /\p{Unified_Ideograph}/u
|
||||
|
||||
function createCounts(): Record<NonStandardTextIssueKind, number> {
|
||||
@@ -75,6 +76,10 @@ function isEmojiModifier(codePoint: number) {
|
||||
return codePoint >= 0x1f3fb && codePoint <= 0x1f3ff
|
||||
}
|
||||
|
||||
function isEmojiTag(codePoint: number) {
|
||||
return codePoint >= 0xe0020 && codePoint <= 0xe007f
|
||||
}
|
||||
|
||||
function isAscii(character: string) {
|
||||
return character.codePointAt(0)! <= 0x7f
|
||||
}
|
||||
@@ -129,6 +134,24 @@ function isAllowedVariationSelector(
|
||||
return UNIFIED_IDEOGRAPH_PATTERN.test(previous)
|
||||
}
|
||||
|
||||
function isAllowedEmojiTagSequence(characters: readonly string[], characterIndex: number) {
|
||||
let start = characterIndex - 1
|
||||
while (start >= 0 && isEmojiTag(characters[start].codePointAt(0)!)) start--
|
||||
if (characters[start]?.codePointAt(0) !== 0x1f3f4) return false
|
||||
|
||||
let end = characterIndex
|
||||
while (end < characters.length && isEmojiTag(characters[end].codePointAt(0)!)) end++
|
||||
return characters[end - 1]?.codePointAt(0) === 0xe007f
|
||||
}
|
||||
|
||||
function isPresentedAsEmoji(characters: readonly string[], characterIndex: number) {
|
||||
const character = characters[characterIndex]
|
||||
return (
|
||||
EMOJI_PRESENTATION_PATTERN.test(character) ||
|
||||
characters[characterIndex + 1]?.codePointAt(0) === 0xfe0f
|
||||
)
|
||||
}
|
||||
|
||||
function codePointLabel(codePoint: number) {
|
||||
return `U+${codePoint.toString(16).toUpperCase().padStart(4, '0')}`
|
||||
}
|
||||
@@ -200,7 +223,8 @@ export function validateNonStandardText(
|
||||
if (FORMAT_PATTERN.test(character)) {
|
||||
const allowed =
|
||||
(codePoint === 0x200c && isAllowedZeroWidthNonJoiner(characters, characterIndex)) ||
|
||||
(codePoint === 0x200d && isAllowedZeroWidthJoiner(characters, characterIndex))
|
||||
(codePoint === 0x200d && isAllowedZeroWidthJoiner(characters, characterIndex)) ||
|
||||
(isEmojiTag(codePoint) && isAllowedEmojiTagSequence(characters, characterIndex))
|
||||
if (!allowed) addIssue('invisible', character, codePoint, currentIndex)
|
||||
hasBaseCharacter = false
|
||||
combiningMarkCount = 0
|
||||
@@ -225,7 +249,7 @@ export function validateNonStandardText(
|
||||
combiningMarkCount = 0
|
||||
hasBaseCharacter = !/^\s$/u.test(character)
|
||||
|
||||
if (isInRanges(codePoint, FANCY_RANGES)) {
|
||||
if (isInRanges(codePoint, FANCY_RANGES) && !isPresentedAsEmoji(characters, characterIndex)) {
|
||||
addIssue('fancy', character, codePoint, currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ test('allows ordinary emoji and valid emoji joiner sequences', () => {
|
||||
assert.equal(validateNonStandardText('Family: 👨👩👧👦').valid, true)
|
||||
assert.equal(validateNonStandardText('Developer: 🧑🏽💻').valid, true)
|
||||
assert.equal(validateNonStandardText('Heart: ❤️').valid, true)
|
||||
assert.equal(validateNonStandardText('Information: ℹ️').valid, true)
|
||||
assert.equal(validateNonStandardText('A button: 🅰️').valid, true)
|
||||
assert.equal(validateNonStandardText('Scotland: 🏴').valid, true)
|
||||
})
|
||||
|
||||
test('detects suspicious invisible and directional characters', () => {
|
||||
|
||||
@@ -499,7 +499,7 @@ function findAt(root: TrieNode, text: string, start: number): ProfanityMatch | u
|
||||
const matchesNegative = current.negatives.some((negative) =>
|
||||
negativeMatches(negative, text, start, end),
|
||||
)
|
||||
if (matchesNegative && current.children.size === 0) return undefined
|
||||
if (matchesNegative) continue
|
||||
|
||||
return {
|
||||
kind: current.terminal.kind,
|
||||
|
||||
@@ -57,7 +57,7 @@ test('uses the first terminal when one configured term prefixes another', () =>
|
||||
})
|
||||
|
||||
test('does not match configured false-positive substrings', () => {
|
||||
assert.equal(validateProfanity('Scunthorpe and peacock').valid, true)
|
||||
assert.equal(validateProfanity('Scunthorpe, Clitheroe, and peacock').valid, true)
|
||||
assert.equal(validateProfanity('cock and cunt').profanityCount, 2)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user