diff options
author | Michał Gołębiowski-Owczarek <m.goleb@gmail.com> | 2021-09-30 16:00:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-30 16:00:24 +0200 |
commit | de5398a6ad088dc006b46c6a870a2a053f4cd663 (patch) | |
tree | 8141154c5f8f2bdc9fb92cf3ad58befa07a9a0dc /src/core/init.js | |
parent | 1019074f7b1df96ee9d6409ada3dc0562046f6c7 (diff) | |
download | jquery-de5398a6ad088dc006b46c6a870a2a053f4cd663.tar.gz jquery-de5398a6ad088dc006b46c6a870a2a053f4cd663.zip |
Core:Manipulation: Add basic TrustedHTML support
This ensures HTML wrapped in TrustedHTML can be used as an input to jQuery
manipulation methods in a way that doesn't violate the
`require-trusted-types-for` Content Security Policy directive.
This commit builds on previous work needed for trusted types support, including
gh-4642 and gh-4724.
One restriction is that while any TrustedHTML wrapper should work as input
for jQuery methods like `.html()` or `.append()`, for passing directly to the
`jQuery` factory the string must start with `<` and end with `>`; no trailing
or leading whitespaces are allowed. This is necessary as we cannot parse out
a part of the input for further construction; that would violate the CSP rule -
and that's what's done to HTML input not matching these constraints.
No trusted types API is used explicitly in source; the majority of the work is
ensuring we don't pass the input converted to string to APIs that would
eventually assign it to `innerHTML`. This extra cautiousness is caused by the
API being Blink-only, at least for now.
The ban on passing strings to `innerHTML` means support tests relying on such
assignments are impossible. We don't currently have such tests on the `main`
branch but we used to have many of them in the 3.x & older lines. If there's
a need to re-add such a test, we'll need an escape hatch to skip them for apps
needing CSP-enforced TrustedHTML.
See https://web.dev/trusted-types/ for more information about TrustedHTML.
Fixes gh-4409
Closes gh-4927
Ref gh-4642
Ref gh-4724
Diffstat (limited to 'src/core/init.js')
-rw-r--r-- | src/core/init.js | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/src/core/init.js b/src/core/init.js index a97fc1060..8fc24d8dd 100644 --- a/src/core/init.js +++ b/src/core/init.js @@ -2,6 +2,7 @@ import jQuery from "../core.js"; import document from "../var/document.js"; import rsingleTag from "./var/rsingleTag.js"; +import isObviousHtml from "./isObviousHtml.js"; import "../traversing/findFilter.js"; @@ -26,20 +27,41 @@ var rootjQuery, // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { + // HANDLE: $(DOMElement) + if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( typeof selector === "function" ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + + } else { - // Assume that strings that start and end with <> are HTML and skip the regex check + // Handle obvious HTML strings + match = selector + ""; + if ( isObviousHtml( match ) ) { + + // Assume that strings that start and end with <> are HTML and skip + // the regex check. This also handles browser-supported HTML wrappers + // like TrustedHTML. match = [ null, selector, null ]; - } else { + // Handle HTML strings or selectors + } else if ( typeof selector === "string" ) { match = rquickExpr.exec( selector ); + } else { + return jQuery.makeArray( selector, this ); } // Match html or make sure no context is specified for #id + // Note: match[1] may be a string or a TrustedHTML wrapper if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) @@ -84,7 +106,7 @@ var rootjQuery, return this; } - // HANDLE: $(expr, $(...)) + // HANDLE: $(expr) & $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || root ).find( selector ); @@ -93,24 +115,8 @@ var rootjQuery, } else { return this.constructor( context ).find( selector ); } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( typeof selector === "function" ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); } - return jQuery.makeArray( selector, this ); }; // Give the init function the jQuery prototype for later instantiation |