Skip to content

extend is not handling property descriptors with accessors #2387

Closed
@marcospont

Description

@marcospont

The 'extend' function from 'util/core' is not handling property descriptors using accessors properly.

The issue was introduced by the following commit: f981192

The below test can be used to duplicate the issue. The object 'obj' has a 'pub' property that is defined using a getter and a setter. Once 'extend' is called, the property descriptor is recreated using 'value' and ignoring the accessors.

import extend from 'sinon/lib/sinon/util/core/extend';

describe('extend', () => {
	it('must preserve accessors', () => {
		const obj = {
			_priv: 1
		};

		Object.defineProperty(obj, 'pub', {
			configurable: true,
			get: () => obj._priv,
			set: value => {
				obj._priv = value;
			}
		});

		const newObj = {};

		extend(newObj, obj);

		expect(newObj['pub']).toBe(1);
	});
});

Activity

fatso83

fatso83 commented on Jul 9, 2021

@fatso83
Contributor

Good find!

sauravazad

sauravazad commented on Jul 17, 2021

@sauravazad
Contributor

There is an inherent mistake in the implementation as it does not distinguishes between Data property and Accessor property

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties

  • Data property
    Associates a key with a value, and has the following attributes:

Attributes of a data property

Attribute Type Description Default value
[[Value]] Any JavaScript type The value retrieved by a get access of the property. undefined
[[Writable]] Boolean If false, the property's [[Value]] cannot be changed. false
[[Enumerable]] Boolean If true, the property will be enumerated in for...in loops.See also Enumerability and ownership of properties. false
[[Configurable]] Boolean If false, the property cannot be deleted, cannot be changed to an accessor property, and attributes other than [[Value]] and [[Writable]] cannot be changed. false
  • Accessor property
    Associates a key with one of two accessor functions (get and set) to retrieve or store a value, and has the following attributes:

Attributes of an accessor property

Attribute Type Description Default value
[[Get]] Function object or undefined The function is called with an empty argument list and retrieves the property value whenever a get access to the value is performed.See also get. undefined
[[Set]] Function object or undefined The function is called with an argument that contains the assigned value and is executed whenever a specified property is attempted to be changed.See also set. undefined
[[Enumerable]] Boolean If true, the property will be enumerated in for...in loops. false
[[Configurable]] Boolean If false, the property can't be deleted and can't be changed to a data property. false

I have raised a PR to fix the behavior #2391.

mroderick

mroderick commented on Jul 27, 2021

@mroderick
Member

This has been fixed by #2391 and published to the npm registry as sinon@11.1.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mroderick@fatso83@sauravazad@marcospont

        Issue actions

          extend is not handling property descriptors with accessors · Issue #2387 · sinonjs/sinon