Prevent corruption of disassembler listing command for paths w/ spaces #253
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This platform uses a build hook to save a disassembler listing to the build folder when compiling sketches.
Due to the use of a redirection operator in the command, it was necessary to execute it via the Windows command interpreter by passing it as an argument to
cmd /c
.Although paths with spaces can be used without difficulty in pattern generated commands executed directly by the Arduino framework, things are more complicated when it comes to executing commands indirectly via
cmd /c
.The
cmd /c
command has an odd handling of quotes:https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/cmd#remarks
Under certain conditions, the first and last quotation mark of the command passed via the argument to
/c
are stripped.These conditions occur for the command generated via the platform's
recipe.hooks.objcopy.postobjcopy.1.pattern.windows
property when the both the path toavr-objdump
and the temporary build path contain a space.The removal of the essential quotes from the start and end of the command executed by
cmd /c
causes an error. for example, if theavr-objdump
path was:The command will fail with the error:
One of the required conditions for the unwanted quote stripping is that the first character of the argument to
cmd /c
is a double quote. So this unwanted behavior can be avoided by ensuring the first character is not a double quote. That is accomplished here by adding a dummy command (adds a blank line to the output, but the most suitable "no operation" candidate I found) that does not require quoting at the start of the argument.Demo of bug
(Arduino CLI used only because it makes it easy to customize the paths to contain spaces)
Additional information
Alternatives considered
It might seem that a less hacky approach would be to simply wrap the entire argument to
cmd /c
in an extra layer of sacrificial quotes, leaving the essential quotes intact in the command that is finally executed. While that does indeed work when running the command directly from the command line, it does not work when used in a pattern in the Arduino platform configuration framework. The problem is that the string generated from the platform pattern can not be executed as is. It must be split into arguments. The list of arguments space separated, with quoting where an argument contains a space.These arguments may contain quote characters, which must be escaped. This escaping is where the simple approach of extra quotes becomes unusable. The
os/exec
Go package used to handle the escaping does that in a way that is compatible with directly executing a command, but is not compatible with the legacy escaping system used by cmd:https://pkg.go.dev/os/exec#Command
Scope of bug
It seems this problem of the command having paths with spaces did not occur in Arduino IDE 1.x due to it using a Windows "8.3" format for the default build path, which does not contain spaces. Arduino CLI (and thus Arduino IDE 2.x) uses the full path format instead. However, the bug could also occur in Arduino IDE 1.x if the user sets a custom
build.path
with spaces.recipe.hooks.savehex.presavehex.2.pattern.windows
also usescmd /C
. However, this command is not subject to the quote stripping because it does not ever have a double quote as the first character of the argument.Related
Originally reported by @cattledogGH
Previous discussion at MCUdude/MegaCoreX#159