Help with Regex not working as intended

I am trying to modify my SMF forum registration to only permit numbers as the user name.

This is the standard SMF code that checks the registration name

[php]Only these characters are permitted.
if (preg_match(’/^\d+$/’, preg_replace(’~&#(?:\d{1,7}|x[0-9a-fA-F]{1,6});~’, ‘’, $context[‘checked_username’])) != 0 || $context[‘checked_username’] == ‘_’ || $context[‘checked_username’] == ‘|’ || strpos($context[‘checked_username’], ‘[code’) !== false || strpos($context[‘checked_username’], ‘[/code’) !== false)
$context[‘valid_username’] = false;
[/php]

This is what I have replaced it with

[php]if (!preg_match(’~^([1-9][0-9]{0,3})$~’, $context[‘checked_username’]))
$context[‘valid_username’] = false;
[/php]

Unfortunately this doesn’t seem to be working as it is still allowing new members to create a username with alpha characters too.

Anyone got any ideas how I can restrict this as I want?

If all you want is to verify that the user entered only numbers (digits from 0 to 9) without any particular pattern or length, the regex would be /[0-9]+/

I wouldn’t use regex for this though, instead I would use is_numeric like this:[php]$context[‘valid_username’] = is_numeric($context[‘checked_username’]);[/php]

This is cleaner and is_numeric should be way faster than preg_match.

If I have misunderstood what you are looking to do, please post a few examples of valid and invalid values.

jay

Thanks for your response. Initially I was trying to get fancy with only accepting a number between 1 and 9999, that is why I used the regex. Thinking about it again it doesn’t need to be that complicated as long as it is numeric then that will do.

I changed your code to be

[php]if(!is_numeric($context[‘checked_username’]))
$context[‘valid_username’] = false;[/php]

As I need it as an if statement rather than as a declaration within the context of SMF so I get the error messages if someone enters an invalid user name. Unfortunately my changes to your code (I am relatively inexperienced at PHP) mean that it still allows alpha characters as user name. Have I screwed up the logic of your statement or is this something else.

This is the entire code from the SMF function

[php]// See if a username already exists.
function RegisterCheckUsername()
{
global $sourcedir, $smcFunc, $context, $txt;

// This is XML!
loadTemplate('Xml');
$context['sub_template'] = 'check_username';
$context['checked_username'] = isset($_GET['username']) ? $_GET['username'] : '';
$context['valid_username'] = true;

// Clean it up like mother would.
$context['checked_username'] = preg_replace('~[\t\n\r\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}' : "\xC2\xA0") : '\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $context['checked_username']);
if ($smcFunc['strlen']($context['checked_username']) > 25)
	$context['checked_username'] = $smcFunc['htmltrim']($smcFunc['substr']($context['checked_username'], 0, 25));

// Only these characters are permitted.
//if (preg_match('/^\d+$/', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $context['checked_username'])) != 0 || $context['checked_username'] == '_' || $context['checked_username'] == '|' || strpos($context['checked_username'], '[code') !== false || strpos($context['checked_username'], '[/code') !== false)
	//$context['valid_username'] = false;
	

if(!is_numeric($context['checked_username']))
$context['valid_username'] = false;

if (stristr($context['checked_username'], $txt['guest_title']) !== false)
	$context['valid_username'] = false;

if (trim($context['checked_username']) == '')
	$context['valid_username'] = false;
else
{
	require_once($sourcedir . '/Subs-Members.php');
	$context['valid_username'] &= isReservedName($context['checked_username'], 0, false, false) ? 0 : 1;
}

}[/php]

Any further help or advice will be most welcome.

If you want to limit $context[‘checked_username’] between (and including) 1 and 9999 you should be able to do something like this:[php]if(!is_numeric($context[‘checked_username’]) || ($context[‘checked_username’]<1 || $context[‘checked_username’]>10000)) $context[‘valid_username’] = false;[/php]…for your first if.

In the long run, this should work, but there is something else going on here… can you post the original, unedited code for this section - the ifs and else look wrong to me, but if that is how they were in the original code, then I don’t want to go messing with them.

Thanks for all your help with this so far.

Unfortunately your new code isn’t working I can still register with an alpha character.

The entire register.php file is 850 lines long. Is it OK to post it all here or is that too big for the forum?

This is the function in register.php that appears to me to be the bit that is doing the verification checking.
[php]// See if a username already exists.
function RegisterCheckUsername()
{
global $sourcedir, $smcFunc, $context, $txt;

// This is XML!
loadTemplate('Xml');
$context['sub_template'] = 'check_username';
$context['checked_username'] = isset($_GET['username']) ? $_GET['username'] : '';
$context['valid_username'] = true;

// Clean it up like mother would.
$context['checked_username'] = preg_replace('~[\t\n\r\x0B\0' . ($context['utf8'] ? ($context['server']['complex_preg_chars'] ? '\x{A0}' : "\xC2\xA0") : '\xA0') . ']+~' . ($context['utf8'] ? 'u' : ''), ' ', $context['checked_username']);
if ($smcFunc['strlen']($context['checked_username']) > 25)
	$context['checked_username'] = $smcFunc['htmltrim']($smcFunc['substr']($context['checked_username'], 0, 25));

// Only these characters are permitted.
if (preg_match('~[<>&"\'=\\\]~', preg_replace('~&#(?:\\d{1,7}|x[0-9a-fA-F]{1,6});~', '', $context['checked_username'])) != 0 || $context['checked_username'] == '_' || $context['checked_username'] == '|' || strpos($context['checked_username'], '[code') !== false || strpos($context['checked_username'], '[/code') !== false)
	$context['valid_username'] = false;

if (stristr($context['checked_username'], $txt['guest_title']) !== false)
	$context['valid_username'] = false;

if (trim($context['checked_username']) == '')
	$context['valid_username'] = false;
else
{
	require_once($sourcedir . '/Subs-Members.php');
	$context['valid_username'] &= isReservedName($context['checked_username'], 0, false, false) ? 0 : 1;
}

}[/php]

This is totally unmodified.

Thanks once again for your help.

Lets try to isolate where the problem lies.

Going back to the altered version with your numeric check:

Try changing:[php]else
{
require_once($sourcedir . ‘/Subs-Members.php’);
$context[‘valid_username’] &= isReservedName($context[‘checked_username’], 0, false, false) ? 0 : 1;
}[/php]

… by adding three lines as follows:[php]else
{
echo “CHECKED USERNAME: $context[‘checked_username’]
”;
echo “VALID USERNAME: $context[‘valid_username’]
”;
exit;
require_once($sourcedir . ‘/Subs-Members.php’);
$context[‘valid_username’] &= isReservedName($context[‘checked_username’], 0, false, false) ? 0 : 1;
}[/php]

This will tell us if the valid_username key is being properly set. If it is returning true or 1 then the problem lies with the checking and we will need to fix that. If it returns false or 0 then the issue is with some other portion of the script.

Let me know…

Thanks once again for all your help. I wish the SMF guys were as helpful.

Now for the bad news, adding your two lines of code prevent the register screen from showing at all. :’(

Sorry, that was my mistake…

Try this instead:[php]echo “CHECKED USERNAME: $context[checked_username]
”;
echo “VALID USERNAME: $context[valid_username]
”;
exit;[/php]

Thanks once again the register page works fine but nothing is being output to the screen and I just get a thank you for registering so it looks to me as though your code is not being run.

Your welcome! I’m sorry we don’t have it solved yet, but we will get there…

Lets move these echos and exit up a little. Try putting it just after the following line:[php]global $sourcedir, $smcFunc, $context, $txt;[/php]

Let me know if it outputs (and exits) now. If it doesn’t I will probably need to see the entire code for this page.

Well that’s different. I moved your code as suggested.

This is the error message I am now getting

Sorry, but you’re not allowed to register multiple accounts at the same time from the same computer.

The vanilla code is too large to post to the forum.

It is uploaded as a zip file to http://turnspain.com/Register.zip

If you want it somewhere else let me know.

Thanks for all your help.

Your very welcome.

I will download the code and check it as soon as I can. We are definitely not even getting to the checking function!

Malasho

Did you have any luck with this by any chance please?

OK, it looks to me like the RegisterCheckUsername is only intended for incoming AJAX checks. It is looking for &sa=usernamecheck or ?sa=usernamecheck (depending on where it occurs) in the url.

Unfortunately, it looks like this would be created by a redirect in some other script. Either way, considering the rather cryptic (to me) regex, which appears to be looking for hexidecimal values, I would probably restore this section to its original code and put your name check somewhere else.

I will look over the script further and see if I can identify a safe place to put this. It may be fine to put it anywhere in the //Begin the registration process section, but I’ll need to spend a little more time reviewing all the code before I would be comfortable suggesting that.

Thanks very much for looking.

I will put the vanilla one back for now.

If you find something easily then great otherwise there are more people wanting help so push mine to the back of the queue.

Given what you have said I have checked and there are several other php and js scripts scattered within the smf environment that handle registrations. I suspect that I have latched on to the wrong script for my purposes.

I will search through the others and see what I can find.

Sounds good Valkrider,

Since the original topic was Regex related and we have effectively solved that, I am going to mark this as solved. We can continue to post in it, but it will indicate that the topic question has been answered.

Let me know if you find a different section and have questions.

Good luck!

jay

Jay

Thanks for all your help. With some heavy prompting I finally got some help from the SMF guys. They couldn’t work out why what i had originally didn’t work. It turns out that Register.php throws and error to the user by colouring the input box red but that’s all. Two other files needed modifying to do what I wanted. Once they identified those I could make the mods and now have exactly what I want.

Thanks for everything.

Colin

Sponsor our Newsletter | Privacy Policy | Terms of Service