Skip to content

[finding] check-comment-mask-corpus swallows an unknown FIRST option — --anything runs a full sweep and exits 0 instead of the usage error #16540

Description

@baozhoutao

Found while porting this script to objectui (objectui#7882). The defect is in objectstack's copy, so it is filed here rather than carried silently into the port. The port already guards it; objectstack does not.

The defect

scripts/check-comment-mask-corpus.mjs, in main():

const maskerFlag = argv.indexOf('--masker');
...
const rest = argv.filter((arg, index) => index !== maskerFlag && index !== maskerFlag + 1);
const unknown = rest.filter((arg) => arg.startsWith('--'));

When --masker is ABSENT, indexOf returns -1, so maskerFlag + 1 is 0. The filter that exists to drop the flag and its value instead drops argv[0] — the first argument. That argument is removed from the very list the unknown-option check then reads.

Consequence: an unknown option in first position is not reported. The script proceeds to a full sweep and exits 0.

node scripts/check-comment-mask-corpus.mjs --no-such-flag

Expected: unknown option(s): --no-such-flag, exit 2 (EXIT_USAGE).
Actual: no usage error; the whole-tree sweep runs and the process exits 0.

Measured in the objectui port (same code path, before the guard was added): the case took 33.5 s — the sweep's wall clock — where the usage path costs milliseconds. That timing is how the port's test caught it.

Why it matters more than a typo

This is a CLI whose whole contract is its exit code, and the failure direction is the quiet one: a misspelled or renamed flag is not refused, it is ignored, and the run reports on the DEFAULT configuration while the operator believes it reported on what they asked for. A future --json, --shard or --since typed in first position would do the same. --masker in first position is unaffected, which is why the shape survives casual use.

Only the first position is affected when --masker is absent. With --masker present, maskerFlag is a real index and the filter behaves.

Suggested shape (as implemented in the objectui port)

Guard the sentinel before using it as an index, and parse the command line once, ahead of the mode dispatch, so --masker with a missing value is a usage error rather than something a later mode flag skips over:

const rest = maskerFlag === -1
  ? argv
  : argv.filter((_arg, index) => index !== maskerFlag && index !== maskerFlag + 1);
const unknown = rest.filter((arg) => arg.startsWith('--') && arg !== '--self-test');

The objectui port covers this with cases that read parseArgs as VALUES (an unknown option is reported from argv[0] and from every other position), plus a spawned run pinning exit 2 as a number.

Not in scope of the card that found it

objectui#7882 is a measurement card about js-comment-mask.mjs's JSX residue and does not touch objectstack. Filed unassigned for triage; the objectui port carries the guard already, so nothing here is blocking it.

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions