Skip to content

fix: array type flags (number/boolean/string) should respect their value#533

Open
chatman-media wants to merge 1 commit into
yargs:mainfrom
chatman-media:fix/array-type-flag-respects-value
Open

fix: array type flags (number/boolean/string) should respect their value#533
chatman-media wants to merge 1 commit into
yargs:mainfrom
chatman-media:fix/array-type-flag-respects-value

Conversation

@chatman-media

Copy link
Copy Markdown

Fixes #415.

Problem

When an array option is configured with an object, the parser decides whether to coerce its values to number/boolean/string based on the presence of the corresponding key, ignoring its value. As a result a falsy type flag still enables coercion:

const parser = require("yargs-parser")

parser("--foo dog cat", { array: { key: "foo", number: false } })
// actual:   { _: [], foo: [ null, null ] }   (NaN on older versions)
// expected: { _: [], foo: [ "dog", "cat" ] }

parser("--foo dog cat", { array: { key: "foo", number: undefined } })
// same wrong result

The README documents enabling coercion with number: true, and the type definition declares these properties as boolean?, so false/undefined should behave as if the flag were absent. The same bug affects boolean: false (values wrongly coerced to booleans) and string: false (numbers wrongly kept as strings).

Cause

In lib/yargs-parser.ts, the assignment was derived from Object.keys(opt), which only checks key existence:

const assignment = Object.keys(opt).map(function (key) {
  const arrayFlagKeys = { boolean: "bools", string: "strings", number: "numbers" }
  return arrayFlagKeys[key]
}).filter(Boolean).pop()

Fix

Only enable a coercion flag when its value is strictly === true. (Also guards the object-vs-string opt case explicitly, instead of relying on a string`s numeric character indices never matching a flag name.)

Tests

Added four tests covering number: false, number: undefined, boolean: false, and string: false. All four fail on main and pass with the fix; the full suite (npm test) stays green (366 passing) with 100% coverage on yargs-parser.ts, and npm run check (gts lint) is clean.

When an array option was configured with an object such as
{ key: 'foo', number: false }, the parser enabled number coercion
regardless of the value because it only checked for the presence of
the key rather than whether it was truthy. As a result, number: false,
number: undefined, boolean: false and string: false all changed parsing
instead of being treated as if the flag were absent.

Only enable the corresponding coercion when the type flag is === true.

Closes yargs#415
@shadowspawn

Copy link
Copy Markdown
Member

(Will be a while before I review this. Both the original code and replacement code are somewhat opaque, and other issues waiting.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Existence of ‘number’ Key in Options.arrays Changes Parsing

2 participants