Skip to content

Commit

Permalink
harden-exports error on 'function' keyword (#2387)
Browse files Browse the repository at this point in the history
_fixup_

## Description

The new `harden-exports` rule should not allow a function defined by the
`function` keyword to be exported, because it can't really be hardened.
The hoisting allows the value to be mutated by an import before it can
be hardened.

### Security Considerations

improvement

### Scaling Considerations

none

### Documentation Considerations

none

### Testing Considerations

new tests

### Compatibility Considerations

bug fix

### Upgrade Considerations

not released yet
  • Loading branch information
turadg authored Jul 29, 2024
2 parents b8ee26e + c39b232 commit a4da6d5
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 51 deletions.
9 changes: 6 additions & 3 deletions packages/eslint-plugin/lib/rules/harden-exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ module.exports = {
}
}
} else if (exportNode.declaration.type === 'FunctionDeclaration') {
// @ts-expect-error xxx typedef
exportNames.push(exportNode.declaration.id.name);
context.report({
node: exportNode,
// The 'function' keyword hoisting makes the valuable mutable before it can be hardened.
message: `Export '${exportNode.declaration.id.name}' should be a const declaration with an arrow function.`,
});
}
} else if (exportNode.specifiers) {
for (const spec of exportNode.specifiers) {
Expand Down Expand Up @@ -91,7 +94,7 @@ module.exports = {
const noun = missingHardenCalls.length === 1 ? 'export' : 'exports';
context.report({
node: exportNode,
message: `The named ${noun} '${missingHardenCalls.join(', ')}' should be followed by a call to 'harden'.`,
message: `Named ${noun} '${missingHardenCalls.join(', ')}' should be followed by a call to 'harden'.`,
fix: function (fixer) {
const hardenCalls = missingHardenCalls
.map(name => `harden(${name});`)
Expand Down
57 changes: 9 additions & 48 deletions packages/eslint-plugin/test/harden-exports.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,6 @@ harden(b);
},
{
code: `
export function foo() {
console.log("foo");
}
harden(foo);
export const a = 1;
harden(a);
`,
},
{
code: `
export const a = 1;
harden(a);
export function bar() {
console.log("bar");
}
harden(bar);
`,
},
{
code: `
export const a = 1;
harden(a);
export function
multilineFunction() {
console.log("This is a multiline function.");
}
harden(multilineFunction);
`,
},
{
code: `
export const {
getEnvironmentOption,
getEnvironmentOptionsList,
Expand All @@ -73,8 +42,7 @@ harden(a);
`,
errors: [
{
message:
"The named export 'b' should be followed by a call to 'harden'.",
message: "Named export 'b' should be followed by a call to 'harden'.",
},
],
output: `
Expand All @@ -91,8 +59,7 @@ export const a = 1;
`,
errors: [
{
message:
"The named export 'a' should be followed by a call to 'harden'.",
message: "Named export 'a' should be followed by a call to 'harden'.",
},
],
output: `
Expand All @@ -109,14 +76,13 @@ export function foo() {
errors: [
{
message:
"The named export 'foo' should be followed by a call to 'harden'.",
"Export 'foo' should be a const declaration with an arrow function.",
},
],
output: `
export function foo() {
console.log("foo");
}
harden(foo);
`,
},
{
Expand All @@ -129,15 +95,14 @@ export function
errors: [
{
message:
"The named export 'multilineFunction' should be followed by a call to 'harden'.",
"Export 'multilineFunction' should be a const declaration with an arrow function.",
},
],
output: `
export function
multilineFunction() {
console.log("This is a multiline function.");
}
harden(multilineFunction);
`,
},
{
Expand All @@ -158,20 +123,18 @@ export function
`,
errors: [
{
message:
"The named export 'a' should be followed by a call to 'harden'.",
message: "Named export 'a' should be followed by a call to 'harden'.",
},
{
message:
"The named export 'b' should be followed by a call to 'harden'.",
message: "Named export 'b' should be followed by a call to 'harden'.",
},
{
message:
"The named export 'foo' should be followed by a call to 'harden'.",
"Export 'foo' should be a const declaration with an arrow function.",
},
{
message:
"The named export 'multilineFunction' should be followed by a call to 'harden'.",
"Export 'multilineFunction' should be a const declaration with an arrow function.",
},
],
output: `
Expand All @@ -186,12 +149,10 @@ harden(alreadyHardened);
export function foo() {
console.log("foo");
}
harden(foo);
export function
multilineFunction() {
console.log("This is a multiline function.");
}
harden(multilineFunction);
`,
},
{
Expand All @@ -205,7 +166,7 @@ environmentOptionsListHas,
errors: [
{
message:
"The named exports 'getEnvironmentOption, getEnvironmentOptionsList, environmentOptionsListHas' should be followed by a call to 'harden'.",
"Named exports 'getEnvironmentOption, getEnvironmentOptionsList, environmentOptionsListHas' should be followed by a call to 'harden'.",
},
],
output: `
Expand Down

0 comments on commit a4da6d5

Please sign in to comment.