2

I have a problem with Regex when used for custom validation.

I have this unobtrusive method:

jQuery.validator.addMethod("isRegex", function (value, element, params) {
    if (value.length < 1) return true;
    var re = new RegExp(params.regex);
    var match = re.exec(value);
    return match;
});

At first I was using this regular expression for validation an email form field:

^\w+([-+.]*[\w-]+)*@(\w+([-.]?\w+)){1,}\.\w{2,4}$

The event would be fired "onkeyup" and at first it would work but if the email address was too long it would cause the browser to hang and the only way to recover would be restarting the browser. This happened on IE and chrome but probably Firefox too.

So for example typing "test@test.com" would work fine. "testtesttest@ttest.com" would also work without problems but "testtesttesttesttesttest@ttest.com" would hang towards the last letters.

At first I thought maybe the regex was an inneficient one causing infinite loops or locks so I changed it to something simple:

^.+@.+\..+$

Partial success, I can type longer email addresses but it still hangs eventually.

Then I thought I should disable the onkeyup event and maybe just validate on blur and for that I used:

   $("#divEmail input[data-val-fieldregex]").keyup(function () { return false; });

Now the keyup is disabled but the browser hangs on blur, so it means the code:

    var re = new RegExp(params.regex);
    var match = re.exec(value);

Must be unable to handle large values.

Any ideas?

Nick
  • 2,877
  • 2
  • 33
  • 62

2 Answers2

1

Try to replace ([-+.]*[\w-]+)* by ([-.]\w+)*

^\w+([-.]\w+)*@\w+([-.]\w+)*\.\w{2,4}$

You can find more informations about catastrophic backtracking here.

The second pattern can cause a catastrophic backtracking too since the dot can match the literal dot, and the arobase.

Note that this kind of pattern is very basic and will exclude many well formed email addresses.

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
  • I tried with ^.+@.+\..+$ and even though the problem improved, there were still issues – Nick Dec 09 '13 at 16:43
  • You were right. I used ^\w+([-.]\w+)*@\w+([-.]\w+)*\.\w{2,4}$ and restarted the browser, it no longer got stuck – Nick Dec 13 '13 at 16:01
0

Try this instead...

jQuery.validator.addMethod('isRegex', function (value, element, param) {
    return this.optional(element) || param.test(value);
});

And within .validate()...

rules: {
    field: {
        isRegex: /^\w+([-+.]*[\w-]+)*@(\w+([-.]?\w+)){1,}\.\w{2,4}$/i
    }
},

Working DEMO: http://jsfiddle.net/ZdCee/


BTW, what's wrong with the email method already built into this plugin?

http://jqueryvalidation.org/email-method/

email: function( value, element ) {
    // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
    return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
},

DEMO: http://jsfiddle.net/ZdCee/1/

Sparky
  • 98,165
  • 25
  • 199
  • 285
  • I can't use the inbuilt one but it turned out that the browser just needed a restart. – Nick Dec 13 '13 at 16:01