Skip to content

fix: parse short option with trailing equals and empty value (-o=) as empty string - #541

Open
youdie006 wants to merge 1 commit into
yargs:mainfrom
youdie006:fix/367-empty-short-option-equals
Open

fix: parse short option with trailing equals and empty value (-o=) as empty string#541
youdie006 wants to merge 1 commit into
yargs:mainfrom
youdie006:fix/367-empty-short-option-equals

Conversation

@youdie006

Copy link
Copy Markdown

Fixes #367

Problem

A short option written with a trailing = and no value mis-parses. The = is treated as a standalone key and the option becomes boolean true:

parser(['-o='], { alias: { o: 'opt' } })
// actual:   { _: [], o: true, opt: true, '=': true }
// expected: { _: [], o: '', opt: '' }

The equivalent long option already behaves correctly, which is the tell that this is a short-option-only bug:

parser(['--opt='])  // => { _: [], opt: '' }   (correct)

Root cause

In the short-option branch of lib/yargs-parser.ts, letters = arg.slice(1, -1).split('') strips the trailing =. For -o= that leaves letters = ['o'], so the letters[j + 1] === '=' guard never matches. Parsing falls through to setArg('o', defaultValue('o')) (boolean true) and then key = arg.slice(-1)[0] picks the trailing = up as a spurious key.

Fix

next is already computed as arg.slice(j + 2) and equals exactly '=' only on the final letter when the arg ends in a trailing =. Adding that as an alternative trigger routes -o= through the existing =-handling branch, where value = arg.slice(j + 3) correctly resolves to '':

if ((letters[j + 1] && letters[j + 1] === '=') || next === '=') {

Non-empty values (-o=x) are unaffected -- they still match the original letters[j + 1] === '=' condition.

Tests

Added a case next to the existing empty-value short-option test covering both -o= (empty) and the -o=x control. Full suite: 363 passing, lint clean.


This change was prepared with AI assistance and reviewed by the author.

… empty string

A short option written with a trailing '=' and no value (e.g. -o=) mis-parsed:
the '=' became a standalone key and the option was set to boolean true instead
of an empty string. The equivalent long option (--opt=) already yields '',
which is the tell that this is short-option-only.

In the short-option branch, letters = arg.slice(1, -1).split('') strips the
trailing '=', so the letters[j + 1] === '=' guard never matches for -o=.
next (arg.slice(j + 2)) equals exactly '=' only on the final letter when the
arg ends in a trailing '='; adding that as an alternative trigger routes -o=
through the existing '='-handling branch where value resolves to ''.

Fixes yargs#367
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.

Using an equal sign with short/alias options and an empty string

1 participant