diff options
author | Michał Gołębiowski <m.goleb@gmail.com> | 2016-05-29 22:24:28 +0200 |
---|---|---|
committer | Michał Gołębiowski <m.goleb@gmail.com> | 2016-06-03 22:48:43 +0200 |
commit | e06fda69f00082b44fd39ce8e851f72d29999011 (patch) | |
tree | 921a3c4ee185b9e02625048afa13d296d3a4b5a5 | |
parent | 5430c540dfedf1a64558d5f55f668904ee787817 (diff) | |
download | jquery-e06fda69f00082b44fd39ce8e851f72d29999011.tar.gz jquery-e06fda69f00082b44fd39ce8e851f72d29999011.zip |
Attributes: Avoid infinite recursion on non-lowercase attribute getters
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 gh-3133
Refs gh-2914
Refs gh-2916
Closes gh-3134
-rw-r--r-- | src/attributes/attr.js | 12 | ||||
-rw-r--r-- | test/unit/attributes.js | 19 |
2 files changed, 26 insertions, 5 deletions
diff --git a/src/attributes/attr.js b/src/attributes/attr.js index af9b3d09b..5d85f4f19 100644 --- a/src/attributes/attr.js +++ b/src/attributes/attr.js @@ -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; }; diff --git a/test/unit/attributes.js b/test/unit/attributes.js index 45efddfe4..127eb3e1e 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -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" ); + } + } ); +} ); |