From f61314ff5cb5e6b620ace758a6f00c94a3031154 Mon Sep 17 00:00:00 2001 From: Oleg Gaidarenko Date: Mon, 8 Apr 2013 15:10:39 -0400 Subject: [PATCH] Fixes #8335. Do not allow add data to non-elements (2.x). Closes gh-1232 --- src/data.js | 26 ++++++++++++++++++++------ test/unit/data.js | 28 ++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/data.js b/src/data.js index eedde4d6f..790a54c97 100644 --- a/src/data.js +++ b/src/data.js @@ -14,7 +14,14 @@ var data_user, data_priv, rmultiDash = /([A-Z])/g; function Data() { - this.cache = {}; + // Support: Android < 4, + // Old WebKit does not have Object.preventExtensions/freeze method, return new empty object instead + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + this.expando = jQuery.expando + Math.random(); } @@ -22,6 +29,13 @@ Data.uid = 1; Data.prototype = { key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, but we should not, see #8335. + // Always return key for "freezed" object for such cases + if ( !this.accept( owner ) ) { + return 0; + } + + var descriptor = {}, // Check if the owner object already has a cache key unlock = owner[ this.expando ]; @@ -156,6 +170,10 @@ Data.prototype = { } } }, + accept: function( owner ) { + // Do not set data on non-element because it will not be cleared (#8335). + return owner.nodeType ? owner.nodeType === 1 || owner.nodeType === 9 : true; + }, hasData: function( owner ) { return !jQuery.isEmptyObject( this.cache[ owner[ this.expando ] ] || {} @@ -181,11 +199,7 @@ data_priv = new Data(); jQuery.extend({ - // This is no longer relevant to jQuery core, but must remain - // supported for the sake of jQuery 1.9.x API surface compatibility. - acceptData: function() { - return true; - }, + acceptData: data_user.accept, hasData: function( elem ) { return data_user.hasData( elem ) || data_priv.hasData( elem ); diff --git a/test/unit/data.js b/test/unit/data.js index 68426dc28..326fc5e2d 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -170,14 +170,6 @@ test("jQuery.data(object/flash)", 25, function() { dataTests( flash ); }); -test("jQuery.data(comment)", 25, function() { - dataTests( document.createComment("") ); -}); - -test("jQuery.data(text)", 25, function() { - dataTests( document.createTextNode("") ); -}); - test(".data()", function() { expect(5); @@ -685,3 +677,23 @@ test(".data doesn't throw when calling selection is empty. #13551", function() { ok( false, e.message ); } }); + +test("jQuery.acceptData", 6, function() { + ok( jQuery.acceptData( document ), "document" ); + ok( jQuery.acceptData( document.documentElement ), "documentElement" ); + ok( jQuery.acceptData( {} ), "object" ); + + ok( !jQuery.acceptData( document.createComment("") ), "comment" ); + ok( !jQuery.acceptData( document.createTextNode("") ), "text" ); + ok( !jQuery.acceptData( document.createDocumentFragment() ), "documentFragment" ); +}); + +test("Check proper data removal of non-element descendants nodes (#8335)", 1, function() { + var div = jQuery("
text
"), + text = div.contents(); + + text.data( "test", "test" ); // This should be a noop. + div.remove(); + + ok( !text.data("test"), "Be sure data is not stored in non-element" ); +}); -- 2.39.5