From 0ef97b59396f5c75e995d754cb8fbf81d3dab82c Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Fri, 11 Mar 2016 10:48:00 -0500 Subject: [PATCH] Core: Restore 1.x isPlainObject constructor checks - Guard isPlainObject against inherited scalar constructors Fixes gh-2982 Close gh-2985 --- src/core.js | 4 +++- test/unit/core.js | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core.js b/src/core.js index 967fa8e26..713c1a3cd 100644 --- a/src/core.js +++ b/src/core.js @@ -233,8 +233,10 @@ jQuery.extend( { return false; } + // Not own constructor property must be Object if ( obj.constructor && - !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + !hasOwn.call( obj, "constructor" ) && + !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) { return false; } diff --git a/test/unit/core.js b/test/unit/core.js index e33f65358..3e71e6551 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -268,7 +268,8 @@ QUnit.test( "type for `Symbol`", function( assert ) { } ); QUnit.asyncTest( "isPlainObject", function( assert ) { - assert.expect( 19 ); + + assert.expect( 22 ); var pass, iframe, doc, parentObj, childObj, deep, fn = function() {}; @@ -276,6 +277,10 @@ QUnit.asyncTest( "isPlainObject", function( assert ) { // The use case that we want to match assert.ok( jQuery.isPlainObject( {} ), "{}" ); assert.ok( jQuery.isPlainObject( new window.Object() ), "new Object" ); + assert.ok( jQuery.isPlainObject( { constructor: fn } ), + "plain object with constructor property" ); + assert.ok( jQuery.isPlainObject( { constructor: "foo" } ), + "plain object with primitive constructor property" ); parentObj = { foo: "bar" }; childObj = Object.create( parentObj ); @@ -310,6 +315,10 @@ QUnit.asyncTest( "isPlainObject", function( assert ) { // Again, instantiated objects shouldn't be matched assert.ok( !jQuery.isPlainObject( new fn() ), "new fn" ); + // Instantiated objects with primitive constructors shouldn't be matched + fn.prototype.constructor = "foo"; + assert.ok( !jQuery.isPlainObject( new fn() ), "new fn with primitive constructor" ); + // Deep object deep = { "foo": { "baz": true }, "foo2": document }; assert.ok( jQuery.isPlainObject( deep ), "Object with objects is still plain" );