diff --git a/src/applications/auth/provider/PhabricatorAuthProviderOAuth1JIRA.php b/src/applications/auth/provider/PhabricatorAuthProviderOAuth1JIRA.php --- a/src/applications/auth/provider/PhabricatorAuthProviderOAuth1JIRA.php +++ b/src/applications/auth/provider/PhabricatorAuthProviderOAuth1JIRA.php @@ -114,7 +114,7 @@ if (!strlen($values[$key_name])) { $errors[] = pht('JIRA instance name is required.'); $issues[$key_name] = pht('Required'); - } else if (!preg_match('/^[a-z0-9.]+$/', $values[$key_name])) { + } else if (!preg_match('/^[a-z0-9.]+\z/', $values[$key_name])) { $errors[] = pht( 'JIRA instance name must contain only lowercase letters, digits, and '. 'period.'); diff --git a/src/applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php b/src/applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php --- a/src/applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php +++ b/src/applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php @@ -41,7 +41,7 @@ $commits = array_fill_keys($commits, array()); foreach ($commits as $name => $info) { $matches = null; - if (!preg_match('/^r([A-Z]+)([0-9a-f]+)$/', $name, $matches)) { + if (!preg_match('/^r([A-Z]+)([0-9a-f]+)\z/', $name, $matches)) { $results[$name] = array( 'error' => 'ERR-UNPARSEABLE', ); diff --git a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php b/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php --- a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php @@ -365,7 +365,7 @@ $c_call->setError(pht('Required')); $page->addPageError( pht('You must choose a callsign for this repository.')); - } else if (!preg_match('/^[A-Z]+$/', $v_call)) { + } else if (!preg_match('/^[A-Z]+\z/', $v_call)) { $c_call->setError(pht('Invalid')); $page->addPageError( pht('The callsign must contain only UPPERCASE letters.')); diff --git a/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php --- a/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php +++ b/src/applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php @@ -233,7 +233,7 @@ rtrim($repository->getLocalPath(), '/'), $path); - if (preg_match('(^/diffusion/[A-Z]+/$)', $path)) { + if (preg_match('(^/diffusion/[A-Z]+/\z)', $path)) { $path = rtrim($path, '/'); } diff --git a/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php --- a/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php +++ b/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php @@ -54,7 +54,7 @@ protected function loadRepository($path) { $viewer = $this->getUser(); - $regex = '@^/?diffusion/(?P[A-Z]+)(?:/|$)@'; + $regex = '@^/?diffusion/(?P[A-Z]+)(?:/|\z)@'; $matches = null; if (!preg_match($regex, $path, $matches)) { throw new Exception( diff --git a/src/applications/diviner/atom/DivinerAtomRef.php b/src/applications/diviner/atom/DivinerAtomRef.php --- a/src/applications/diviner/atom/DivinerAtomRef.php +++ b/src/applications/diviner/atom/DivinerAtomRef.php @@ -43,7 +43,7 @@ public function setName($name) { $normal_name = self::normalizeString($name); - if (preg_match('/^@[0-9]+$/', $normal_name)) { + if (preg_match('/^@[0-9]+\z/', $normal_name)) { throw new Exception( "Atom names must not be in the form '/@\d+/'. This pattern is ". "reserved for disambiguating atoms with similar names."); diff --git a/src/applications/diviner/workflow/DivinerWorkflow.php b/src/applications/diviner/workflow/DivinerWorkflow.php --- a/src/applications/diviner/workflow/DivinerWorkflow.php +++ b/src/applications/diviner/workflow/DivinerWorkflow.php @@ -52,7 +52,7 @@ } $book['root'] = Filesystem::resolvePath($book['root'], $full_path); - if (!preg_match('/^[a-z][a-z-]*$/', $book['name'])) { + if (!preg_match('/^[a-z][a-z-]*\z/', $book['name'])) { $name = $book['name']; throw new PhutilArgumentUsageException( "Book configuration '{$book_path}' has name '{$name}', but book names ". diff --git a/src/applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php b/src/applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php --- a/src/applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php +++ b/src/applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php @@ -113,7 +113,7 @@ // Make sure there's no funny business going on here. Users normally have // no ability to affect the content of handles, but double-check that // we're only accessing local storage just in case. - if (!preg_match('@^[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{28}$@', $handle)) { + if (!preg_match('@^[a-f0-9]{2}/[a-f0-9]{2}/[a-f0-9]{28}\z@', $handle)) { throw new Exception( "Local disk filesystem handle '{$handle}' is malformed!"); } diff --git a/src/applications/macro/controller/PhabricatorMacroEditController.php b/src/applications/macro/controller/PhabricatorMacroEditController.php --- a/src/applications/macro/controller/PhabricatorMacroEditController.php +++ b/src/applications/macro/controller/PhabricatorMacroEditController.php @@ -48,7 +48,7 @@ if (!strlen($macro->getName())) { $errors[] = pht('Macro name is required.'); $e_name = pht('Required'); - } else if (!preg_match('/^[a-z0-9:_-]{3,}$/', $macro->getName())) { + } else if (!preg_match('/^[a-z0-9:_-]{3,}\z/', $macro->getName())) { $errors[] = pht( 'Macro must be at least three characters long and contain only '. 'lowercase letters, digits, hyphens, colons and underscores.'); diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php --- a/src/applications/people/storage/PhabricatorUser.php +++ b/src/applications/people/storage/PhabricatorUser.php @@ -610,7 +610,7 @@ return false; } - return (bool)preg_match('/^[a-zA-Z0-9._-]*[a-zA-Z0-9_-]$/', $username); + return (bool)preg_match('/^[a-zA-Z0-9._-]*[a-zA-Z0-9_-]\z/', $username); } public static function getDefaultProfileImageURI() { diff --git a/src/applications/people/storage/PhabricatorUserEmail.php b/src/applications/people/storage/PhabricatorUserEmail.php --- a/src/applications/people/storage/PhabricatorUserEmail.php +++ b/src/applications/people/storage/PhabricatorUserEmail.php @@ -49,7 +49,7 @@ // To this end, we're roughly verifying that there's some normal text, an // "@" symbol, and then some more normal text. - $email_regex = '(^[a-z0-9_+.!-]+@[a-z0-9_+:.-]+$)i'; + $email_regex = '(^[a-z0-9_+.!-]+@[a-z0-9_+:.-]+\z)i'; if (!preg_match($email_regex, $address)) { return false; } diff --git a/src/applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php b/src/applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php --- a/src/applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php +++ b/src/applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php @@ -27,6 +27,13 @@ '@@' => false, '@' => false, 'user@' => false, + + "user@domain.com\n" => false, + "user@\ndomain.com" => false, + "\nuser@domain.com" => false, + "user@domain.com\r" => false, + "user@\rdomain.com" => false, + "\ruser@domain.com" => false, ); foreach ($tests as $input => $expect) { diff --git a/src/applications/people/storage/__tests__/PhabricatorUserTestCase.php b/src/applications/people/storage/__tests__/PhabricatorUserTestCase.php --- a/src/applications/people/storage/__tests__/PhabricatorUserTestCase.php +++ b/src/applications/people/storage/__tests__/PhabricatorUserTestCase.php @@ -36,6 +36,13 @@ 'a,lincoln' => false, 'a&lincoln' => false, 'a/lincoln' => false, + + "username\n" => false, + "user\nname" => false, + "\nusername" => false, + "username\r" => false, + "user\rname" => false, + "\rusername" => false, ); foreach ($map as $name => $expect) { diff --git a/src/applications/phlux/controller/PhluxEditController.php b/src/applications/phlux/controller/PhluxEditController.php --- a/src/applications/phlux/controller/PhluxEditController.php +++ b/src/applications/phlux/controller/PhluxEditController.php @@ -48,7 +48,7 @@ if (!strlen($key)) { $errors[] = pht('Variable key is required.'); $e_key = pht('Required'); - } else if (!preg_match('/^[a-z0-9.-]+$/', $key)) { + } else if (!preg_match('/^[a-z0-9.-]+\z/', $key)) { $errors[] = pht( 'Variable key "%s" must contain only lowercase letters, digits, '. 'period, and hyphen.', diff --git a/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php b/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php --- a/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php +++ b/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php @@ -79,7 +79,7 @@ $repository->setName($request->getValue('name')); $callsign = $request->getValue('callsign'); - if (!preg_match('/^[A-Z]+$/', $callsign)) { + if (!preg_match('/^[A-Z]+\z/', $callsign)) { throw new ConduitException('ERR-BAD-CALLSIGN'); } $repository->setCallsign($callsign);