From aa6344baf87145ffc807a527d9c1fb03c96b1948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Wed, 25 Sep 2019 00:41:07 +0200 Subject: [PATCH] Selector: Use shallow document comparisons to avoid IE/Edge crashes IE/Edge sometimes crash when comparing documents between frames using the strict equality operator (`===` & `!==`). Funnily enough, shallow comparisons (`==` & `!=`) work without crashing. Fixes gh-4441 Closes gh-4471 --- src/selector.js | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/selector.js b/src/selector.js index fbfa7d1d8..183adbbac 100644 --- a/src/selector.js +++ b/src/selector.js @@ -172,10 +172,7 @@ function find( selector, context, results, seed ) { // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } + setDocument( context ); context = context || document; if ( documentIsHTML ) { @@ -425,7 +422,11 @@ function setDocument( node ) { doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected - if ( doc === document || doc.nodeType !== 9 ) { + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 ) { return; } @@ -436,7 +437,11 @@ function setDocument( node ) { // Support: IE 9 - 11+, Edge 12 - 18+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if ( preferredDoc !== document && + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { // Support: IE 9 - 11+, Edge 12 - 18+ @@ -449,11 +454,7 @@ find.matches = function( expr, elements ) { }; find.matchesSelector = function( elem, expr ) { - - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } + setDocument( elem ); if ( documentIsHTML && !nonnativeSelectorCache[ expr + " " ] && @@ -1413,14 +1414,24 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ); if ( outermost ) { - outermostContext = context === document || context || outermost; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; } // Add elements passing elementMatchers directly to results for ( ; ( elem = elems[ i ] ) != null; i++ ) { if ( byElement && elem ) { j = 0; - if ( !context && elem.ownerDocument !== document ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { setDocument( elem ); xml = !documentIsHTML; }