Commit | Line | Data |
---|---|---|
1e7a45c4 VSB |
1 | /** |
2 | * For jQuery versions less than 3.4.0, this replaces the jQuery.extend | |
3 | * function with the one from jQuery 3.4.0, slightly modified (documented | |
4 | * below) to be compatible with older jQuery versions. | |
5 | * | |
6 | * This provides the Object.prototype pollution vulnerability fix to Drupal | |
7 | * installations running older jQuery versions, including the version (3.2.1) | |
8 | * shipped with Drupal core. | |
9 | * | |
10 | * @see https://github.com/jquery/jquery/pull/4333 | |
11 | */ | |
12 | ||
13 | (function (jQuery) { | |
14 | ||
15 | // Do not override jQuery.extend() if the jQuery version is already >=3.4.0. | |
16 | var versionParts = jQuery.fn.jquery.split('.'); | |
17 | var majorVersion = parseInt(versionParts[0]); | |
18 | var minorVersion = parseInt(versionParts[1]); | |
19 | var patchVersion = parseInt(versionParts[2]); | |
20 | var isPreReleaseVersion = (patchVersion.toString() !== versionParts[2]); | |
21 | if ( | |
22 | (majorVersion > 3) || | |
23 | (majorVersion === 3 && minorVersion > 4) || | |
24 | (majorVersion === 3 && minorVersion === 4 && patchVersion > 0) || | |
25 | (majorVersion === 3 && minorVersion === 4 && patchVersion === 0 && !isPreReleaseVersion) | |
26 | ) { | |
27 | return; | |
28 | } | |
29 | ||
30 | /** | |
31 | * This is almost verbatim copied from jQuery 3.4.0. | |
32 | * | |
33 | * Only one minor change has been made: | |
34 | * - The call to isFunction() is changed to jQuery.isFunction(). | |
35 | * | |
36 | * The above change ensures compatibility with older jQuery versions, | |
37 | * including 3.2.1 which is shipped with Drupal core. | |
38 | */ | |
39 | jQuery.extend = jQuery.fn.extend = function() { | |
40 | var options, name, src, copy, copyIsArray, clone, | |
41 | target = arguments[ 0 ] || {}, | |
42 | i = 1, | |
43 | length = arguments.length, | |
44 | deep = false; | |
45 | ||
46 | // Handle a deep copy situation | |
47 | if ( typeof target === "boolean" ) { | |
48 | deep = target; | |
49 | ||
50 | // Skip the boolean and the target | |
51 | target = arguments[ i ] || {}; | |
52 | i++; | |
53 | } | |
54 | ||
55 | // Handle case when target is a string or something (possible in deep copy) | |
56 | if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { | |
57 | target = {}; | |
58 | } | |
59 | ||
60 | // Extend jQuery itself if only one argument is passed | |
61 | if ( i === length ) { | |
62 | target = this; | |
63 | i--; | |
64 | } | |
65 | ||
66 | for ( ; i < length; i++ ) { | |
67 | ||
68 | // Only deal with non-null/undefined values | |
69 | if ( ( options = arguments[ i ] ) != null ) { | |
70 | ||
71 | // Extend the base object | |
72 | for ( name in options ) { | |
73 | copy = options[ name ]; | |
74 | ||
75 | // Prevent Object.prototype pollution | |
76 | // Prevent never-ending loop | |
77 | if ( name === "__proto__" || target === copy ) { | |
78 | continue; | |
79 | } | |
80 | ||
81 | // Recurse if we're merging plain objects or arrays | |
82 | if ( deep && copy && ( jQuery.isPlainObject( copy ) || | |
83 | ( copyIsArray = Array.isArray( copy ) ) ) ) { | |
84 | src = target[ name ]; | |
85 | ||
86 | // Ensure proper type for the source value | |
87 | if ( copyIsArray && !Array.isArray( src ) ) { | |
88 | clone = []; | |
89 | } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { | |
90 | clone = {}; | |
91 | } else { | |
92 | clone = src; | |
93 | } | |
94 | copyIsArray = false; | |
95 | ||
96 | // Never move original objects, clone them | |
97 | target[ name ] = jQuery.extend( deep, clone, copy ); | |
98 | ||
99 | // Don't bring in undefined values | |
100 | } else if ( copy !== undefined ) { | |
101 | target[ name ] = copy; | |
102 | } | |
103 | } | |
104 | } | |
105 | } | |
106 | ||
107 | // Return the modified object | |
108 | return target; | |
109 | }; | |
110 | ||
111 | })(jQuery); |