GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Arguments for external executables aren't correctly escaped · Issue #1995 · PowerShell/PowerShell

Arguments for external executables aren't correctly escaped #1995

New issue
Copy link
New issue
Copy link
Closed
Closed
Arguments for external executables aren't correctly escaped#1995
Copy link
Labels
Committee-ReviewedPS-Committee has reviewed this and made a decisionPS-Committee has reviewed this and made a decisionResolution-FixedThe issue is fixed.The issue is fixed.WG-Enginecore PowerShell engine, interpreter, and runtimecore PowerShell engine, interpreter, and runtime
Milestone
7.2-Consider

Description

@be5invis
Belleve (be5invis)
opened on Aug 21, 2016
Issue body actions

Steps to reproduce

  1. write a C program native.exe which acquires ARGV
  2. Run native.exe "`"a`""

Expected behavior

ARGV[1] == "a"

Actual behavior

ARGV[1] == a

Environment data

Windows 10 x64

Name                           Value
----                           -----
PSVersion                      5.1.14393.0
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.0
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
Reacted by ggirard07, Nate McMaster, Amar Sood, Daniel Fallon, Giorgi Chakhidze, Mariusz Pawelski, Alexandre L., Nathan Lowe, Francis Agyapong, Felix Becker and 27 more

Activity

Next
  1. andyleejordan commented on Aug 31, 2016

    @andyleejordan
    Andy Jordan (andyleejordan)
    on Aug 31, 2016
    Member
    More actions

    Why do you think that "\"a\"" the expected behavior? My understanding of PowerShell escapes says that the actual behavior is the correct and expected behavior. ""a"" is a pair of quotes surrounding an escaped pair of quotes surrounding an a, so PowerShell interprets the outer unescaped pair as "this is a string argument" and so drops them, then interprets the escaped pair as escaped quotes and so keeps them, leaving you with "a". At no point was a \ added to the string.

    The fact that Bash uses \ as an escape character is irrelevant. In PowerShell, the escape character is a backtick. See PowerShell escape characters.

    If you want to pass literally "\"a\"", I believe you would use:

    > echo `"\`"a\`"`"
    "\"a\""
  2. Andy Jordan (andyleejordan)
    closed this as completedon Aug 31, 2016
  3. be5invis commented on Aug 31, 2016

    @be5invis
    Belleve (be5invis)
    on Aug 31, 2016
    Author
    More actions

    Andy Jordan (@andschwa)
    Yes, escapes works fine for internal cmdlets, but things get weird when communicate with native binaries, especially on Windows.
    When running native.exe ""a"", the ARGV[1] should be

    "a"
    

    (three characters)

    instead of

    a
    

    (one character).

  4. be5invis commented on Aug 31, 2016

    @be5invis
    Belleve (be5invis)
    on Aug 31, 2016
    Author
    More actions

    Currently to make native.exe correctly receive an ARGV with two quotes and an a character, you have to use this weird call:

    native.exe "\`"a\`""
    Reacted by Michael Klement, Ivan Akcheurov, Doug Maurer and Serhan Apaydın
    Reacted by Nathan Lowe, Gennadiy Belousov, Jiashuo Li, Amin Ya, Ivan Akcheurov, Luiz, oczkoisse, Haoran Ni and Lars Moelleken
  5. andyleejordan commented on Aug 31, 2016

    @andyleejordan
    Andy Jordan (andyleejordan)
    on Aug 31, 2016
    Member
    More actions

    Ah, I see. Re-opening.

  6. Andy Jordan (andyleejordan)
    reopened this on Aug 31, 2016
  7. andyleejordan commented on Aug 31, 2016

    @andyleejordan
    Andy Jordan (andyleejordan)
    on Aug 31, 2016
    Member
    More actions

    Out of a strong curiosity, what happens if you try a build using #1639?

  8. be5invis commented on Aug 31, 2016

    @be5invis
    Belleve (be5invis)
    on Aug 31, 2016
    Author
    More actions

    Andy Jordan (@andschwa) The same. You HAVE to double-esacpe to satisify both PowerShell and CommandLineToArgvW. This line:

    native.exe "`"a`""

    results a StartProcess equalivent to cmd

    native.exe ""a""
    Reacted by bb010g
  9. andyleejordan commented on Sep 19, 2016

    @andyleejordan
    Andy Jordan (andyleejordan)
    on Sep 19, 2016
    Member
    More actions

    Belleve (@be5invis) Douglas Thrift (@douglaswth) is this resolved via #2182?

  10. be5invis commented on Sep 20, 2016

    @be5invis
    Belleve (be5invis)
    on Sep 20, 2016 via email
    Author
    More actions
    No, We still need to add a backslash before a backtick-escaped double quote? This does not solve the double-escaping problem. (That is, we have to escape a double quote for both PowerShell and CommandLineToArgvW.)
  11. vors commented on Sep 20, 2016

    @vors
    sergei (vors)
    on Sep 20, 2016
    Collaborator
    More actions

    Since ""a"" is equal to '"a"', do you suggest that native.exe '"a"' should result in "\"a\""?

  12. douglaswth commented on Sep 20, 2016

    @douglaswth
    Douglas Thrift (douglaswth)
    on Sep 20, 2016
    Contributor
    More actions

    This seems like a feature request that if implemented could break a large number of already existing PowerShell scripts that use the required double escaping, so extreme care would be required with any solution.

    Reacted by Luiz
  13. be5invis commented on Sep 20, 2016

    @be5invis
    Belleve (be5invis)
    on Sep 20, 2016
    Author
    More actions

    sergei (@vors) Yes.
    Douglas Thrift (@douglaswth) The double-escaping is really silly: why do we need the “inner” escapes made in the DOS era?

    Reacted by Michael Klement, Jiashuo Li, Roy Ivy III and Paul Abrams
  14. be5invis commented on Sep 20, 2016

    @be5invis
    Belleve (be5invis)
    on Sep 20, 2016
    Author
    More actions

    sergei (@vors) Douglas Thrift (@douglaswth)
    This is a the C code used to show GetCommandLineW and CommandLineToArgvW results:

    #include <stdio.h>
    #include <wchar.h>
    #include <Windows.h>
    
    int main() {
      LPWSTR cmdline = GetCommandLineW();
      wprintf(L"Command Line : %s\n", cmdline);
    
      int nArgs;
      LPWSTR *szArglist = CommandLineToArgvW(cmdline, &nArgs);
      if (NULL == szArglist) {
        wprintf(L"CommandLineToArgvW failed\n");
        return 0;
      } else {
        for (int i = 0; i < nArgs; i++) {
          wprintf(L"argv[%d]: %s\n", i, szArglist[i]);
        }
      }
      LocalFree(szArglist);
    }
  15. be5invis commented on Sep 20, 2016

    @be5invis
    Belleve (be5invis)
    on Sep 20, 2016
    Author
    More actions

    Here is the result

    $ ./a "a b"
    Command Line : "Z:\playground\ps-cmdline\a.exe" "a b"
    argv[0]: Z:\playground\ps-cmdline\a.exe
    argv[1]: a b
    
    $ ./a 'a b'
    Command Line : "Z:\playground\ps-cmdline\a.exe" "a b"
    argv[0]: Z:\playground\ps-cmdline\a.exe
    argv[1]: a b
    
    $ ./a 'a"b'
    Command Line : "Z:\playground\ps-cmdline\a.exe" a"b
    argv[0]: Z:\playground\ps-cmdline\a.exe
    argv[1]: ab
    
    $ ./a 'a"b"c'
    Command Line : "Z:\playground\ps-cmdline\a.exe" a"b"c
    argv[0]: Z:\playground\ps-cmdline\a.exe
    argv[1]: abc
    
    $ ./a 'a\"b\"c'
    Command Line : "Z:\playground\ps-cmdline\a.exe" a\"b\"c
    argv[0]: Z:\playground\ps-cmdline\a.exe
    argv[1]: a"b"c
    
    Reacted by Jiashuo Li, Tatsunori Uchino, bb010g and Giorgi Chakhidze
  16. 218 remaining items

    Load more actions
  17. mklement0 commented on May 6, 2021

    @mklement0
    Michael Klement (mklement0)
    on May 6, 2021
    Contributor
    More actions

    A decision regarding the accommodations on Windows has been made: #15143 (comment).

  18. Ilya (iSazonov)
    added
    Area-FileSystem-Providerspecific to the FileSystem providerspecific to the FileSystem provider
    and removed
    Area-FileSystem-Providerspecific to the FileSystem providerspecific to the FileSystem provider
    on Dec 1, 2021
  19. Steve Lee (SteveL-MSFT)
    added
    Resolution-FixedThe issue is fixed.The issue is fixed.
    on Aug 11, 2022
  20. SteveL-MSFT commented on Aug 11, 2022

    @SteveL-MSFT
    Steve Lee (SteveL-MSFT)
    on Aug 11, 2022
    Member
    More actions

    This appears to be fixed in 7.3:

    PS> testexe -echoargs "`"a`""
    Arg 0 is <"a">
    Reacted by Luiz
  21. Steve Lee (SteveL-MSFT)
    closed this as completedon Aug 11, 2022
  22. jiasli commented on Aug 11, 2022

    @jiasli
    Jiashuo Li (jiasli)
    on Aug 11, 2022
    More actions

    This appears to be fixed in 7.3:

    Thanks a lot Steve Lee (@SteveL-MSFT). May I know which PR is responsible for the fix?

  23. jiasli commented on Aug 11, 2022

    @jiasli
    Jiashuo Li (jiasli)
    on Aug 11, 2022
    More actions

    I can verify double quotes are escaped correctly in v7.3.0-preview.6 when calling a .exe.

    > echo $PSVersionTable
    
    Name                           Value
    ----                           -----
    PSVersion                      7.3.0-preview.6
    ...
    
    > python -c "import sys; print(sys.argv)" '"ab"'
    ['-c', '"ab"']
    

    However, special characters (", |, &) are still not escaped correctly when invoking a cmd script. Consider a very simply script test.cmd:

    echo %*
    python -c "import sys; print(sys.argv)" %*

    For |, running test.cmd in PowerShell v7.3.0-preview.6 gives:

    PS D:\> ./test.cmd "a|b"
    'b' is not recognized as an internal or external command,
    operable program or batch file.
    

    This differs from the behavior of Command Prompt:

    D:\>test.cmd "a|b"
    
    D:\>echo "a|b"
    "a|b"
    
    D:\>python -c "import sys; print(sys.argv)" "a|b"
    ['-c', 'a|b']
    

    This causes problem for Azure CLI when there is | or & in argument value: Azure/azure-cli#20972

    For ", running test.cmd in PowerShell v7.3.0-preview.6 gives:

    PS D:\> ./test.cmd "`"ab`""
    
    D:\>echo "ab"
    "ab"
    
    D:\>python -c "import sys; print(sys.argv)" "ab"
    ['-c', 'ab']
    

    This differs from the behavior of Command Prompt:

    D:\>test.cmd "\"ab\""
    
    D:\>echo "\"ab\""
    "\"ab\""
    
    D:\>python -c "import sys; print(sys.argv)" "\"ab\""
    ['-c', '"ab"']
    
    Reacted by Roy Ivy III
  24. rivy commented on Aug 11, 2022

    @rivy
    Roy Ivy III (rivy)
    on Aug 11, 2022
    More actions

    As noted by Jiashuo Li (@jiasli), this issue is not actually fixed.

    Reacted by Christopher Yeleighton
  25. brendandburns commented on Aug 11, 2022

    @brendandburns
    Brendan Burns (brendandburns)
    on Aug 11, 2022
    Contributor
    More actions

    The PowerShell behavior here is the same as bash

    test.sh:

    #!/bin/bash
    
    echo $@
    bburns@DESKTOP-VHJJ57D:~$ ./test.sh "a|b"
    a|b
    bburns@DESKTOP-VHJJ57D:~$ ./test.sh "a&b"
    a&b
    bburns@DESKTOP-VHJJ57D:~$

    In my opinion, the bash/powershell behavior makes more sense than the cmd behavior. In the above example, the quotes are intended for the shell interpreter, they are not part of the user's input. The shell's job is to pass each value as a String to the command that it calls. It is the executable/command scripts responsibility to re-escape as necessary before shelling out again.

  26. brendandburns commented on Aug 11, 2022

    @brendandburns
    Brendan Burns (brendandburns)
    on Aug 11, 2022
    Contributor
    More actions

    Furthermore this seems to be a specific behavior related to cmd.exe calling command scripts.

    import sys
    print(sys.argv)
    C:\Users\bburns>py test.py 'a|b'
    'b'' is not recognized as an internal or external command,
    operable program or batch file.
    
    C:\Users\bburns>py test.py 'a&b'
    ['test.py', "'a"]
    'b'' is not recognized as an internal or external command,
    operable program or batch file.
  27. yecril71pl commented on Sep 16, 2022

    @yecril71pl
    Christopher Yeleighton (yecril71pl)
    on Sep 16, 2022
    Contributor
    More actions

    As noted by Jiashuo Li (@jiasli), this issue is not actually fixed.

    This issue is about passing arguments to native executables that support passing arguments. The executable cmd.exe is not one of them, it uses the whole command line instead. The only reliable way to call cmd.exe is to print the expected command line out into a temporary command script and run that script without any arguments.

    Reacted by Luiz
  28. mayerwin
    added a commit that references this issue on Apr 28, 2026

    Fix npm "Unknown command: pm" in build-play-aab on Windows PowerShell…

    7b99205
  29. Alina (AlinaWan)
    added a commit that references this issue on Sep 7, 2026

    feat!: add the print statement and static modifier

    a8bf600
  30. Hakan Gök (hakanngok)
    added a commit that references this issue on Sep 23, 2026

    Acik temada terminal acilirken 'Invalid JSON provided to --settings' …

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Committee-ReviewedPS-Committee has reviewed this and made a decisionPS-Committee has reviewed this and made a decisionResolution-FixedThe issue is fixed.The issue is fixed.WG-Enginecore PowerShell engine, interpreter, and runtimecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

      Milestone

      • 7.2-ConsiderNo due date

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.