diff --git a/src/applications/phriction/storage/PhrictionDocument.php b/src/applications/phriction/storage/PhrictionDocument.php index f2060af2bf..0c553fdfab 100644 --- a/src/applications/phriction/storage/PhrictionDocument.php +++ b/src/applications/phriction/storage/PhrictionDocument.php @@ -42,6 +42,10 @@ final class PhrictionDocument extends PhrictionDAO if ($slug == '/') { return $prefix; } else { + // NOTE: The effect here is to escape non-latin characters, since modern + // browsers deal with escaped UTF8 characters in a reasonable way (showing + // the user a readable URI) but older programs may not. + $slug = phutil_escape_uri($slug); return $prefix.$slug; } } diff --git a/src/infrastructure/util/PhabricatorSlug.php b/src/infrastructure/util/PhabricatorSlug.php index 0a95579218..9dfff16251 100644 --- a/src/infrastructure/util/PhabricatorSlug.php +++ b/src/infrastructure/util/PhabricatorSlug.php @@ -3,14 +3,11 @@ final class PhabricatorSlug { public static function normalize($slug) { - - // TODO: We need to deal with unicode at some point, this is just a very - // basic proof-of-concept implementation. - - $slug = strtolower($slug); $slug = preg_replace('@/+@', '/', $slug); $slug = trim($slug, '/'); - $slug = preg_replace('@[^a-z0-9/]+@', '_', $slug); + $slug = phutil_utf8_strtolower($slug); + $slug = preg_replace("@[\\x00-\\x19#%&+=\\\\?<> ]+@", '_', $slug); + $slug = preg_replace('@_+@', '_', $slug); $slug = trim($slug, '_'); return $slug.'/'; @@ -20,8 +17,8 @@ final class PhabricatorSlug { $parts = explode('/', trim($slug, '/')); $default_title = end($parts); $default_title = str_replace('_', ' ', $default_title); - $default_title = ucwords($default_title); - $default_title = nonempty($default_title, 'Untitled Document'); + $default_title = phutil_utf8_ucwords($default_title); + $default_title = nonempty($default_title, pht('Untitled Document')); return $default_title; } diff --git a/src/infrastructure/util/__tests__/PhabricatorSlugTestCase.php b/src/infrastructure/util/__tests__/PhabricatorSlugTestCase.php index 735727ac01..03b95f239c 100644 --- a/src/infrastructure/util/__tests__/PhabricatorSlugTestCase.php +++ b/src/infrastructure/util/__tests__/PhabricatorSlugTestCase.php @@ -13,8 +13,10 @@ final class PhabricatorSlugTestCase extends PhabricatorTestCase { 'derp//derp' => 'derp/derp/', 'DERP//DERP' => 'derp/derp/', 'a B c' => 'a_b_c/', - '-1~2.3abcd' => '1_2_3abcd/', - "T\x95O\x95D\x95O" => 't_o_d_o/', + '-1~2.3abcd' => '-1~2.3abcd/', + "T\x00O\x00D\x00O" => "t_o_d_o/", + 'x#%&+=\\?<> y' => 'x_y/', + "\xE2\x98\x83" => "\xE2\x98\x83/", ); foreach ($slugs as $slug => $normal) {