Skip to content

Commit

Permalink
Attributes: Avoid infinite recursion on non-lowercase attribute getters
Browse files Browse the repository at this point in the history
Attribute hooks are determined for the lowercase versions of attribute names
but this has not been reflected in the bool attribute hooks. The code that
temporarily removed a handler to avoid an infinite loop was removing an
incorrect handler causing stack overflow.

Fixes jquerygh-3133
Refs jquerygh-2914
Refs jquerygh-2916
Closes jquerygh-3134
  • Loading branch information
mgol committed Jun 3, 2016
1 parent 5430c54 commit e06fda6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/attributes/attr.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,18 @@ jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name )
var getter = attrHandle[ name ] || jQuery.find.attr;

attrHandle[ name ] = function( elem, name, isXML ) {
var ret, handle;
var ret, handle,
lowercaseName = name.toLowerCase();

if ( !isXML ) {

// Avoid an infinite loop by temporarily removing this function from the getter
handle = attrHandle[ name ];
attrHandle[ name ] = ret;
handle = attrHandle[ lowercaseName ];
attrHandle[ lowercaseName ] = ret;
ret = getter( elem, name, isXML ) != null ?
name.toLowerCase() :
lowercaseName :
null;
attrHandle[ name ] = handle;
attrHandle[ lowercaseName ] = handle;
}
return ret;
};
Expand Down
19 changes: 19 additions & 0 deletions test/unit/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -1642,3 +1642,22 @@ QUnit.test( "SVG class manipulation (gh-2199)", function( assert ) {
assert.ok( !elem.hasClass( "awesome" ), "SVG element (" + this + ") toggles the class off" );
} );
} );

QUnit.test( "non-lowercase boolean attribute getters should not crash", function( assert ) {
assert.expect( 3 );

var elem = jQuery( "<input checked required autofocus type='checkbox'>" );

jQuery.each( {
checked: "Checked",
required: "requiRed",
autofocus: "AUTOFOCUS"
}, function( lowercased, original ) {
try {
assert.strictEqual( elem.attr( original ), lowercased,
"The '" + this + "' attribute getter should return the lowercased name" );
} catch ( e ) {
assert.ok( false, "The '" + this + "' attribute getter threw" );
}
} );
} );

0 comments on commit e06fda6

Please sign in to comment.