@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

When "utf8mb4" is available, use it as the default client charset when invoking standalone "mysql" commands

Summary:
Fixes T13390. We have some old code which doesn't dynamically select between "utf8mb4" and "utf8". This can lead to dumping utf8mb4 data over a utf8 connection in `bin/storage dump`, which possibly corrupts some emoji/whales.

Instead, prefer "utf8mb4" if it's available.

Test Plan: Ran `bin/storage dump` and `bin/storage shell`, saw sub-commands select utf8mb4 as the client charset.

Maniphest Tasks: T13390

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

+13 -3
+8
src/infrastructure/storage/management/PhabricatorStorageManagementAPI.php
··· 298 298 return self::isCharacterSetAvailableOnConnection($character_set, $conn); 299 299 } 300 300 301 + public function getClientCharset() { 302 + if ($this->isCharacterSetAvailable('utf8mb4')) { 303 + return 'utf8mb4'; 304 + } else { 305 + return 'utf8'; 306 + } 307 + } 308 + 301 309 public static function isCharacterSetAvailableOnConnection( 302 310 $character_set, 303 311 AphrontDatabaseConnection $conn) {
+3 -1
src/infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php
··· 179 179 $argv = array(); 180 180 $argv[] = '--hex-blob'; 181 181 $argv[] = '--single-transaction'; 182 - $argv[] = '--default-character-set=utf8'; 182 + 183 + $argv[] = '--default-character-set'; 184 + $argv[] = $api->getClientCharset(); 183 185 184 186 if ($args->getArg('for-replica')) { 185 187 $argv[] = '--master-data';
+2 -2
src/infrastructure/storage/management/workflow/PhabricatorStorageManagementShellWorkflow.php
··· 31 31 } 32 32 33 33 return phutil_passthru( 34 - 'mysql --protocol=TCP --default-character-set=utf8mb4 '. 35 - '-u %s %C -h %s %C', 34 + 'mysql --protocol=TCP --default-character-set %R -u %s %C -h %s %C', 35 + $api->getClientCharset(), 36 36 $api->getUser(), 37 37 $flag_password, 38 38 $host,