vscode-cpptools icon indicating copy to clipboard operation
vscode-cpptools copied to clipboard

Launch task adding quotes to glob pattern args

Open MatiasDuhalde opened this issue 2 years ago • 3 comments

Environment

  • OS and version: Arch Linux x86_6 6.7.1-arch1-1
  • VS Code: 1.86.0-insider (3dea5cbbcb88d7f6dad71148f3d3f98b853ab836)
  • C/C++ extension: v1.19.2 (pre-release)
  • OS and version of remote machine (if applicable):
  • GDB / LLDB version: 14.1 / 16.0.6

Bug Summary and Steps to Reproduce

Bug Summary:

This problem only occurs in the pre-release version of the extension, the current release version (v1.18.5) works normally.

When launching a build task of type cppbuild, if glob patterns (i.e. **/*.cpp) are present in the args array, the extension will surround them with quotes, causing the build command to fail.

This bug applies both for clang++ and for g++.

Steps to reproduce:

  1. Install the pre-release version of the extension + have a compiler installed, such as clang++.
  2. Create a .vscode/tasks.json file containing a simple task:
{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "Glob pattern bug",
      "command": "clang++",
      "args": ["-g", "**/*.cpp", "other_file.cpp", "another_file.cpp", "**/glob_pattern/*"]
    }
  ],
  "version": "2.0.0"
}
  1. Execute the task.
  2. The command will fail, and the glob pattern tokens in args will be surrounded by quotes: clang++ -g '**/*.cpp' other_file.cpp another_file.cpp '**/glob_pattern/*'.

Debugger Configurations

// tasks.json
{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "Build app (clang/LLVM)",
      "command": "clang++",
      "detail": "Build the engine",
      "args": ["-fcolor-diagnostics", "-g", "main.cpp", "src/**/*.cpp", "-o", "main"],
      "problemMatcher": ["$gcc"],
      "hide": false,
      "isBackground": false,
      "icon": {
        "color": "terminal.ansiWhite",
        "id": "wrench"
      },
      "options": {
        "cwd": "${workspaceFolder}"
      },
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ],
  "version": "2.0.0"
}

Debugger Logs

*  Executing task: Build app (clang/LLVM) 

Starting build...
clang++ -fcolor-diagnostics -g main.cpp 'src/**/*.cpp' -o main
clang-16: error: no such file or directory: 'src/**/*.cpp'

Build finished with error(s).

 *  The terminal process failed to launch (exit code: -1). 
 *  Terminal will be reused by tasks, press any key to close it.

Other Extensions

No response

Additional Information

No response

MatiasDuhalde avatar Jan 25 '24 12:01 MatiasDuhalde

Seems to be caused by PR #11734 included in the latest pre-release version 1.19.2, particularly this regular expression that matches a string containing characters normally contained in a glob pattern:

https://github.com/microsoft/vscode-cpptools/blob/3f1e851152626e9af01387b672d565bf25498990/Extension/src/common.ts#L1415

MatiasDuhalde avatar Jan 25 '24 13:01 MatiasDuhalde

@browntarik , This seems to be an issue with use of child_process.spawn with a combination of an array of arguments and the shell option set to true. The documentation of this args field does not clearly indicate whether shell parsing should occur (when shell is set to true in options). Inconsistent behavior between platforms would seem to be a nodejs bug.

Arrays of arguments generally should never have shell escaping present, as they are not part of a command line, per se. A main purpose of shell escaping is to disambiguate how individual arguments are delimited on a command line, which should not be an issue when args are already separated into an array.

I'd suggest we instead use an API that is less ambiguous about this behavior, such as child_process.exec, as that accepts a command line instead of separate args. That call should inherently always do shell processing. If there wasn't a requirement here that we inject some shell operators (cmd /c chcp 65001>nul &&, on Windows), use of child_process.spawn with shell set to false, would be preferable.

Colengms avatar Jan 25 '24 23:01 Colengms

After further investigation, it looks like there are not any changes we can make to support this behavior, for some reason the api in child process in node.js does not correctly resolve glob patterns within the shell even though this behavior can be replicated with expanded glob patterns within the terminal. This seems like a node.js bug and would be better resolved through them: https://github.com/nodejs/node/issues

Additionally, this issue does not seem to work in 1.18.5 either.

browntarik avatar Feb 08 '24 21:02 browntarik

In the end this was fixed in v1.19.5, so I'll be closing this issue.

MatiasDuhalde avatar Mar 05 '24 08:03 MatiasDuhalde