Skip to content

Add test coverage for optional backtick prior to flags for PowerShell#2458

Open
ericcornelissen wants to merge 14 commits intomainfrom
powershell-hyphen-backtick
Open

Add test coverage for optional backtick prior to flags for PowerShell#2458
ericcornelissen wants to merge 14 commits intomainfrom
powershell-hyphen-backtick

Conversation

@ericcornelissen
Copy link
Copy Markdown
Owner

@ericcornelissen ericcornelissen commented Apr 4, 2026

Closes #2014
Relates to #908, #2036, #2436 (comment)

@ericcornelissen ericcornelissen added the test Relates to testing label Apr 4, 2026
Because when escaping the backtick is escaped and thus preserved in the
output and when quoting the backtick has no effect (it is not otherwise
escaped either).
@github-actions github-actions bot added the ci/cd Relates to ci/cd label Apr 4, 2026
@ericcornelissen ericcornelissen added the bug Something isn't working label Apr 5, 2026
Re-implement the internal logic for the flag protection functionality.
At a high level, the old implementation is removed and a new one is
implemented instead. The reason for removing the old implementation is
that it was fundamentally flawed because of a circular relation between
escaping and flag protection: escaping might change the input string
such that flag protection is necessary and flag protection may change
the result of escaping because it changes the input string. This buggy
behavior is (hopefully) fixed and has been recorded in the changelog.

To address this the "flagProtection" function has been replaced by
a function that splits the provided argument into flag-prefix and
non-flag-prefix parts and escapes and prunes the argument prefix
iteratively [^1] until there are no more empty-after-escaping or
flag-prefixes left, at which point the remaining string is escaped
(and quoted, if necessary).

This also fixes a bug with flag protection that did not require the
full rewriting, namely that on Windows a prefix combining `-` and `/`
would always leave one or the other, thus leaving flags behind. This bug
has been recorded separately in the changelog.

This _finally_ makes the dream of having flag protection be a platform
(rather than shell) level things be a reality!

This change is accompanied by a ton of changes to the test suite that
should increase the confidence in the change and new behavior. First and
foremost, as this change was triggered by a problem with flag protection
on Windows, the test fixtures for windows have been significantly
extended focussing on flag-related character (`-` and `/`) and their
combination. The changes to the `index.test.js` unit suites is just as
a result of lifting the flag protection from the shell to the platform
level. The `shells.test.js` similarly have most test related to flag
protection removed but did get back tests for the composition of flag
protection with the shell specific escaping and quoting logic. Notably,
this expands the testing of flag protection beyond fixtures into
property tests (testing the metamorphic property that adding a flag
prefix to an argument does not affect how the argument is escaped
compared to escaping the argument itself).

Lastly, this reverts some temporary changes intended for testing Windows
stuff in CI.

---
[^1]: See the `pathological strings` fixtures for example of why this is
      necessary.
@ericcornelissen ericcornelissen marked this pull request as ready for review April 5, 2026 14:33
- Revert temporary change.
- Remove use of `||=`.
- Fix uncaught mutant (`(arg) => [arg]` -> `(arg) => []`).
@ericcornelissen

This comment has been minimized.

@coderabbitai

This comment has been minimized.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

Walkthrough

This change refactors flag protection handling by introducing a shared compose utility function that chains escaping, flag-protection, and quoting transformations. Flag protection capabilities are centralized into new getFlagFunction() exports in src/internal/unix.js and src/internal/win.js, replacing per-shell getFlagProtectionFunction() exports across all shell modules. The main constructor in src/index.js switches from conditional branching to using the new composition pattern. Test suites and fixtures are updated to invoke flag protection through the composition pipeline rather than calling shell-specific flag protection functions directly. New test cases for pathological input strings are added across Unix and Windows fixture files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Labels

bug Something isn't working ci/cd Relates to ci/cd test Relates to testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flag protection functionality is platform specific rather than shell specific?

1 participant