@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow a wider range of characters in macro names, including emoji

Summary:
Fixes T6121. See PHI357.

- Allow emoji and other unicode (like Chinese characters) as long as you have at least three of them.
- Disallow macros with only latin symbols. These were previously allowed.

Test Plan: Created a macro for "🐶🐶🐶", then used it in a comment.

Maniphest Tasks: T6121

Differential Revision: https://secure.phabricator.com/D19051

+90 -7
+2
src/__phutil_library_map__.php
··· 3203 3203 'PhabricatorMacroQuery' => 'applications/macro/query/PhabricatorMacroQuery.php', 3204 3204 'PhabricatorMacroReplyHandler' => 'applications/macro/mail/PhabricatorMacroReplyHandler.php', 3205 3205 'PhabricatorMacroSearchEngine' => 'applications/macro/query/PhabricatorMacroSearchEngine.php', 3206 + 'PhabricatorMacroTestCase' => 'applications/macro/xaction/__tests__/PhabricatorMacroTestCase.php', 3206 3207 'PhabricatorMacroTransaction' => 'applications/macro/storage/PhabricatorMacroTransaction.php', 3207 3208 'PhabricatorMacroTransactionComment' => 'applications/macro/storage/PhabricatorMacroTransactionComment.php', 3208 3209 'PhabricatorMacroTransactionQuery' => 'applications/macro/query/PhabricatorMacroTransactionQuery.php', ··· 8751 8752 'PhabricatorMacroQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 8752 8753 'PhabricatorMacroReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler', 8753 8754 'PhabricatorMacroSearchEngine' => 'PhabricatorApplicationSearchEngine', 8755 + 'PhabricatorMacroTestCase' => 'PhabricatorTestCase', 8754 8756 'PhabricatorMacroTransaction' => 'PhabricatorModularTransaction', 8755 8757 'PhabricatorMacroTransactionComment' => 'PhabricatorApplicationTransactionComment', 8756 8758 'PhabricatorMacroTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+1 -1
src/applications/macro/markup/PhabricatorImageMacroRemarkupRule.php
··· 8 8 9 9 public function apply($text) { 10 10 return preg_replace_callback( 11 - '@^\s*([a-zA-Z0-9:_\-]+)$@m', 11 + '@^\s*([a-zA-Z0-9:_\x7f-\xff-]+)$@m', 12 12 array($this, 'markupImageMacro'), 13 13 $text); 14 14 }
+41 -6
src/applications/macro/xaction/PhabricatorMacroNameTransaction.php
··· 52 52 new PhutilNumber($max_length))); 53 53 } 54 54 55 - if (!preg_match('/^[a-z0-9:_-]{3,}\z/', $new_value)) { 56 - $errors[] = $this->newInvalidError( 57 - pht('Macro name "%s" be at least three characters long and contain '. 58 - 'only lowercase letters, digits, hyphens, colons and '. 59 - 'underscores.', 60 - $new_value)); 55 + if (!self::isValidMacroName($new_value)) { 56 + // This says "emoji", but the actual rule we implement is "all other 57 + // unicode characters are also fine". 58 + $errors[] = $this->newInvalidError( 59 + pht( 60 + 'Macro name "%s" be: at least three characters long; and contain '. 61 + 'only lowercase letters, digits, hyphens, colons, underscores, '. 62 + 'and emoji; and not be composed entirely of latin symbols.', 63 + $new_value), 64 + $xaction); 61 65 } 62 66 63 67 // Check name is unique when updating / creating ··· 76 80 } 77 81 78 82 return $errors; 83 + } 84 + 85 + public static function isValidMacroName($name) { 86 + if (preg_match('/^[:_-]+\z/', $name)) { 87 + return false; 88 + } 89 + 90 + // Accept trivial macro names. 91 + if (preg_match('/^[a-z0-9:_-]{3,}\z/', $name)) { 92 + return true; 93 + } 94 + 95 + // Reject names with fewer than 3 glyphs. 96 + $length = phutil_utf8v_combined($name); 97 + if (count($length) < 3) { 98 + return false; 99 + } 100 + 101 + // Check character-by-character for any symbols that we don't want. 102 + $characters = phutil_utf8v($name); 103 + foreach ($characters as $character) { 104 + if (ord($character[0]) > 0x7F) { 105 + continue; 106 + } 107 + 108 + if (preg_match('/^[^a-z0-9:_-]/', $character)) { 109 + return false; 110 + } 111 + } 112 + 113 + return true; 79 114 } 80 115 81 116 }
+46
src/applications/macro/xaction/__tests__/PhabricatorMacroTestCase.php
··· 1 + <?php 2 + 3 + final class PhabricatorMacroTestCase 4 + extends PhabricatorTestCase { 5 + 6 + public function testMacroNames() { 7 + $lit = "\xF0\x9F\x94\xA5"; 8 + $combining_diaeresis = "\xCC\x88"; 9 + 10 + $cases = array( 11 + // Only 2 glyphs long. 12 + "u{$combining_diaeresis}n" => false, 13 + "{$lit}{$lit}" => false, 14 + 15 + // Too short. 16 + 'a' => false, 17 + '' => false, 18 + 19 + // Bad characters. 20 + 'yes!' => false, 21 + "{$lit} {$lit} {$lit}" => false, 22 + "aaa\nbbb" => false, 23 + 'aaa~' => false, 24 + 'aaa`' => false, 25 + 26 + // Special rejections for only latin symbols. 27 + '---' => false, 28 + '___' => false, 29 + '-_-' => false, 30 + ':::' => false, 31 + '-_:' => false, 32 + 33 + "{$lit}{$lit}{$lit}" => true, 34 + 'bwahahaha' => true, 35 + "u{$combining_diaeresis}nt" => true, 36 + 'a-a-a-a' => true, 37 + ); 38 + 39 + foreach ($cases as $input => $expect) { 40 + $this->assertEqual( 41 + $expect, 42 + PhabricatorMacroNameTransaction::isValidMacroName($input), 43 + pht('Validity of macro "%s"', $input)); 44 + } 45 + } 46 + }