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

Add safePerformance to guard against bad performance calls #1677

Merged
merged 9 commits into from
Dec 17, 2024

Conversation

Kuuuube
Copy link
Member

@Kuuuube Kuuuube commented Dec 17, 2024

performance is a big potential footgun since we have no linting or validation on them and as far as I can tell there is no way to get it. For example, simply making a typo in a performance.measure(...) call or putting a performance.mark(...) call in the wrong scope can throw an error that may break things while being uncaught by all tests (#1676).

safePerformance runs and logs errors from performance instead of letting the errors propagate. All copied methods are identical except that they can return undefined if there is an error. Currently, we don't use the returns anywhere so this doesn't require any further code changes to accommodate.

I haven't copied over every method from performance but if they're needed in the future it's super simple to add more. Currently we only use mark, measure, and now. I also didn't make the class extend Performance because its constructor gave Illegal constructor errors no matter what I did (if someone can figure that out it may be worth adding) and ts doesn't like overriding base class methods when the return type is different.

I've added an eslint rule to block the use of performance directly. The rule also could add on [property=/mark|measure/] to single those out or [property!=/now|every|non|erroring|method/]. But I think that's not needed here.

Files using performance outside of the extension I've put ignores for this rule.

@Kuuuube Kuuuube added kind/meta The issue or PR is meta area/tech-debt labels Dec 17, 2024
@Kuuuube Kuuuube requested a review from a team as a code owner December 17, 2024 17:00
@@ -43,15 +43,18 @@ function main() {
const schema = parseJson(schemaSource);

for (const dataFileName of args.slice(1)) {
// eslint-disable-next-line no-restricted-syntax
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have something specific to the performance custom rule?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. I can't find anything in the eslint docs. But the name is a bit misleading. It does not disable all restricted syntax, it only disables the no-restricted-syntax rule. For Yomitan this means it only disables this:

"no-restricted-syntax": [
    "error",
    {
        "message": "Avoid using JSON.parse(), prefer parseJson.",
        "selector": "MemberExpression[object.name=JSON][property.name=parse]"
    },
    {
        "message": "Avoid using Response.json(), prefer readResponseJson.",
        "selector": "MemberExpression[property.name=json]"
    },
    {
        "message": "Avoid using performance, prefer safePerformance.",
        "selector": "MemberExpression[object.name=performance]"
    }
],

/**
* This object is the default performance measurer used by the runtime.
*/
export const safePerformance = new SafePerformance();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we shadow performance instead of using a new variable and changing calls?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but this would break the eslint rule. Checked to see if there's any way to ban the use of a specific class so we could ban Performance but I don't see any way to select that. Selecting performance will end up disallowing both the shadowed and not shadowed.

If the eslint rule is removed, this could work if you are suggesting making the new performance a global. It can't not be a global since any files that haven't imported the shadowing performance will be able to access the normal performance due to the missing eslint rule.

@jamesmaa jamesmaa added this pull request to the merge queue Dec 17, 2024
Merged via the queue into yomidevs:master with commit b39bd51 Dec 17, 2024
11 checks passed
djahandarie added a commit that referenced this pull request Dec 18, 2024
# This targets the branch of #1487

Fixes merge conflicts from #1677

History here looks a little funky but when it's actually merged into the
PR only 65ec09d and
e80b3c3 should show since master
already has the others.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/tech-debt kind/meta The issue or PR is meta
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants