From 70b008d18da5a9a1a7f374d6dee65f418f12ea7e Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 23 Feb 2014 16:20:38 -0800 Subject: [PATCH] Add test coverage that our definition of BMP agrees with MySQL Summary: Ref T1191. Test that MySQL's rules match those of `phutil_is_utf8_with_only_bmp_characters()`: - Build a string with //every// character that we consider to be a BMP character. - Write it into MySQL. - Read it back out. - Make sure MySQL didn't truncate it. Test Plan: Ran unit test. This test runs pretty quickly (50ms), the string with every character isn't all that enormous. Reviewers: btrahan, arice Reviewed By: arice CC: chad, arice, aran Maniphest Tasks: T1191 Differential Revision: https://secure.phabricator.com/D8314 --- .../autopatches/20140223.bigutf8scratch.sql | 2 + .../storage/HarbormasterScratchTable.php | 1 + .../PhabricatorInfrastructureTestCase.php | 54 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 resources/sql/autopatches/20140223.bigutf8scratch.sql diff --git a/resources/sql/autopatches/20140223.bigutf8scratch.sql b/resources/sql/autopatches/20140223.bigutf8scratch.sql new file mode 100644 index 0000000000..43bd1891ce --- /dev/null +++ b/resources/sql/autopatches/20140223.bigutf8scratch.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_scratchtable + ADD bigData LONGTEXT COLLATE utf8_bin; diff --git a/src/applications/harbormaster/storage/HarbormasterScratchTable.php b/src/applications/harbormaster/storage/HarbormasterScratchTable.php index ad58120c85..518bdcdc5f 100644 --- a/src/applications/harbormaster/storage/HarbormasterScratchTable.php +++ b/src/applications/harbormaster/storage/HarbormasterScratchTable.php @@ -9,5 +9,6 @@ final class HarbormasterScratchTable extends HarbormasterDAO { protected $data; + protected $bigData; } diff --git a/src/infrastructure/__tests__/PhabricatorInfrastructureTestCase.php b/src/infrastructure/__tests__/PhabricatorInfrastructureTestCase.php index 70ba05bb4b..7697f344b1 100644 --- a/src/infrastructure/__tests__/PhabricatorInfrastructureTestCase.php +++ b/src/infrastructure/__tests__/PhabricatorInfrastructureTestCase.php @@ -3,6 +3,12 @@ final class PhabricatorInfrastructureTestCase extends PhabricatorTestCase { + protected function getPhabricatorTestCaseConfiguration() { + return array( + self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true, + ); + } + /** * This is more of an acceptance test case instead of a unittest. It verifies * that all symbols can be loaded correctly. It can catch problems like @@ -22,6 +28,54 @@ final class PhabricatorInfrastructureTestCase 'In test cases, all applications should default to installed.'); } + public function testMySQLAgreesWithUsAboutBMP() { + // Build a string with every BMP character in it, then insert it into MySQL + // and read it back. We expect to get the same string out that we put in, + // demonstrating that strings which pass our BMP checks are also valid in + // MySQL and no silent data truncation will occur. + + $buf = ''; + + for ($ii = 0x01; $ii <= 0x7F; $ii++) { + $buf .= chr($ii); + } + + for ($ii = 0xC2; $ii <= 0xDF; $ii++) { + for ($jj = 0x80; $jj <= 0xBF; $jj++) { + $buf .= chr($ii).chr($jj); + } + } + + // NOTE: This is \xE0\xA0\xZZ. + for ($ii = 0xE0; $ii <= 0xE0; $ii++) { + for ($jj = 0xA0; $jj <= 0xBF; $jj++) { + for ($kk = 0x80; $kk <= 0xBF; $kk++) { + $buf .= chr($ii).chr($jj).chr($kk); + } + } + } + + // NOTE: This is \xE1\xZZ\xZZ through \xEF\xZZ\xZZ. + for ($ii = 0xE1; $ii <= 0xEF; $ii++) { + for ($jj = 0x80; $jj <= 0xBF; $jj++) { + for ($kk = 0x80; $kk <= 0xBF; $kk++) { + $buf .= chr($ii).chr($jj).chr($kk); + } + } + } + + $this->assertEqual(194431, strlen($buf)); + $this->assertEqual(true, phutil_is_utf8_with_only_bmp_characters($buf)); + + $write = id(new HarbormasterScratchTable()) + ->setData('all.utf8.bmp') + ->setBigData($buf) + ->save(); + + $read = id(new HarbormasterScratchTable())->load($write->getID()); + + $this->assertEqual($buf, $read->getBigData()); + } }