2008-05-06

Bug Discovered in Internet Explorer 7 JavaScript Regular Expression Engine

I enhanced my understanding about Regular Expressions' "look-ahead" concept that I hadn't fully comprehended before. The fact that (at least in the .NET framework and most JavaScript engines; I assume it also works in PERL and other popular RegEx engines...) you can use look-aheads to not only find a match but not include in the full-text match; but can look-ahead and not have the position of the start of the match matter either.

For some reason I always thought that the match would be made and the beginning of the next match would start at the position the other left off at. I wet my pants with glee when I found that wasn't the case...

That is, until I tried an expression in JavaScript in Internet Explorer 7.

To see an example of what I'm talking about, run my "Regular Expression Tests for Your Browser" on JavaScriptJedi.com in multiple browsers on your computer. You'll be running the "Pre Match Look Aheads (2008-05-05)" tests which are the only ones there at the time of this writing. I may add more in the future.

The scenario is this:
I had a set of password restriction requirements to enforce on a form when a user wanted to change their password. The requirements were that the password must be at least 8 characters long; contains at least one number and at least one "symbol". Due to a database constraint, I also added a max-length requirement of 50 characters, and I interpreted "symbol" to mean any non-alpha-numeric character.

That said, the regular expression ended up like this:
/^(?=.*[0-9])(?=.*[^a-zA-Z0-9]).{8,50}$/

What's really cool about this is; when run in a properly working regular expression engine, it doesn't matter if the number or "symbol" come first, it will detect them both and then from the beginning of the string match any characters between the lengths 8 and 50. Genius. Whoever came up with Regular Expressions needs a Nobel prize or some equivalent; because, well, they just make a developer's world a better place to live. :)

So after getting uber-excited about my new found knowledge and greater love for Regular Expressions, my bubble was quickly burst when I found out it didn't work correctly in IE7 and I had to come up with a workaround.

So go see my page and try it for yourself; and I'd love to get your feedback on this one. I'll be submitting a bug report to Microsoft (if I can figure out how...) and if I hear anything back from them (which I'm sure I won't...) I'll post my findings here.

I'd especially like to hear from Mac users that can test on the major Mac browsers for me and tell me which work and which don't.

13 comments:

Dan said...

Your tests passed fine for me on Safari (Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-us) AppleWebKit/523.10.3 (KHTML, like Gecko) ) and Firefox (Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14). I'm using Leopard on an iMac.

That One Guy said...

Right on Dan... thanks for providing that info for us!

I imagine Mac's IE isn't going to work since it's ancient? :) (Does anyone even use that on Mac anymore?)

Dan said...

As of 31 Jan 2006, IE for Mac is no longer available for download from Microsoft. See w3schools for more details.

macmec said...

Same result here with Safari (3.1.1 PPC). I tested in IE (5.2.3) just for "fun", it didn't even run the tests when I clicked the button. Opera (9.25) and Firefox (2.0.0.14), however, both worked flawlessly. I figured the other browsers, using the Gecko engine, would end up with the same results, so I skipped the rest. But in true completist form, I did test in iCab (4.0.1) and OmniWeb (5.6), both of which worked as the other properly-written, standards-compliant touting browsers did. M$ sucky software strikes again... and again... and again... One of these days, Jeff, you'll see the light and join us happy Apple advocates; then, once again, your life will have true meaning ;)

Anonymous said...

@That One Guy, I've described this bug (and a workaround) on my blog at http://blog.stevenlevithan.com/archives/regex-lookahead-bug

@macmec, jees man, lay off the Kool-Aid.

That One Guy said...

Good article Steve. Thanks for the extra info!

Unknown said...

Ran into this little knacker myself, today!

Expression: /^(?=.*\d)(?=.*[A-Z]).{6,16}$/

LibStar said...

(?=^.{8,20}$)(?=.*\d.*\d.*\d)(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])[0-9a-zA-Z]*

Password between 8 and 20 characters, alpha-numerics only, includes at least 3 letters and 3 numbers. Works with all IE (using ASP.NET RegularExpressionValidator)

Dan said...

Had the very same problem and LibStars workaround worked just fine. Thank you!

Matthew said...

@Steve Your solution worked perfectly for me. If others are having this same problem, check out his solution first.

praveen said...

Please help me regarding regular expression for strong password. conditions are


"Password must contain at least 8 characters including at least 2 numbers "

Must Allowed :
1abcdef2
21abcdef
abcdef22
1abcd4ef
1a$bcdef
1abcd^f2
12345678
1234567d
1234567%
1234567%33434
1234567%ddd
1234567dd%

Not Allowed
abcdef5%


it has to work in IE 7 ,IE8

i have a regulare Expression (ValidationExpression="(?=(?:.*?\d){2})(?=(?:.*?[A-Za-z@#$%^&+=]){2}).{8,}" )
but it is not working in IE7

That One Guy said...

What about this?
(?=(?:.*?\d){2})(?=(?:.*?[A-Za-z0-9@#$%^&+=]){2})^.{8,}$

Note:
You had "1a$bcdef" as allowed, but it doesn't contain 2 numbers; so it should be moved to the "not allowed" list.

David said...

Tests passed on Chrome/11.0.696.60
Thanks for your article!