I've to validate some data in my form, none of them works but i'd like some help for the username validation hoping that I can fix the other problems later.
So here is my form, nothing unusual :
<form action="inscription_traitement.php" method="post">
<label>Nom d'utilisateur : </label><br/>
<input type="text" name="username"/>
<label>Adresse e-mail : </label><br/>
<input type="text" name="mail"/>
<label>Mot de passe : </label><br/>
<input type="password" name="password"/>
<label>Répétez votre mot de passe : </label><br/>
<input type="password" name="password_r"/>
<input type="submit" name="submit" value="S'inscrire"/><input type="reset" value="Annuler"/>
</form>
Then that redirect to my validation file (the problem is in invalidUsername()):
<?php
if (isset($_POST["submit"])){
$username = $_POST["username"];
$mail = $_POST["mail"];
$password = $_POST["password"];
$password_r = $_POST["password_r"];
require_once "database_connection.php";
require_once "functions.php";
// Here is the problem
if(invalidUsername($username) !== false){
header("Location: inscription.php?error=invalid_username");
exit();
}
if(usernameExists($db, $username) !== false){
header("Location: inscription.php?error=username_exists");
exit();
}
if(invalidMail($mail) !== false){
header("Location: inscription.php?error=invalid_mail");
exit();
}
if(mailExists($db, $mail) !== false){
header("Location: inscription.php?error=mail_exists");
exit();
}
if(invalidPassword($password) !== false){
header("Location: inscription.php?error=invalid_password");
exit();
}
if (passwordMatch($password, $password_r) !== false){
header("Location: inscription.php?error=password_match");
exit();
}
createUser($db, $username, $mail, $password);
}
else{
header("location: inscription.php");
}?>
And finally i created a file that regroups all my functions, the one we are interested in is invalidUsername():
<?php
// here is the problem
function invalidUsername($username){
$usernameRegex = "/[A-Za-z0-9-_]{5,15}/";
if(!preg_match($usernameRegex, $username)){
return true;
}else{
return false;
}
}
function usernameExists($db, $username){
$username = mysql_real_escape_string($username);
$query = mysql_query("SELECT * FROM player WHERE p_username = ".$username.";");
try{
$stmt = $db->prepare($query);
$stmt->execute();
}catch(PDOException $e){
header("Location: inscription.php?error=\".$e.\"");
return true;
}
return false;
}
function invalidMail($mail){
if(!filter_var($mail, FILTER_VALIDATE_EMAIL)){
return true;
}else{
return false;
}
}
function mailExists($db, $mail){
$query = "SELECT * FROM player WHERE p_mail_adress = ?;";
$stmt = $db->prepare($query);
try{
$stmt->execute(array($mail));
}catch(Exception $e){
header("Location: inscription.php?error=stmt_error");
return true;
}
return false;
}
function invalidPassword($password){
$passwordRegex = "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/";
if(!preg_match($passwordRegex, $password)){
return true;
}else{
return false;
}
}
function passwordMatch($password, $password_r){
if($password != $password_r){
return true;
}else{
return false;
}
}
function createUser($db, $username, $mail, $password){
$ip_adress = $_SERVER['REMOTE_ADDR'];
$query = "INSERT INTO player(p_username, p_mail_adress, p_password, p_ip, p_score, p_is_online) VALUES(?, ?, ?, ?, ?, ?);";
$stmt = $db->prepare($query);
try{
$stmt->execute(array($username, $mail, $password, $ip_adress, 0, 0));
}catch(Exception $e){
header("Location: inscription.php?error=$e");
}
header("Location: inscription.php?bienvenu");
}?>
The problem is the following : the invalidUsername() function return me true (meaning that the validation did not pass) all the time, even if i put correct data in my username field. I tried my regex online and it works. I can't understand where I messed up and the logic seems good to me.
I use Easyphp Devserver 17 if it can help you.
CodePudding user response:
There are two issues:
- The hyphen placement inside a character class is strict in the latest PHP versions, it should be located either at the start of end of the pattern to avoid any issues
- The pattern must be anchored, i.e. it must match the entire string, else, the
{5,15}
limiting quantifier makes little sense.
You need to use
function invalidUsername($username){
$usernameRegex = "/^[\w-]{5,15}$/D";
return (bool)preg_match($usernameRegex, $username));
}
Details:
^
- start of string[\w-]{5,15}
- five to fifteen ASCII letters, digits, underscores or hyphens$
- end of stringD
- the flag means that the end of string$
anchor matches only at the end of string.
CodePudding user response:
The dash character matches characters from X to Y:
a-z = match from "a" to "z"
0-9 = match from "0" to "9"
The last dash is interpreted the same way:
9-_ = match from "9" to "_"
This is obviously nonsense. To avoid this you must escape the dash character with \
Example:
/[A-Za-z0-9\-_]{5,15}/
CodePudding user response:
Regex:
[0-9] # A single digit
[_] # An underscore
[0-9] # A single digit
According to PHP manual:
preg_match()
returns 1 if the pattern matches given subject, 0 if it does not, or false on failure.
I recommend online preg_match editor: https://www.phpliveregex.com/#tab-preg-match
This will solve your problems. I am not able to verify what string parameters you provide.