Skip to content
Permalink
Browse files
Manipulation: Make jQuery.htmlPrefilter an identity function
Closes gh-4642

(cherry picked from 90fed4b)
  • Loading branch information
mgol committed Mar 16, 2020
1 parent 04bf577 commit 1d61fd9407e6fbe82fe55cb0b938307aa0791f77
Showing 18 changed files with 246 additions and 257 deletions.
@@ -33,13 +33,6 @@ define( [

var

/* eslint-disable max-len */

// See https://github.com/eslint/eslint/issues/3229
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,

/* eslint-enable */

// Support: IE <=10 - 11, Edge 12 - 13 only
// In IE/Edge using regex groups here causes severe slowdowns.
// See https://connect.microsoft.com/IE/feedback/details/1736512/
@@ -236,7 +229,7 @@ function remove( elem, selector, keepData ) {

jQuery.extend( {
htmlPrefilter: function( html ) {
return html.replace( rxhtmlTag, "<$1></$2>" );
return html;
},

clone: function( elem, dataAndEvents, deepDataAndEvents ) {
@@ -251,7 +251,7 @@ this.testIframe = function( title, fileName, func, wrapper ) {
}
wrapper.call( QUnit, title, function( assert ) {
var done = assert.async(),
$iframe = supportjQuery( "<iframe/>" )
$iframe = supportjQuery( "<iframe></iframe>" )
.css( { position: "absolute", top: "0", left: "-600px", width: "500px" } )
.attr( { id: "qunit-fixture-iframe", src: url( fileName ) } );

@@ -49,7 +49,7 @@ <h2>
<script>
var logUL = jQuery( "#log" );
function doLog( message, args ) {
jQuery( "<li />").appendTo( logUL ).text( message + ': "' + Array.prototype.join.call( args, '" - "' ) + '"' );
jQuery( "<li></li>" ).appendTo( logUL ).text( message + ': "' + Array.prototype.join.call( args, '" - "' ) + '"' );
}
jQuery.ajax( "./data/badjson.js" , {
context: jQuery( "#success" ),
@@ -2456,7 +2456,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re

addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxError", assert )();
jQuery( document ).on( "ajaxStop", done );
jQuery( "<div/>" ).load( baseURL + "404.txt", function() {
jQuery( "<div></div>" ).load( baseURL + "404.txt", function() {
assert.ok( true, "complete" );
} );
} );
@@ -2563,7 +2563,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
return "Hello World";
}
} );
jQuery( "<div/>" ).load( url( "name.html" ), function( responseText ) {
jQuery( "<div></div>" ).load( url( "name.html" ), function( responseText ) {
assert.strictEqual( jQuery( this ).html(), "Hello World", "Test div was filled with filtered data" );
assert.strictEqual( responseText, "Hello World", "Test callback receives filtered data" );
done();
@@ -2573,7 +2573,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.test( "jQuery.fn.load( String, Object, Function )", function( assert ) {
assert.expect( 2 );
var done = assert.async();
jQuery( "<div />" ).load( url( "mock.php?action=echoHtml" ), {
jQuery( "<div></div>" ).load( url( "mock.php?action=echoHtml" ), {
"bar": "ok"
}, function() {
var $node = jQuery( this );
@@ -2587,7 +2587,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
assert.expect( 2 );
var done = assert.async();

jQuery( "<div />" ).load( url( "mock.php?action=echoHtml" ), "foo=3&bar=ok", function() {
jQuery( "<div></div>" ).load( url( "mock.php?action=echoHtml" ), "foo=3&bar=ok", function() {
var $node = jQuery( this );
assert.strictEqual( $node.find( "#method" ).text(), "GET", "Check method" );
assert.ok( $node.find( "#query" ).text().match( /foo=3&bar=ok/ ), "Check if a string of data is passed correctly" );
@@ -93,12 +93,12 @@ QUnit.test( "attr(String)", function( assert ) {
assert.equal( jQuery( "#area1" ).attr( "maxLength" ), "30", "Check for maxLength attribute" );

// using innerHTML in IE causes href attribute to be serialized to the full path
jQuery( "<a/>" ).attr( {
jQuery( "<a></a>" ).attr( {
"id": "tAnchor5",
"href": "#5"
} ).appendTo( "#qunit-fixture" );
assert.equal( jQuery( "#tAnchor5" ).attr( "href" ), "#5", "Check for non-absolute href (an anchor)" );
jQuery( "<a id='tAnchor6' href='#5' />" ).appendTo( "#qunit-fixture" );
jQuery( "<a id='tAnchor6' href='#5'></a>" ).appendTo( "#qunit-fixture" );
assert.equal( jQuery( "#tAnchor5" ).prop( "href" ), jQuery( "#tAnchor6" ).prop( "href" ), "Check for absolute href prop on an anchor" );

jQuery( "<script type='jquery/test' src='#5' id='scriptSrc'></script>" ).appendTo( "#qunit-fixture" );
@@ -136,7 +136,7 @@ QUnit.test( "attr(String)", function( assert ) {
assert.equal( $img.attr( "height" ), "53", "Retrieve height attribute on an element with display:none." );

// Check for style support
styleElem = jQuery( "<div/>" ).appendTo( "#qunit-fixture" ).css( {
styleElem = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" ).css( {
background: "url(UPPERlower.gif)"
} );
assert.ok( !!~styleElem.attr( "style" ).indexOf( "UPPERlower.gif" ), "Check style attribute getter" );
@@ -158,11 +158,11 @@ QUnit.test( "attr(String)", function( assert ) {
$a = jQuery( "<a href='#' onclick='something()'>Click</a>" ).appendTo( "#qunit-fixture" );
assert.equal( $a.attr( "onclick" ), "something()", "Retrieve ^on attribute without anonymous function wrapper." );

assert.ok( jQuery( "<div/>" ).attr( "doesntexist" ) === undefined, "Make sure undefined is returned when no attribute is found." );
assert.ok( jQuery( "<div/>" ).attr( "title" ) === undefined, "Make sure undefined is returned when no attribute is found." );
assert.equal( jQuery( "<div/>" ).attr( "title", "something" ).attr( "title" ), "something", "Set the title attribute." );
assert.ok( jQuery( "<div></div>" ).attr( "doesntexist" ) === undefined, "Make sure undefined is returned when no attribute is found." );
assert.ok( jQuery( "<div></div>" ).attr( "title" ) === undefined, "Make sure undefined is returned when no attribute is found." );
assert.equal( jQuery( "<div></div>" ).attr( "title", "something" ).attr( "title" ), "something", "Set the title attribute." );
assert.ok( jQuery().attr( "doesntexist" ) === undefined, "Make sure undefined is returned when no element is there." );
assert.equal( jQuery( "<div/>" ).attr( "value" ), undefined, "An unset value on a div returns undefined." );
assert.equal( jQuery( "<div></div>" ).attr( "value" ), undefined, "An unset value on a div returns undefined." );
assert.strictEqual( jQuery( "<select><option value='property'></option></select>" ).attr( "value" ), undefined, "An unset value on a select returns undefined." );

$form = jQuery( "#form" ).attr( "enctype", "multipart/form-data" );
@@ -180,7 +180,7 @@ QUnit.test( "attr(String) on cloned elements, #9646", function( assert ) {

assert.strictEqual( input.clone( true ).attr( "name", "test" )[ 0 ].name, "test", "Name attribute should be changed on cloned element" );

div = jQuery( "<div id='tester' />" );
div = jQuery( "<div id='tester'></div>" );
div.attr( "id" );

assert.strictEqual( div.clone( true ).attr( "id", "test" )[ 0 ].id, "test", "Id attribute should be changed on cloned element" );
@@ -299,7 +299,7 @@ QUnit.test( "attr(String, Object)", function( assert ) {
$input = jQuery( "<input type='checkbox'/>" ).attr( "checked", true );
assert.equal( $input.prop( "checked" ), true, "Setting checked updates property (verified by .prop)" );
assert.equal( $input[ 0 ].checked, true, "Setting checked updates property (verified by native property)" );
$input = jQuery( "<option/>" ).attr( "selected", true );
$input = jQuery( "<option></option>" ).attr( "selected", true );
assert.equal( $input.prop( "selected" ), true, "Setting selected updates property (verified by .prop)" );
assert.equal( $input[ 0 ].selected, true, "Setting selected updates property (verified by native property)" );

@@ -592,7 +592,7 @@ QUnit.test( "removeAttr(String)", function( assert ) {
assert.expect( 12 );
var $first;

assert.equal( jQuery( "<div class='hello' />" ).removeAttr( "class" ).attr( "class" ), undefined, "remove class" );
assert.equal( jQuery( "<div class='hello'></div>" ).removeAttr( "class" ).attr( "class" ), undefined, "remove class" );
assert.equal( jQuery( "#form" ).removeAttr( "id" ).attr( "id" ), undefined, "Remove id" );
assert.equal( jQuery( "#foo" ).attr( "style", "position:absolute;" ).removeAttr( "style" ).attr( "style" ), undefined, "Check removing style attribute" );
assert.equal( jQuery( "#form" ).attr( "style", "position:absolute;" ).removeAttr( "style" ).attr( "style" ), undefined, "Check removing style attribute on a form" );
@@ -692,7 +692,7 @@ QUnit.test( "prop(String, Object)", function( assert ) {
assert.equal( jQuery( "#select2" ).prop( "selectedIndex" ), 3, "Check for selectedIndex attribute" );
assert.equal( jQuery( "#foo" ).prop( "nodeName" ).toUpperCase(), "DIV", "Check for nodeName attribute" );
assert.equal( jQuery( "#foo" ).prop( "tagName" ).toUpperCase(), "DIV", "Check for tagName attribute" );
assert.equal( jQuery( "<option/>" ).prop( "selected" ), false, "Check selected attribute on disconnected element." );
assert.equal( jQuery( "<option></option>" ).prop( "selected" ), false, "Check selected attribute on disconnected element." );

assert.equal( jQuery( "#listWithTabIndex" ).prop( "tabindex" ), 5, "Check retrieving tabindex" );
jQuery( "#text1" ).prop( "readonly", true );
@@ -837,16 +837,16 @@ QUnit.test( "option.prop('selected', true) affects select.selectedIndex (gh-2732

function addOptions( $elem ) {
return $elem.append(
jQuery( "<option/>" ).val( "a" ).text( "One" ),
jQuery( "<option/>" ).val( "b" ).text( "Two" ),
jQuery( "<option/>" ).val( "c" ).text( "Three" )
jQuery( "<option></option>" ).val( "a" ).text( "One" ),
jQuery( "<option></option>" ).val( "b" ).text( "Two" ),
jQuery( "<option></option>" ).val( "c" ).text( "Three" )
)
.find( "[value=a]" ).prop( "selected", true ).end()
.find( "[value=c]" ).prop( "selected", true ).end();
}

var $optgroup,
$select = jQuery( "<select/>" );
$select = jQuery( "<select></select>" );

// Check select with options
addOptions( $select ).appendTo( "#qunit-fixture" );
@@ -856,7 +856,7 @@ QUnit.test( "option.prop('selected', true) affects select.selectedIndex (gh-2732
$select.empty();

// Check select with optgroup
$optgroup = jQuery( "<optgroup/>" );
$optgroup = jQuery( "<optgroup></optgroup>" );
addOptions( $optgroup ).appendTo( $select );
$select.find( "[value=b]" ).prop( "selected", true );

@@ -970,7 +970,7 @@ QUnit.test( "val()", function( assert ) {
assert.equal( $button.val(), "foobar", "Value retrieval on a button does not return innerHTML" );
assert.equal( $button.val( "baz" ).html(), "text", "Setting the value does not change innerHTML" );

assert.equal( jQuery( "<option/>" ).val( "test" ).attr( "value" ), "test", "Setting value sets the value attribute" );
assert.equal( jQuery( "<option></option>" ).val( "test" ).attr( "value" ), "test", "Setting value sets the value attribute" );
} );

QUnit.test( "val() with non-matching values on dropdown list", function( assert ) {
@@ -1029,7 +1029,7 @@ var testVal = function( valueObj, assert ) {
assert.equal( document.getElementById( "text1" ).value, "", "Check for modified (via val(null)) value of input element" );

var j,
$select = jQuery( "<select multiple><option value='1'/><option value='2'/></select>" ),
$select = jQuery( "<select multiple><option value='1'></option><option value='2'></option></select>" ),
$select1 = jQuery( "#select1" );

$select1.val( valueObj( "3" ) );
@@ -1145,7 +1145,7 @@ QUnit.test( "val(select) after form.reset() (Bug #2551)", function( assert ) {
QUnit.test( "select.val(space characters) (gh-2978)", function( assert ) {
assert.expect( 37 );

var $select = jQuery( "<select/>" ).appendTo( "#qunit-fixture" ),
var $select = jQuery( "<select></select>" ).appendTo( "#qunit-fixture" ),
spaces = {
"\\t": {
html: "&#09;",
@@ -1230,7 +1230,7 @@ var testAddClass = function( valueObj, assert ) {
j.addClass( valueObj( "asdf" ) );
assert.ok( j.hasClass( "asdf" ), "Check node,textnode,comment for addClass" );

div = jQuery( "<div/>" );
div = jQuery( "<div></div>" );

div.addClass( valueObj( "test" ) );
assert.equal( div.attr( "class" ), "test", "Make sure there's no extra whitespace." );
@@ -1669,17 +1669,17 @@ QUnit.test( "coords returns correct values in IE6/IE7, see #10828", function( as
assert.expect( 1 );

var area,
map = jQuery( "<map />" );
map = jQuery( "<map></map>" );

area = map.html( "<area shape='rect' coords='0,0,0,0' href='#' alt='a' />" ).find( "area" );
area = map.html( "<area shape='rect' coords='0,0,0,0' href='#' alt='a'></area>" ).find( "area" );
assert.equal( area.attr( "coords" ), "0,0,0,0", "did not retrieve coords correctly" );
} );

QUnit.test( "should not throw at $(option).val() (#14686)", function( assert ) {
assert.expect( 1 );

try {
jQuery( "<option/>" ).val();
jQuery( "<option></option>" ).val();
assert.ok( true );
} catch ( _ ) {
assert.ok( false );
@@ -36,7 +36,7 @@ QUnit.test( "ajax", function( assert ) {
QUnit.test( "attributes", function( assert ) {
assert.expect( 6 );

var a = jQuery( "<a/>" ).appendTo( "#qunit-fixture" ),
var a = jQuery( "<a></a>" ).appendTo( "#qunit-fixture" ),
input = jQuery( "<input/>" ).appendTo( "#qunit-fixture" );

assert.strictEqual( a.attr( "foo", "bar" ).attr( "foo" ), "bar", ".attr getter/setter" );
@@ -56,7 +56,7 @@ if ( jQuery.css ) {
QUnit.test( "css", function( assert ) {
assert.expect( 1 );

var div = jQuery( "<div/>" ).appendTo( "#qunit-fixture" );
var div = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" );

assert.strictEqual( div.css( "width", "50px" ).css( "width" ), "50px", ".css getter/setter" );
} );
@@ -66,7 +66,7 @@ if ( jQuery.fn.show && jQuery.fn.hide ) {
QUnit.test( "show/hide", function( assert ) {
assert.expect( 2 );

var div = jQuery( "<div/>" ).appendTo( "#qunit-fixture" );
var div = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" );

div.hide();
assert.strictEqual( div.css( "display" ), "none", "div hidden" );
@@ -126,7 +126,7 @@ QUnit.test( "core", function( assert ) {
QUnit.test( "data", function( assert ) {
assert.expect( 4 );

var elem = jQuery( "<div data-c='d'/>" ).appendTo( "#qunit-fixture" );
var elem = jQuery( "<div data-c='d'></div>" ).appendTo( "#qunit-fixture" );

assert.ok( !jQuery.hasData( elem[ 0 ] ), "jQuery.hasData - false" );
assert.strictEqual( elem.data( "a", "b" ).data( "a" ), "b", ".data getter/setter" );
@@ -138,7 +138,7 @@ QUnit.test( "dimensions", function( assert ) {
assert.expect( 3 );

var elem = jQuery(
"<div style='margin: 10px; padding: 7px; border: 2px solid black;' /> "
"<div style='margin: 10px; padding: 7px; border: 2px solid black;'></div> "
).appendTo( "#qunit-fixture" );

assert.strictEqual( elem.width( 50 ).width(), 50, ".width getter/setter" );
@@ -149,7 +149,7 @@ QUnit.test( "dimensions", function( assert ) {
QUnit.test( "event", function( assert ) {
assert.expect( 1 );

var elem = jQuery( "<div/>" ).appendTo( "#qunit-fixture" );
var elem = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" );

elem
.on( "click", function() {
@@ -168,12 +168,12 @@ QUnit.test( "manipulation", function( assert ) {

var child,
elem1 = jQuery( "<div><span></span></div>" ).appendTo( "#qunit-fixture" ),
elem2 = jQuery( "<div/>" ).appendTo( "#qunit-fixture" );
elem2 = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" );

assert.strictEqual( elem1.text( "foo" ).text(), "foo", ".html getter/setter" );

assert.strictEqual(
elem1.html( "<span/>" ).html(),
elem1.html( "<span></span>" ).html(),
"<span></span>",
".html getter/setter"
);
@@ -182,8 +182,8 @@ QUnit.test( "manipulation", function( assert ) {
assert.strictEqual( elem1.prepend( elem2 )[ 0 ].childNodes[ 0 ], elem2[ 0 ], ".prepend" );

child = elem1.find( "span" );
child.after( "<a/>" );
child.before( "<b/>" );
child.after( "<a></a>" );
child.before( "<b></b>" );

assert.strictEqual(
elem1.html(),
@@ -197,8 +197,8 @@ QUnit.test( "manipulation", function( assert ) {
QUnit[ /jsdom\//.test( navigator.userAgent ) ? "skip" : "test" ]( "offset", function( assert ) {
assert.expect( 3 );

var parent = jQuery( "<div style='position:fixed;top:20px;'/>" ).appendTo( "#qunit-fixture" ),
elem = jQuery( "<div style='position:absolute;top:5px;'/>" ).appendTo( parent );
var parent = jQuery( "<div style='position:fixed;top:20px;'></div>" ).appendTo( "#qunit-fixture" ),
elem = jQuery( "<div style='position:absolute;top:5px;'></div>" ).appendTo( parent );

assert.strictEqual( elem.offset().top, 25, ".offset getter" );
assert.strictEqual( elem.position().top, 5, ".position getter" );
@@ -23,9 +23,9 @@ QUnit.test( "jQuery()", function( assert ) {

var elem, i,
obj = jQuery( "div" ),
code = jQuery( "<code/>" ),
code = jQuery( "<code></code>" ),
img = jQuery( "<img/>" ),
div = jQuery( "<div/><hr/><code/><b/>" ),
div = jQuery( "<div></div><hr/><code></code><b/>" ),
exec = false,
expected = 23,
attrObj = {
@@ -113,7 +113,7 @@ QUnit.test( "jQuery()", function( assert ) {
elem = jQuery( "\n\n<em>world</em>" )[ 0 ];
assert.equal( elem.nodeName.toLowerCase(), "em", "leading newlines" );

elem = jQuery( "<div/>", attrObj );
elem = jQuery( "<div></div>", attrObj );

if ( jQuery.fn.width ) {
assert.equal( elem[ 0 ].style.width, "10px", "jQuery() quick setter width" );
@@ -458,7 +458,7 @@ QUnit.test( "jQuery('html')", function( assert ) {

assert.ok( jQuery( "<link rel='stylesheet'/>" )[ 0 ], "Creating a link" );

assert.ok( !jQuery( "<script/>" )[ 0 ].parentNode, "Create a script" );
assert.ok( !jQuery( "<script></script>" )[ 0 ].parentNode, "Create a script" );

assert.ok( jQuery( "<input/>" ).attr( "type", "hidden" ), "Create an input and set the type." );

@@ -526,8 +526,8 @@ QUnit.test( "jQuery('massive html #7990')", function( assert ) {
QUnit.test( "jQuery('html', context)", function( assert ) {
assert.expect( 1 );

var $div = jQuery( "<div/>" )[ 0 ],
$span = jQuery( "<span/>", $div );
var $div = jQuery( "<div></div>" )[ 0 ],
$span = jQuery( "<span></span>", $div );
assert.equal( $span.length, 1, "verify a span created with a div context works, #1763" );
} );

@@ -1356,7 +1356,7 @@ QUnit.test( "jQuery.parseHTML", function( assert ) {
assert.equal( jQuery.parseHTML( "text" )[ 0 ].nodeType, 3, "Parsing text returns a text node" );
assert.equal( jQuery.parseHTML( "\t<div></div>" )[ 0 ].nodeValue, "\t", "Preserve leading whitespace" );

assert.equal( jQuery.parseHTML( " <div/> " )[ 0 ].nodeType, 3, "Leading spaces are treated as text nodes (#11290)" );
assert.equal( jQuery.parseHTML( " <div></div> " )[ 0 ].nodeType, 3, "Leading spaces are treated as text nodes (#11290)" );

html = jQuery.parseHTML( "<div>test div</div>" );

2 comments on commit 1d61fd9

@svhyd
Copy link

@svhyd svhyd commented on 1d61fd9 May 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Michał, is there a patch for the old jQuery releases for this fix?

E.g., like this one: https://github.com/DanielRuf/snyk-js-jquery-565129

Especially, for 1.x series as I'm using 1.12.4.

Also, does this address both these CVE's or only the first one in the list?

https://nvd.nist.gov/vuln/detail/CVE-2020-11022
https://nvd.nist.gov/vuln/detail/CVE-2020-11023

Thanks.

@dmethvin
Copy link
Member

@dmethvin dmethvin commented on 1d61fd9 May 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't comment on commits. There is no patch for 1.x or 2.x, they are no longer supported and in any case this is a pretty big breaking change, likely even more so on the browsers supported by those versions. Patching this would almost surely cause a cascade of failures in code and plugins that you would need to address.

Please sign in to comment.