Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: no-restricted-properties misses destructuring object returned from function call #16412

Closed
1 task done
merrywhether opened this issue Oct 12, 2022 · 7 comments · Fixed by #17818 · May be fixed by nodejs/node#53023
Closed
1 task done

Bug: no-restricted-properties misses destructuring object returned from function call #16412

merrywhether opened this issue Oct 12, 2022 · 7 comments · Fixed by #17818 · May be fixed by nodejs/node#53023
Assignees
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion bug ESLint is working incorrectly needs bikeshedding Minor details about this change need to be discussed repro:yes rule Relates to ESLint's core rules
Projects

Comments

@merrywhether
Copy link

merrywhether commented Oct 12, 2022

Environment

Node version: v16.14.2
npm version: v8.5.0
Local ESLint version: v8.24.0 (Currently used)
Global ESLint version: Not found
Operating System: darwin 21.6.0

What parser are you using?

@typescript-eslint/parser

What did you do?

After targeting a property in no-restricted-properties, immediately destructuring an object returned from a function call and accessing the restricted property:

const { bad } = foo();

ESLint demo example

What did you expect to happen?

Accessing restricted property via immediately destructuring object returned from function call is marked as lint error.

What actually happened?

Accessing restricted property via immediately destructuring object returned from function call is not recognized as error.

Participation

  • I am willing to submit a pull request for this issue.

Additional comments

AIUI the issue arises from checking the RHS type in an assignment. In the case where all instances of a property are restricted (no paired object argument) the RHS type check is unnecessary. Given the tight coupling with object, a "simple" solution might be treating this object as anonymous/unnamable and defaulting it to undefined (or empty string or some other sentinel that would always fail the ensuing object-name-related Map accesses):

function checkDestructuringAssignment(node) {
    if (node.left.type === "ObjectPattern") {
        const objectName = node.right.type === "Identifier" ? node.right.name : undefined;
            node.left.properties.forEach(property => {
                checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property));
            });
        }
    } 
}

(I fully admit there might be reasons why this doesn't work)

It would also be possible to extend the API with the ability to constrain the functions whose returned objects' properties can't be accessed (similar to object), but this does increase complexity as you have to handle CallExpression, AsyncExpression, and probably lots more. So maybe that's better left to future need-based implementation?

(useful reference PR for me or whoever winds up tackling this)

@merrywhether merrywhether added bug ESLint is working incorrectly repro:needed labels Oct 12, 2022
@eslint-github-bot eslint-github-bot bot added this to Needs Triage in Triage Oct 12, 2022
@mdjermanovic mdjermanovic moved this from Needs Triage to Triaging in Triage Oct 12, 2022
@mdjermanovic
Copy link
Member

Hi @merrywhether, thanks for the issue!

I think this is a bug. The following property accesses are basically the same, yet only the first is reported:

/* eslint no-restricted-properties: ["error", { property: "bad" }] */

bad = foo().bad; // error

({ bad } = foo()); // no error

I couldn't find any mention of this in #7151, or a test case that would confirm intent to allow access to restricted properties when the destructuring source is not given as an identifier, so this is most likely an oversight in the implementation.

@mdjermanovic
Copy link
Member

The rule should probably check all object patterns. In each of the following examples, bad property of an object is accessed:

/* eslint no-restricted-properties: ["error", { property: "bad" }] */

const { bad } = foo(); // should be error?

const { bar: { bad } } = foo; // // should be error?

const { bar: { bad } = {} } = foo; // // should be error?

const [{ bad }] = foo; // // should be error?

({ bad } = foo()); // // should be error?

({ bar: { bad } } = foo); // // should be error?

({ bar: { bad } = {} } = foo); // // should be error?

[{ bad }] = foo; // // should be error?

({ bad }) => {}; // // should be error?

({ bad } = {}) => {}; // // should be error?

({ bad: bar }) => {}; // // should be error?

({ bar: { bad } = {} }) => {}; // // should be error?

Currently, neither of the above examples is reported. Since this would introduce many new cases in which the rule warns, I'd like more opinions from the team.

@mdjermanovic mdjermanovic added rule Relates to ESLint's core rules accepted There is consensus among the team that this change meets the criteria for inclusion needs bikeshedding Minor details about this change need to be discussed and removed repro:needed labels Oct 12, 2022
@mdjermanovic mdjermanovic moved this from Triaging to Feedback Needed in Triage Oct 12, 2022
@snitin315
Copy link
Contributor

@mdjermanovic I feel the same that it should check all object patterns. So all the above examples should be reported 👍🏻

@snitin315 snitin315 moved this from Feedback Needed to Ready to Implement in Triage Nov 6, 2022
@thewizarodofoz
Copy link

Hey good people, wanted to check whether anyone is working on this.
I have no experience in implementing rules, but I could give it a go if no one is available.

@Tanujkanti4441
Copy link
Contributor

Tanujkanti4441 commented Aug 18, 2023

The rule should probably check all object patterns. In each of the following examples, bad property of an object is accessed:

/* eslint no-restricted-properties: ["error", { property: "bad" }] */

const { bad } = foo(); // should be error?

const { bar: { bad } } = foo; // // should be error?

const { bar: { bad } = {} } = foo; // // should be error?

const [{ bad }] = foo; // // should be error?

({ bad } = foo()); // // should be error?

({ bar: { bad } } = foo); // // should be error?

({ bar: { bad } = {} } = foo); // // should be error?

[{ bad }] = foo; // // should be error?

({ bad }) => {}; // // should be error?

({ bad } = {}) => {}; // // should be error?

({ bad: bar }) => {}; // // should be error?

({ bar: { bad } = {} }) => {}; // // should be error?

@mdjermanovic, in these cases rule should report just the bad property ? or also the object's name that property is inside , if object is specified in the rules option ?

if yes for the reporting objects as well then the for object pattern in function arguments, will it work like this ?

/* eslint no-restricted-properties: ["error", {object: "restrictedObject", property: "bad" }] */

const foo = ({ bad } = {}, ) => {}; // // should be error

foo(restrictedObject);  

and for the example below what would be the restricted object ?

/* eslint no-restricted-properties: ["error", {object: "restrictedObject", property: "bad" }] */

const { bar: { bad } } = foo; // // should be error?

const [{ bad }] = foo; // // should be error?

@arka1002
Copy link
Contributor

I’m going to do this, give me two weeks.

@Tanujkanti4441
Copy link
Contributor

I’m going to do this, give me two weeks.

Ok! assigning you.

arka1002 added a commit to arka1002/eslint that referenced this issue Nov 30, 2023
arka1002 added a commit to arka1002/eslint that referenced this issue Dec 5, 2023
arka1002 added a commit to arka1002/eslint that referenced this issue Dec 5, 2023
mdjermanovic pushed a commit that referenced this issue Dec 14, 2023
…ts (#17818)

* fix: adds nested objects in no-restricted-properties

Fixes: #16412

* chore: removes arrowfunction, variabledeclarator and assignmentexpression

* chore: removed unnecessary restrictions

* chore: change empty object name to null

* chore: add docs of the changed rules

* chore: add a note in the docs

* chore: change tests to languageOptions

* chore: fix lints
ZihongQu added a commit to ZihongQu/node that referenced this issue May 16, 2024
Since eslint fixed eslint/eslint#16412 and we are on
eslint v8.57.0 so that we can take advantage of no-restricted-properties rule
for webcrypto.
ZihongQu added a commit to ZihongQu/node that referenced this issue May 18, 2024
Since eslint fixed eslint/eslint#16412 and we
are on eslint v8.57.0 so that we can take advantage of
no-restricted-properties rule for webcrypto.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion bug ESLint is working incorrectly needs bikeshedding Minor details about this change need to be discussed repro:yes rule Relates to ESLint's core rules
Projects
Archived in project
Triage
Ready to Implement
6 participants