Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.909 diff -u -p -r1.909 user.module --- modules/user/user.module 26 May 2008 17:12:55 -0000 1.909 +++ modules/user/user.module 5 Jun 2008 11:40:14 -0000 @@ -356,11 +356,21 @@ function user_save($account, $array = ar * Verify the syntax of the given name. */ function user_validate_name($name) { - if (!strlen($name)) return t('You must enter a username.'); - if (substr($name, 0, 1) == ' ') return t('The username cannot begin with a space.'); - if (substr($name, -1) == ' ') return t('The username cannot end with a space.'); - if (strpos($name, ' ') !== FALSE) return t('The username cannot contain multiple spaces in a row.'); - if (ereg("[^\x80-\xF7 [:alnum:]@_.-]", $name)) return t('The username contains an illegal character.'); + if (!$name) { + return t('You must enter a username.'); + } + if (substr($name, 0, 1) == ' ') { + return t('The username cannot begin with a space.'); + } + if (substr($name, -1) == ' ') { + return t('The username cannot end with a space.'); + } + if (strpos($name, ' ') !== FALSE) { + return t('The username cannot contain multiple spaces in a row.'); + } + if (preg_match('/[^\x{80}-\x{F7} a-z0-9@_.\'-]/i', $name)) { + return t('The username contains an illegal character.'); + } if (preg_match('/[\x{80}-\x{A0}' . // Non-printable ISO-8859-1 + NBSP '\x{AD}' . // Soft-hyphen '\x{2000}-\x{200F}' . // Various space characters @@ -369,12 +379,13 @@ function user_validate_name($name) { '\x{FEFF}' . // Byte order mark '\x{FF01}-\x{FF60}' . // Full-width latin '\x{FFF9}-\x{FFFD}' . // Replacement characters - '\x{0}]/u', // NULL byte + '\x{0}-\x{1F}]/u', // NULL byte and control characters $name)) { return t('The username contains an illegal character.'); } - if (strpos($name, '@') !== FALSE && !eregi('@([0-9a-z](-?[0-9a-z])*.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t('The username is not a valid authentication ID.'); - if (strlen($name) > USERNAME_MAX_LENGTH) return t('The username %name is too long: it must be %max characters or less.', array('%name' => $name, '%max' => USERNAME_MAX_LENGTH)); + if (drupal_strlen($name) > USERNAME_MAX_LENGTH) { + return t('The username %name is too long: it must be %max characters or less.', array('%name' => $name, '%max' => USERNAME_MAX_LENGTH)); + } } function user_validate_mail($mail) { @@ -1401,7 +1412,7 @@ function user_edit_form(&$form_state, $u '#title' => t('Username'), '#default_value' => $edit['name'], '#maxlength' => USERNAME_MAX_LENGTH, - '#description' => t('Spaces are allowed; punctuation is not allowed except for periods, hyphens, and underscores.'), + '#description' => t('Spaces are allowed; punctuation is not allowed except for periods, hyphens, apostrophes, and underscores.'), '#required' => TRUE, ); } Index: modules/user/user.test =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.test,v retrieving revision 1.5 diff -u -p -r1.5 user.test --- modules/user/user.test 2 Jun 2008 17:42:58 -0000 1.5 +++ modules/user/user.test 5 Jun 2008 11:40:14 -0000 @@ -116,47 +116,44 @@ class UserValidationTestCase extends Dru } // Username validation. - function testMinLengthName() { - $name = ''; - $result = user_validate_name($name); - $this->assertNotNull($result, 'Excessively short username'); - } - - function testValidCharsName() { - $name = 'ab/'; - $result = user_validate_name($name); - $this->assertNotNull($result, 'Invalid chars in username'); - } - - function testMaxLengthName() { - $name = str_repeat('a', 61); - $result = user_validate_name($name); - $this->assertNotNull($result, 'Excessively long username'); - } - - function testValidName() { - $name = 'abc'; - $result = user_validate_name($name); - $this->assertNull($result, 'Valid username'); - } - - // Mail validation. - function testMinLengthMail() { - $name = ''; - $result = user_validate_mail($name); - $this->assertNotNull($result, 'Empty mail'); - } - - function testInValidMail() { - $name = 'abc'; - $result = user_validate_mail($name); - $this->assertNotNull($result, 'Invalid mail'); + function testUsernames() { + $test_cases = array( // '' => array('', 'assert'), + 'foo' => array('Valid username', 'assertNull'), + 'FOO' => array('Valid username', 'assertNull'), + 'Foo O\'Bar' => array('Valid username', 'assertNull'), + 'foo@bar' => array('Valid username', 'assertNull'), + 'foo@example.com' => array('Valid username', 'assertNull'), + 'foo@-example.com' => array('Valid username', 'assertNull'), // invalid domains are allowed in usernames + 'þòøÇߪř€' => array('Valid username', 'assertNull'), + 'ᚠᛇᚻ᛫ᛒᛦᚦ' => array('Valid UTF8 username', 'assertNull'), // runes + ' foo' => array('Username that starts with a space', 'assertNotNull'), + 'foo ' => array('Username that ends with a space', 'assertNotNull'), + 'foo bar' => array('Username that contains 2 spaces \'  \'', 'assertNotNull'), + '' => array('Empty username', 'assertNotNull'), + 'foo/' => array('Invalid chars in username', 'assertNotNull'), + 'foo' . chr(0) . 'bar' => array('chr(0) in username', 'assertNotNull'), // NULL + 'foo' . chr(13) . 'bar' => array('chr(13) in username', 'assertNotNull'), // CR + str_repeat('x', USERNAME_MAX_LENGTH + 1) => array('Excessively long username', 'assertNotNull'), + ); + foreach ($test_cases as $name => $test_case) { + list($description, $test) = $test_case; + $result = user_validate_name($name); + $this->$test($result, $description . ' ('. $name . '). %s'); + } } - function testValidMail() { - $name = 'absdsdsdc@dsdsde.com'; - $result = user_validate_mail($name); - $this->assertNull($result, 'Valid mail'); + // Mail validation. More extensive tests can be found at common.test + function testMailAddresses() { + $test_cases = array( // '' => array('', 'assert'), + '' => array('Empty mail address', 'assertNotNull'), + 'foo' => array('Invalid mail address', 'assertNotNull'), + 'foo@example.com' => array('Valid mail address', 'assertNull'), + ); + foreach ($test_cases as $name => $test_case) { + list($description, $test) = $test_case; + $result = user_validate_mail($name); + $this->$test($result, $description . ' (' . $name . '). %s'); + } } } Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.211 diff -u -p -r1.211 bootstrap.inc --- includes/bootstrap.inc 26 May 2008 17:12:54 -0000 1.211 +++ includes/bootstrap.inc 5 Jun 2008 11:40:15 -0000 @@ -718,7 +718,7 @@ function referer_uri() { * Internet Explorer 6. */ function check_plain($text) { - return drupal_validate_utf8($text) ? htmlspecialchars($text, ENT_QUOTES) : ''; + return drupal_validate_utf8($text) ? htmlspecialchars($text, ENT_COMPAT) : ''; } /**