diff --git a/phpBB/config/default/container/services_profilefield.yml b/phpBB/config/default/container/services_profilefield.yml index ebbd3fbf8e..c0ef5ec7e4 100644 --- a/phpBB/config/default/container/services_profilefield.yml +++ b/phpBB/config/default/container/services_profilefield.yml @@ -82,6 +82,7 @@ services: profilefields.type.string: class: phpbb\profilefields\type\type_string arguments: + - '@auth' - '@request' - '@template' - '@user' @@ -91,6 +92,7 @@ services: profilefields.type.text: class: phpbb\profilefields\type\type_text arguments: + - '@auth' - '@request' - '@template' - '@user' @@ -100,6 +102,7 @@ services: profilefields.type.url: class: phpbb\profilefields\type\type_url arguments: + - '@auth' - '@request' - '@template' - '@user' diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php index 5daa61076c..5784a1212a 100644 --- a/phpBB/phpbb/profilefields/manager.php +++ b/phpBB/phpbb/profilefields/manager.php @@ -254,6 +254,17 @@ class manager /** @var \phpbb\profilefields\type\type_interface $profile_field */ $profile_field = $this->type_collection[$row['field_type']]; $cp_data['pf_' . $row['field_ident']] = $profile_field->get_profile_field($row); + + /** + * Replace Emojis and other 4bit UTF-8 chars not allowed by MySQL with UCR/NCR + * using their Numeric Character Reference's Hexadecimal notation. + * Check the permissions for using Emojis first. + */ + if ($this->auth->acl_get('u_emoji')) + { + $cp_data['pf_' . $row['field_ident']] = utf8_encode_ucr($cp_data['pf_' . $row['field_ident']]); + } + $check_value = $cp_data['pf_' . $row['field_ident']]; if (($cp_result = $profile_field->validate_profile_field($check_value, $row)) !== false) diff --git a/phpBB/phpbb/profilefields/type/type_string.php b/phpBB/phpbb/profilefields/type/type_string.php index 8710c8c603..289d78228a 100644 --- a/phpBB/phpbb/profilefields/type/type_string.php +++ b/phpBB/phpbb/profilefields/type/type_string.php @@ -15,6 +15,12 @@ namespace phpbb\profilefields\type; class type_string extends type_string_common { + /** + * Auth object + * @var \phpbb\auth\auth + */ + protected $auth; + /** * Request object * @var \phpbb\request\request @@ -36,12 +42,14 @@ class type_string extends type_string_common /** * Construct * + * @param \phpbb\auth\auth $auth Auth object * @param \phpbb\request\request $request Request object * @param \phpbb\template\template $template Template object * @param \phpbb\user $user User object */ - public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + public function __construct(\phpbb\auth\auth $auth, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) { + $this->auth = $auth; $this->request = $request; $this->template = $template; $this->user = $user; @@ -99,6 +107,17 @@ class type_string extends type_string_common */ public function validate_profile_field(&$field_value, $field_data) { + /** + * Check for out-of-bounds characters that are currently + * not supported by utf8_bin in MySQL if Emoji is not allowed + */ + if (!$this->auth->acl_get('u_emoji')) + { + if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $field_value)) + { + return $this->user->lang('FIELD_INVALID_CHARS_INVALID', $this->get_field_name($field_data['lang_name'])); + } + } return $this->validate_string_profile_field('string', $field_value, $field_data); } diff --git a/phpBB/phpbb/profilefields/type/type_text.php b/phpBB/phpbb/profilefields/type/type_text.php index 79ee82351a..a2e2167ac5 100644 --- a/phpBB/phpbb/profilefields/type/type_text.php +++ b/phpBB/phpbb/profilefields/type/type_text.php @@ -15,6 +15,12 @@ namespace phpbb\profilefields\type; class type_text extends type_string_common { + /** + * Auth object + * @var \phpbb\auth\auth + */ + protected $auth; + /** * Request object * @var \phpbb\request\request @@ -36,12 +42,14 @@ class type_text extends type_string_common /** * Construct * + * @param \phpbb\auth\auth $auth Auth object * @param \phpbb\request\request $request Request object * @param \phpbb\template\template $template Template object * @param \phpbb\user $user User object */ - public function __construct(\phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) + public function __construct(\phpbb\auth\auth $auth, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user) { + $this->auth = $auth; $this->request = $request; $this->template = $template; $this->user = $user; @@ -99,6 +107,17 @@ class type_text extends type_string_common */ public function validate_profile_field(&$field_value, $field_data) { + /** + * Check for out-of-bounds characters that are currently + * not supported by utf8_bin in MySQL if Emoji is not allowed + */ + if (!$this->auth->acl_get('u_emoji')) + { + if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $field_value)) + { + return $this->user->lang('FIELD_INVALID_CHARS_INVALID', $this->get_field_name($field_data['lang_name'])); + } + } return $this->validate_string_profile_field('text', $field_value, $field_data); } diff --git a/tests/profilefields/type_string_test.php b/tests/profilefields/type_string_test.php index 54bb406838..d7ad16895d 100644 --- a/tests/profilefields/type_string_test.php +++ b/tests/profilefields/type_string_test.php @@ -26,6 +26,7 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case { global $config, $request, $user, $cache, $phpbb_root_path, $phpEx; + $auth = new \phpbb\auth\auth(); $user = $this->getMock('\phpbb\user', array(), array( new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), '\phpbb\datetime' @@ -40,6 +41,7 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case $template = $this->getMock('\phpbb\template\template'); $this->cp = new \phpbb\profilefields\type\type_string( + $auth, $request, $template, $user diff --git a/tests/profilefields/type_url_test.php b/tests/profilefields/type_url_test.php index 3bb5d52899..f592d1099d 100644 --- a/tests/profilefields/type_url_test.php +++ b/tests/profilefields/type_url_test.php @@ -30,6 +30,7 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case { global $config, $request, $user, $cache, $phpbb_root_path, $phpEx; + $auth = new \phpbb\auth\auth(); $config = new \phpbb\config\config([]); $cache = new phpbb_mock_cache; $user = $this->getMock('\phpbb\user', array(), array( @@ -44,6 +45,7 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case $template = $this->getMock('\phpbb\template\template'); $this->cp = new \phpbb\profilefields\type\type_url( + $auth, $request, $template, $user