Skip to content

Commit 31a7e3f

Browse files
authored
feat: fix no-restricted-properties false negatives with unknown objects (#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
1 parent ba87a06 commit 31a7e3f

3 files changed

Lines changed: 152 additions & 29 deletions

File tree

docs/src/rules/no-restricted-properties.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Certain properties on objects may be disallowed in a codebase. This is useful fo
1111

1212
## Rule Details
1313

14-
This rule looks for accessing a given property key on a given object name, either when reading the property's value or invoking it as a function. You may specify an optional message to indicate an alternative API or a reason for the restriction.
14+
This rule looks for accessing a given property key on a given object name, either when reading the property's value or invoking it as a function. You may specify an optional message to indicate an alternative API or a reason for the restriction. This rule applies to both properties accessed by dot notation and destructuring.
1515

1616
### Options
1717

@@ -96,6 +96,10 @@ disallowedObjectName.disallowedPropertyName(); /*error Disallowed object propert
9696
}] */
9797

9898
foo.__defineGetter__(bar, baz);
99+
100+
const { __defineGetter__ } = qux();
101+
102+
({ __defineGetter__ }) => {};
99103
```
100104

101105
:::

lib/rules/no-restricted-properties.js

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -142,40 +142,27 @@ module.exports = {
142142
}
143143
}
144144

145-
/**
146-
* Checks property accesses in a destructuring assignment expression, e.g. `var foo; ({foo} = bar);`
147-
* @param {ASTNode} node An AssignmentExpression or AssignmentPattern node
148-
* @returns {undefined}
149-
*/
150-
function checkDestructuringAssignment(node) {
151-
if (node.right.type === "Identifier") {
152-
const objectName = node.right.name;
153-
154-
if (node.left.type === "ObjectPattern") {
155-
node.left.properties.forEach(property => {
156-
checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property));
157-
});
158-
}
159-
}
160-
}
161-
162145
return {
163146
MemberExpression(node) {
164147
checkPropertyAccess(node, node.object && node.object.name, astUtils.getStaticPropertyName(node));
165148
},
166-
VariableDeclarator(node) {
167-
if (node.init && node.init.type === "Identifier") {
168-
const objectName = node.init.name;
169-
170-
if (node.id.type === "ObjectPattern") {
171-
node.id.properties.forEach(property => {
172-
checkPropertyAccess(node.id, objectName, astUtils.getStaticPropertyName(property));
173-
});
149+
ObjectPattern(node) {
150+
let objectName = null;
151+
152+
if (node.parent.type === "VariableDeclarator") {
153+
if (node.parent.init && node.parent.init.type === "Identifier") {
154+
objectName = node.parent.init.name;
155+
}
156+
} else if (node.parent.type === "AssignmentExpression" || node.parent.type === "AssignmentPattern") {
157+
if (node.parent.right.type === "Identifier") {
158+
objectName = node.parent.right.name;
174159
}
175160
}
176-
},
177-
AssignmentExpression: checkDestructuringAssignment,
178-
AssignmentPattern: checkDestructuringAssignment
161+
162+
node.properties.forEach(property => {
163+
checkPropertyAccess(node, objectName, astUtils.getStaticPropertyName(property));
164+
});
165+
}
179166
};
180167
}
181168
};

tests/lib/rules/no-restricted-properties.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,138 @@ ruleTester.run("no-restricted-properties", rule, {
546546
},
547547
type: "MemberExpression"
548548
}]
549+
}, {
550+
code: "const { bar: { bad } = {} } = foo;",
551+
options: [{ property: "bad" }],
552+
languageOptions: { ecmaVersion: 6 },
553+
errors: [{
554+
messageId: "restrictedProperty",
555+
data: {
556+
propertyName: "bad",
557+
message: ""
558+
}
559+
}]
560+
}, {
561+
code: "const { bar: { bad } } = foo;",
562+
options: [{ property: "bad" }],
563+
languageOptions: { ecmaVersion: 6 },
564+
errors: [{
565+
messageId: "restrictedProperty",
566+
data: {
567+
propertyName: "bad",
568+
message: ""
569+
}
570+
}]
571+
}, {
572+
code: "const { bad } = foo();",
573+
options: [{ property: "bad" }],
574+
languageOptions: { ecmaVersion: 6 },
575+
errors: [{
576+
messageId: "restrictedProperty",
577+
data: {
578+
propertyName: "bad",
579+
message: ""
580+
}
581+
}]
582+
}, {
583+
code: "({ bad } = foo());",
584+
options: [{ property: "bad" }],
585+
languageOptions: { ecmaVersion: 6 },
586+
errors: [{
587+
messageId: "restrictedProperty",
588+
data: {
589+
propertyName: "bad",
590+
message: ""
591+
}
592+
}]
593+
}, {
594+
code: "({ bar: { bad } } = foo);",
595+
options: [{ property: "bad" }],
596+
languageOptions: { ecmaVersion: 6 },
597+
errors: [{
598+
messageId: "restrictedProperty",
599+
data: {
600+
propertyName: "bad",
601+
message: ""
602+
}
603+
}]
604+
}, {
605+
code: "({ bar: { bad } = {} } = foo);",
606+
options: [{ property: "bad" }],
607+
languageOptions: { ecmaVersion: 6 },
608+
errors: [{
609+
messageId: "restrictedProperty",
610+
data: {
611+
propertyName: "bad",
612+
message: ""
613+
}
614+
}]
615+
}, {
616+
code: "({ bad }) => {};",
617+
options: [{ property: "bad" }],
618+
languageOptions: { ecmaVersion: 6 },
619+
errors: [{
620+
messageId: "restrictedProperty",
621+
data: {
622+
propertyName: "bad",
623+
message: ""
624+
}
625+
}]
626+
}, {
627+
code: "({ bad } = {}) => {};",
628+
options: [{ property: "bad" }],
629+
languageOptions: { ecmaVersion: 6 },
630+
errors: [{
631+
messageId: "restrictedProperty",
632+
data: {
633+
propertyName: "bad",
634+
message: ""
635+
}
636+
}]
637+
}, {
638+
code: "({ bad: bar }) => {};",
639+
options: [{ property: "bad" }],
640+
languageOptions: { ecmaVersion: 6 },
641+
errors: [{
642+
messageId: "restrictedProperty",
643+
data: {
644+
propertyName: "bad",
645+
message: ""
646+
}
647+
}]
648+
}, {
649+
code: "({ bar: { bad } = {} }) => {};",
650+
options: [{ property: "bad" }],
651+
languageOptions: { ecmaVersion: 6 },
652+
errors: [{
653+
messageId: "restrictedProperty",
654+
data: {
655+
propertyName: "bad",
656+
message: ""
657+
}
658+
}]
659+
}, {
660+
code: "[{ bad }] = foo;",
661+
options: [{ property: "bad" }],
662+
languageOptions: { ecmaVersion: 6 },
663+
errors: [{
664+
messageId: "restrictedProperty",
665+
data: {
666+
propertyName: "bad",
667+
message: ""
668+
}
669+
}]
670+
}, {
671+
code: "const [{ bad }] = foo;",
672+
options: [{ property: "bad" }],
673+
languageOptions: { ecmaVersion: 6 },
674+
errors: [{
675+
messageId: "restrictedProperty",
676+
data: {
677+
propertyName: "bad",
678+
message: ""
679+
}
680+
}]
549681
}
550682
]
551683
});

0 commit comments

Comments
 (0)