Side navigation
#3837 closed bug (fixed)
Opened January 14, 2009 12:11AM UTC
Closed January 17, 2009 04:56PM UTC
Last modified March 14, 2012 10:54PM UTC
Complex selector using :not() can lead to an infinite loop
Reported by: | dtetto | Owned by: | john |
---|---|---|---|
Priority: | major | Milestone: | 1.3.1 |
Component: | selector | Version: | 1.3 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Don't know exactly which part of the selector causes the bug, but:
$('.container div:not(.excluded) div');
causes an infinite loop at line 1769 of jquery.js in Firefox 3. (It doesn't cause the loop in a recent WebKit nightly; I haven't tested in IE or Opera.)
This is a bug introduced in the RC for 1.3 (it didn't exist in beta 2, nor in jQuery 1.2).
Here's the full test case with links to some working variations to help isolate the problem:
Attachments (0)
Change History (8)
Changed January 14, 2009 12:13AM UTC by comment:1
Changed January 14, 2009 12:48AM UTC by comment:2
It only seems to freeze/loop if you enable the 'console' in firebug. Without enabling it, it works fine for me on FF 3.0.5.
Changed January 15, 2009 02:05PM UTC by comment:3
component: | unfilled → selector |
---|---|
milestone: | 1.3 → 1.3.1 |
owner: | → john |
version: | → 1.3 |
Changed January 15, 2009 04:34PM UTC by comment:4
If it helps, I have found a similar problem in IE7 and Firefox 3.1 (disabling Firebug didn't help Firefox).
I am still investigating, but for me, have narrowed it down to this:
.find('> tbody:not(.row-template) > tr:not(.removed)')
Furthermore, I believe it is in this part of the selector:
('> tbody:not(.row-template))
I hope to provide a test case in a day or three when I get another spare moment...
Changed January 15, 2009 11:47PM UTC by comment:5
I was having a similar problem (jQuery goes into infinite loop, causes script timeout error) and narrowed it down to the :not selector. Changing the code to use the .not() method fixed the script timeout.
The code that was failing in IE and Firefox 3:
$('div.postfooter div.rating a.ratebutton:not(.igray)').click(rateEntry);
The code that works:
$('div.postfooter div.rating a.ratebutton').not('.igray').click(rateEntry);
Changed January 16, 2009 01:49AM UTC by comment:6
More details and another case where the ':not' selector fails:
http://littlegreenfootballs.com/article/32453_Tech_Note-_JQuery_1.3_Released
Changed January 16, 2009 02:41AM UTC by comment:7
I'm having a similar problem (infinite loop, same line), but it has nothing to do with the :not selector, so this may help in chasing down the bug. Given the following HTML structure:
<html> ... <body> <a></a> </body> </html>
This query causes the infinite loop:
Notably, these queries do NOT cause loops:
$('.someclass>span>a') $('div>span>a') $('div.someclass>body>a') $('div.someclass>span>font')
It seems that the trouble comes when you have an initial selector (the A at the end) that does match at least one element, so checkSet isn't empty, then you step back to a selector that fails for ALL elements in checkSet (the span selector), so checkSet is now filled with false, then you step back one more level to a selector that has both a tag and a class specifier. preFilter.TAG() goes into an infinite loop trying to find an element to run isXML() on. I'm not sure where the fix for this should go, but that should be enough to track it down, hopefully.
Incidentally, I'm running Fx3.0.4 on Linux with Firebug enabled.
Changed January 17, 2009 04:56PM UTC by comment:8
resolution: | → fixed |
---|---|
status: | new → closed |
Yeah, it was all about the preFilter.TAG logic - thanks for the pointer, dchurch. :not() was a red herring, but it's ok, since it should be fixed now:
http://github.com/jeresig/sizzle/commit/4a85526713de4e1b771dbe8b046d78dcec6da4b8
Will be merging the fix into jQuery soon.
Correction: The loop happens at http://code.jquery.com/jquery-1.3.js line 1774.