Bug Tracker

Opened 14 years ago

Closed 14 years ago

Last modified 11 years ago

#3837 closed bug (fixed)

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:


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: http://www.babywhale.net/loop/final.php

Change History (8)

comment:1 Changed 14 years ago by dtetto

Correction: The loop happens at http://code.jquery.com/jquery-1.3.js line 1774.

comment:2 Changed 14 years ago by Thasmo

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.

comment:3 Changed 14 years ago by john

Component: unfilledselector
Owner: set to john
Version: 1.3

comment:4 Changed 14 years ago by ashah

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...

comment:5 Changed 14 years ago by C.Johnson

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);

comment:6 Changed 14 years ago by C.Johnson

More details and another case where the ':not' selector fails:


comment:7 Changed 14 years ago by dchurch

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:


This query causes the infinite loop:


Notably, these queries do NOT cause loops:


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.

comment:8 Changed 14 years ago by john

Resolution: fixed
Status: newclosed

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.

Note: See TracTickets for help on using tickets.