/** * Filters one attribute only and ensures its value is allowed. * * This function has the advantage of being more secure than esc_attr() and can * escape data in some situations where hq_kses() must strip the whole attribute. * * @since 0.0.1 * * @param string $string The 'whole' attribute, including name and value. * @param string $element The element name to which the attribute belongs. * @return string Filtered attribute. */ function hq_kses_one_attr($string, $element) { $uris = array('xmlns', 'profile', 'href', 'src', 'cite', 'classid', 'codebase', 'data', 'usemap', 'longdesc', 'action'); $allowed_html = hq_kses_allowed_html('post'); $allowed_protocols = hq_allowed_protocols(); $string = hq_kses_no_null($string, array('slash_zero' => 'keep')); $string = hq_kses_js_entities($string); // Preserve leading and trailing whitespace. $matches = array(); preg_match('/^\\s*/', $string, $matches); $lead = $matches[0]; preg_match('/\\s*$/', $string, $matches); $trail = $matches[0]; if (empty($trail)) { $string = substr($string, strlen($lead)); } else { $string = substr($string, strlen($lead), -strlen($trail)); } // Parse attribute name and value from input. $split = preg_split('/\\s*=\\s*/', $string, 2); $name = $split[0]; if (count($split) == 2) { $value = $split[1]; // Remove quotes surrounding $value. // Also guarantee correct quoting in $string for this one attribute. if ('' == $value) { $quote = ''; } else { $quote = $value[0]; } if ('"' == $quote || "'" == $quote) { if (substr($value, -1) != $quote) { return ''; } $value = substr($value, 1, -1); } else { $quote = '"'; } // Sanitize quotes, angle braces, and entities. $value = esc_attr($value); // Sanitize URI values. if (in_array(strtolower($name), $uris)) { $value = hq_kses_bad_protocol($value, $allowed_protocols); } $string = "{$name}={$quote}{$value}{$quote}"; $vless = 'n'; } else { $value = ''; $vless = 'y'; } // Sanitize attribute by name. hq_kses_attr_check($name, $value, $string, $vless, $element, $allowed_html); // Restore whitespace. return $lead . $string . $trail; }
/** * Callback to add a base url to relative links in passed content. * * @since 0.0.1 * @access private * * @global string $_links_add_base * * @param string $m The matched link. * @return string The processed link. */ function _links_add_base($m) { global $_links_add_base; //1 = attribute name 2 = quotation mark 3 = URL return $m[1] . '=' . $m[2] . (preg_match('#^(\\w{1,20}):#', $m[3], $protocol) && in_array($protocol[1], hq_allowed_protocols()) ? $m[3] : HQ_HTTP::make_absolute_url($m[3], $_links_add_base)) . $m[2]; }
/** * Edit user settings based on contents of $_POST * * Used on user-edit.php and profile.php to manage and process user options, passwords etc. * * @since 0.0.1 * * @param int $user_id Optional. User ID. * @return int|HQ_Error user id of the updated user */ function edit_user($user_id = 0) { $hq_roles = hq_roles(); $user = new stdClass(); if ($user_id) { $update = true; $user->ID = (int) $user_id; $userdata = get_userdata($user_id); $user->user_login = hq_slash($userdata->user_login); } else { $update = false; } if (!$update && isset($_POST['user_login'])) { $user->user_login = sanitize_user($_POST['user_login'], true); } $pass1 = $pass2 = ''; if (isset($_POST['pass1'])) { $pass1 = $_POST['pass1']; } if (isset($_POST['pass2'])) { $pass2 = $_POST['pass2']; } if (isset($_POST['role']) && current_user_can('edit_users')) { $new_role = sanitize_text_field($_POST['role']); $potential_role = isset($hq_roles->role_objects[$new_role]) ? $hq_roles->role_objects[$new_role] : false; // Don't let anyone with 'edit_users' (admins) edit their own role to something without it. // Multisite super admins can freely edit their blog roles -- they possess all caps. if (is_multisite() && current_user_can('manage_sites') || $user_id != get_current_user_id() || $potential_role && $potential_role->has_cap('edit_users')) { $user->role = $new_role; } // If the new role isn't editable by the logged-in user die with error $editable_roles = get_editable_roles(); if (!empty($new_role) && empty($editable_roles[$new_role])) { hq_die(__('You can’t give users that role.')); } } if (isset($_POST['email'])) { $user->user_email = sanitize_text_field(hq_unslash($_POST['email'])); } if (isset($_POST['url'])) { if (empty($_POST['url']) || $_POST['url'] == 'http://') { $user->user_url = ''; } else { $user->user_url = esc_url_raw($_POST['url']); $protocols = implode('|', array_map('preg_quote', hq_allowed_protocols())); $user->user_url = preg_match('/^(' . $protocols . '):/is', $user->user_url) ? $user->user_url : 'http://' . $user->user_url; } } if (isset($_POST['first_name'])) { $user->first_name = sanitize_text_field($_POST['first_name']); } if (isset($_POST['last_name'])) { $user->last_name = sanitize_text_field($_POST['last_name']); } if (isset($_POST['nickname'])) { $user->nickname = sanitize_text_field($_POST['nickname']); } if (isset($_POST['display_name'])) { $user->display_name = sanitize_text_field($_POST['display_name']); } if (isset($_POST['description'])) { $user->description = trim($_POST['description']); } foreach (hq_get_user_contact_methods($user) as $method => $name) { if (isset($_POST[$method])) { $user->{$method} = sanitize_text_field($_POST[$method]); } } if ($update) { $user->rich_editing = isset($_POST['rich_editing']) && 'false' == $_POST['rich_editing'] ? 'false' : 'true'; $user->admin_color = isset($_POST['admin_color']) ? sanitize_text_field($_POST['admin_color']) : 'fresh'; $user->show_admin_bar_front = isset($_POST['admin_bar_front']) ? 'true' : 'false'; } $user->comment_shortcuts = isset($_POST['comment_shortcuts']) && 'true' == $_POST['comment_shortcuts'] ? 'true' : ''; $user->use_ssl = 0; if (!empty($_POST['use_ssl'])) { $user->use_ssl = 1; } $errors = new HQ_Error(); /* checking that username has been typed */ if ($user->user_login == '') { $errors->add('user_login', __('<strong>ERROR</strong>: Please enter a username.')); } /* checking the password has been typed twice */ /** * Fires before the password and confirm password fields are checked for congruity. * * @since 0.0.1 * * @param string $user_login The username. * @param string &$pass1 The password, passed by reference. * @param string &$pass2 The confirmed password, passed by reference. */ do_action_ref_array('check_passwords', array($user->user_login, &$pass1, &$pass2)); if ($update) { if (empty($pass1) && !empty($pass2)) { $errors->add('pass', __('<strong>ERROR</strong>: You entered your new password only once.'), array('form-field' => 'pass1')); } elseif (!empty($pass1) && empty($pass2)) { $errors->add('pass', __('<strong>ERROR</strong>: You entered your new password only once.'), array('form-field' => 'pass2')); } } else { if (empty($pass1)) { $errors->add('pass', __('<strong>ERROR</strong>: Please enter your password.'), array('form-field' => 'pass1')); } elseif (empty($pass2)) { $errors->add('pass', __('<strong>ERROR</strong>: Please enter your password twice.'), array('form-field' => 'pass2')); } } /* Check for "\" in password */ if (false !== strpos(hq_unslash($pass1), "\\")) { $errors->add('pass', __('<strong>ERROR</strong>: Passwords may not contain the character "\\".'), array('form-field' => 'pass1')); } /* checking the password has been typed twice the same */ if ($pass1 != $pass2) { $errors->add('pass', __('<strong>ERROR</strong>: Please enter the same password in the two password fields.'), array('form-field' => 'pass1')); } if (!empty($pass1)) { $user->user_pass = $pass1; } if (!$update && isset($_POST['user_login']) && !validate_username($_POST['user_login'])) { $errors->add('user_login', __('<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.')); } if (!$update && username_exists($user->user_login)) { $errors->add('user_login', __('<strong>ERROR</strong>: This username is already registered. Please choose another one.')); } /* checking e-mail address */ if (empty($user->user_email)) { $errors->add('empty_email', __('<strong>ERROR</strong>: Please enter an e-mail address.'), array('form-field' => 'email')); } elseif (!is_email($user->user_email)) { $errors->add('invalid_email', __('<strong>ERROR</strong>: The email address isn’t correct.'), array('form-field' => 'email')); } elseif (($owner_id = email_exists($user->user_email)) && (!$update || $owner_id != $user->ID)) { $errors->add('email_exists', __('<strong>ERROR</strong>: This email is already registered, please choose another one.'), array('form-field' => 'email')); } /** * Fires before user profile update errors are returned. * * @since 0.0.1 * * @param array &$errors An array of user profile update errors, passed by reference. * @param bool $update Whether this is a user update. * @param HQ_User &$user HQ_User object, passed by reference. */ do_action_ref_array('user_profile_update_errors', array(&$errors, $update, &$user)); if ($errors->get_error_codes()) { return $errors; } if ($update) { $user_id = hq_update_user($user); } else { $user_id = hq_insert_user($user); hq_new_user_notification($user_id, null, 'both'); } return $user_id; }