aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/init.js
diff options
context:
space:
mode:
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>2021-09-30 16:00:24 +0200
committerGitHub <noreply@github.com>2021-09-30 16:00:24 +0200
commitde5398a6ad088dc006b46c6a870a2a053f4cd663 (patch)
tree8141154c5f8f2bdc9fb92cf3ad58befa07a9a0dc /src/core/init.js
parent1019074f7b1df96ee9d6409ada3dc0562046f6c7 (diff)
downloadjquery-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.js54
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