]> source.dussan.org Git - jquery.git/commitdiff
Selector: Use shallow document comparisons to avoid IE/Edge crashes
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>
Tue, 24 Sep 2019 22:41:07 +0000 (00:41 +0200)
committerGitHub <noreply@github.com>
Tue, 24 Sep 2019 22:41:07 +0000 (00:41 +0200)
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

index fbfa7d1d8a32bcec8ce2cabb109e23ad60571e44..183adbbac63c20f06394364616b038c126f275b7 100644 (file)
@@ -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;
                                        }