Core: reject U+FEFF in emoji icon payloads to match the JS resolver

Python's validate_icon accepted emoji: (not str.isspace(), category
Cf) while the generated JS isEmojiPayload rejects it via \s, so the backend
could store a key the admin and panel silently fall back on. An exhaustive
code-point sweep shows U+FEFF is the only divergence; add it to the
forbidden set. ZWJ U+200D stays valid.

Add tools/icons/emoji-payload-cases.json, a shared verdict table asserted
by both tests/test_core_icons.py (validate_icon) and the admin Vitest
suite (resolveIcon), so any future divergence fails one of the suites.

Task: 8286a894-133f-4582-90fb-88f47eef6628 (review finding NQ-ICON-01)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 08:44:44 -04:00
co-authored by Claude Opus 5.5
parent 7eed8fdbf1
commit 23d21977c6
4 changed files with 101 additions and 4 deletions
+26
View File
@@ -0,0 +1,26 @@
{
"_comment": "Shared emoji-payload verdicts. tests/test_core_icons.py (validate_icon) and admin/src/icons/registry.test.ts (resolveIcon) both assert every row, so the Python and JS rules cannot diverge silently.",
"cases": [
{ "payload": "🐕", "valid": true, "why": "plain emoji" },
{ "payload": "👨‍👩‍👧‍👦", "valid": true, "why": "ZWJ family (U+200D allowed)" },
{ "payload": "⭐⭐⭐⭐⭐⭐⭐⭐", "valid": true, "why": "exactly 8 code points" },
{ "payload": "⭐⭐⭐⭐⭐⭐⭐⭐⭐", "valid": false, "why": "9 code points, over the cap" },
{ "payload": "", "valid": false, "why": "empty" },
{ "payload": "", "valid": false, "why": "U+FEFF BOM alone" },
{ "payload": "🐕", "valid": false, "why": "trailing U+FEFF" },
{ "payload": "🐕 ", "valid": false, "why": "trailing space" },
{ "payload": "a b", "valid": false, "why": "inner space" },
{ "payload": "🐕 ", "valid": false, "why": "no-break space" },
{ "payload": "🐕 ", "valid": false, "why": "ideographic space" },
{ "payload": "🐕
", "valid": false, "why": "line separator" },
{ "payload": "🐕\n", "valid": false, "why": "newline" },
{ "payload": "🐕\u0000", "valid": false, "why": "NUL control" },
{ "payload": "🐕\u0007🐕", "valid": false, "why": "BEL control" },
{ "payload": "🐕\u001c", "valid": false, "why": "file-separator control" },
{ "payload": "🐕\u0085", "valid": false, "why": "NEL C1 control" },
{ "payload": "🐕\u007f", "valid": false, "why": "DEL control" },
{ "payload": "<b>", "valid": false, "why": "markup <" },
{ "payload": "a>b", "valid": false, "why": "markup >" },
{ "payload": "a&b", "valid": false, "why": "entity start &" }
]
}