]> source.dussan.org Git - jquery.git/commitdiff
Fixes #8335. Do not allow add data to non-elements (2.x). Closes gh-1232
authorOleg Gaidarenko <markelog@gmail.com>
Mon, 8 Apr 2013 19:10:39 +0000 (15:10 -0400)
committerRick Waldron <waldron.rick@gmail.com>
Mon, 8 Apr 2013 19:10:39 +0000 (15:10 -0400)
src/data.js
test/unit/data.js

index eedde4d6f719d577d6aca7fbaa27e9e491ddce8e..790a54c97350dc14a334fcd4f8cdf1f33944407c 100644 (file)
@@ -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 );
index 68426dc2822a50bf2ee10e907688c04854c48fba..326fc5e2dfb6adac7f0a7bc6901ce38de44fbe12 100644 (file)
@@ -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("<div>text</div>"),
+               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" );
+});