php regex too strict - php

Just wondering why this is too strict, I can send very simplified emails to say tim#yahoo.com or two#google.com
but if I make the email any longer (sacagawea#gmail.com) it does not get sent.
Instead it echos back my error message:Invalid Email Address Supplied
// Create a function to check email
function checkEmail($email)
{
// Add some regex
return preg_match('/^\S+#[\w\d.-]{2,}\.[\w]{2,6}$/iU', $email) ? TRUE : FALSE;
}

If you have access to php 5.2 or above, you should use the filter functions :
function checkEmail($email){
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
Or validate it, "the right way".

This part
#[\w\d.-]{2,}
is gobbling up
#gmail.com
leaving nothing for this part
[\w\d.-]{2,}
to match.
Better to reuse something already proven, see for example http://www.regular-expressions.info/email.html

I usually don't fret myself too much for checking email validity. I just need to check there is a value in front of "#" and at the back. That's all. The rest of the "checking" job, the MTAs will do that for me. If its invalid email, i will get a response from MTA. If its able to be sent out, that means the email is most probably valid.

please try
'/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/'
it also fits for subdomain email adresses as email#sub.domain.tl

Related

Preg match fails on some urls - not emails

I have the code below in the submitted form section of a php file. It is meant to catch any emails that contain a url and reject them.
if (preg_match("/(\b(((https?|ftp|file|):\/\/)|www[.])[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/i", $msg)) {
return false;
}
return true;
But I received an email with dozens of lines like this:
[url=http://example.рф]шкафы купе[/url]
I tried sending a message with one of the lines in the original email and the code blocked it. Why didn't it stop this spammer?
Based on the replies, which I deeply appreciate, I changed the code to the following. All I really want is to block url's. It doesn't matter what the path and parameters are so I think this catches all possibilities. This is used instead of php filters because the filters page says it can't catch URN's.
if (preg_match("/(\b(((https?|ftp|file|[-A-Z0-9]|):\/\/)|www[.]))/i", $msg)) {

PHPMailer do not send if email is invalid

I'm using PHPMailer to send emails via contact form.
When I enter an invalid email address in the input field, the email is still sent. I want to perform both client-side and server-side validations.
Does PHPMailer have a built-in validation system to check for invalid email address? If the email entered is invalid I want to return an error and not send the email.
The easiest and most correct way to validate email addresses is to use filter_var. Rather than relying on a patched PHPMailer, you could write a function to validate them before you send them to PHPMailer.
function validateEmailAddr($addr) {
// note: do not attempt to write any regex to validate email addresses;
// it will invariably be wrong
return filter_var($addr, FILTER_VALIDATE_EMAIL);
}
You said that you could enter something like 'sdjfygsdfisdf' and still get the email sent to you.
That's odd. Because adding any email address ('to', 'cc', 'bcc', 'replyto') in PHPMailer will go through the addOrEnqueueAnAddress() function, which does include validation checks. Adding a 'from' address uses different code, but also does validation checks.
The most obvious thing here is that you're not actually doing any error checking to trap for those errors.
Depending on whether you've got PHPMailer using exceptions or not, you might just be getting a false value returned from functions like setFrom() when you give it a bad address. If you ignore that value and carry on anyway, then yes, the email will still be sent.
So you need to add some error handling. Check for function call returning false.
However my preferred suggestion would be to switch to using exceptions for your error handler -- PHPMailer can do this just by setting a flag. This will make error handling easier, as you won't need to check for false on every single function call; just wrap the whole thing in a try catch block, and do your error handling in one go at the end.

check correct email format for swedish letters

i'm making a website that has a form which gets validated in php.
When people post the form the email gets sent to a $email variable and i check for the correct format. However i've yet to find a piece of code that checks if the format is correct (if its valid doesnt matter right now), i've found phps own function but it doesnt check for swedish letters, i've also found another function that checks the mail format but that breaks if you have an email with format xxx.yy#zz.aa. it only works if the format is xxx#zz.aa.
I would very much appreciate any help to make this work and to find a function that works.
You can use this regexp:
if(preg_match("/^\b[A-ZÅÄÖåäö0-9._%+-]+#[A-ZÅÄÖåäö0-9.-]+\.[A-Z]{2,4}\b$/i",$email)){
//mail is valid
}
This will validate youråäö#adressö.se etc.
Single thing that you can check in email address is it contains #. Check for that without any code found anywhere
i personally suggest you to validate forms in client side (i.e) using javascript or jquery
if all form validations are carried to the server the server load gets increased that too there is re- submission for invalid entries.
jquery code for email validation :
function ValidateEmail(email) {
var expr = /^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
return expr.test(email);
};
$("#id").blur(function(){
if(!ValidateEmail($("#id").val())){
//your code
}
else {
//your code
}
})

Is email#domain a valid email address

I'm evaluating a bunch of email validation techniques and someone of them output that email#domain is valid. I read somewhere that this email may be technically valid if it's being used for internal networking, but really for almost all practical purposes on the web today, this email should not evaluate to true.
What does your email validation library or home-baked method do, and do you allow this sort of thing?
Well, it depends on what the application is supposed to do.
Is it going to be used in an intranet? If so, email#domain may be fine.
If not, you might want to explicitly require a fqdn so that they can't send mail internally on your domain (foo#localhost, etc).
It shouldn't be difficult to check the domain part:
$domain = array_pop(explode('#', $email));
Then, depending on your need, validate the domain.
You can check it for valid syntax (that it's a fqdn). There are plenty of tutorials online (And that a lot of frameworks provide) that can validate a domain in a string to see if it's a fqdn format...
Or, if your needs are greater, you can just verify that your server can resolve it (Via something like dns_get_record()...
if (false === dns_get_record($domain, DNS_MX)) {
//invalid domain (can't find an MX record)...
}
(Note, I said you could do this, not if you should. That will depend on your exact use case)...
The domain .io currently has an MX resource record, so yes it is valid. It is explicitly allowed by RFC 5321.
You are welcome to use my free PHP function is_email() to validate addresses. It's available to download here. Try validating http://isemail.info/jblue#io online for example.
It will ensure that an address is fully RFC 5321 compliant. It can optionally also check whether the domain actually exists and has an MX record.
You shouldn't rely on a validator to tell you whether a user's email address actually exists: some ISPs give out non-compliant addresses to their users, particularly in countries which don't use the Latin alphabet. More in my essay about email validation here: http://isemail.info/about.
See this article for a regex to match all valid email addresses:
You may want to tweak it to
Discard IP domains
Discard port numbers
And to answer your quetion about email#domain, you can discard that too, if you are not expecting intranet emails.
the check with false isn't the best way, the return value can be an empty array, e.g. $domain = '-onlinbe.de';
try empty() instead: http://us3.php.net/manual/en/function.empty.php
$dnsMx = dns_get_record($domain, DNS_MX);
$dnsA = dns_get_record($domain, DNS_A);
if (empty($dnsMx) && empty($dnsA)) {
echo 'domain not available';
}
or use
if(gethostbyname($domain) === $domain) {
echo 'no ip found';
}

Allow user#example or user#localhost in email validation?

I'm working on an email validation check and we need to decided whether to allow user#localhost and user#example (notice no .anything) to be validated as a valid email address. This is for an open source project that has a number of use cases on both the web at large and intranets.
RFC 2822 (Internet Message Format Standard) allows it but RFC 2821 (SMTP Standard) says it should fail.
Thoughts?
It depends on your application. If you think that several of your users will have an email #localhost, and you don't mind. Then go for it.
Make it a configurable option, so people can decide for themselves. I'd default it to failure, personally, as I've yet to run into a case - intranet or public internet - where I've had someone use a valid user#localhost type address.
I would disable it. Very few organizations use internal domains, and those that do generally use "acme.localhost" or "intranet.com" or something else of the like. There is some sort of configuration going on in the DNS that they use to make it work.
Regardless, internal email is nearly dead anyway: with the advent of instant messaging, Twitter, and SMS along with the increasing availability of external email for every member of a company, it is almost entirely likely that you will never get a TLD-less domain in an email.
For the folks that do require it, they can always tweak the regex themselves, as they were savvy enough to set up a custom hostname to handle internal email.
Well, if you have DNS working for internally you could always just do a DNS lookup.
But if this is going to fail with SMTP, then I would suggest making sure you don't include it.
I have seen email addresses of the form user#localhost, typically when looking at archives of a mailing list and the administrator hosted and posted from the same machine. So it can definitely occur - and I admit it broke my parsing routine! So now I am a little more flexible to email addresses.
Looking at this it looks like you've we need two quick checks as detailed:
<?php
function valid_email($email) {
// First, we check that there's one # symbol, and that the lengths are right
if (!ereg("^[^#]{1,64}#[^#]{1,255}$", $email)) {
// Email invalid because wrong number of characters in one section, or wrong number of # symbols.
return false;
}
// take a given email address and split it into the username and domain.
list($userName, $mailDomain) = split("#", $email);
if (checkdnsrr($mailDomain, "MX")) {
// this is a valid email domain!
return true;
}
else {
// this email domain doesn't exist!
return false;
}
}
?>
(source 1, source 2)

Categories