https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122367
Bug ID: 122367
Summary: Runtime argument expansion removes non-quote character
on Windows
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: ada
Assignee: unassigned at gcc dot gnu.org
Reporter: octoberstargazer7405 at mivirl dot dev
CC: dkm at gcc dot gnu.org
Target Milestone: ---
On Windows (and only Windows), the runtime's command-line argument expansion
strips the first and last character from an argument if the first character is
a single quote, even if the last character isn't a matching quote (e.g.
`'example` becomes `exampl`)
Tested with the prebuilt binaries for 15.2.0-1 and 16.0.0 (snapshot) from
https://github.com/alire-project/GNAT-FSF-builds/
To reproduce the issue:
----------------------------------------------------------------------
-- echo_arguments.adb
with Ada.Command_Line;
with Ada.Text_IO;
procedure Echo_Arguments is
begin
for I in 1 .. Ada.Command_Line.Argument_Count loop
Ada.Text_IO.Put ("'");
declare
Argument : constant String := Ada.Command_Line.Argument (I);
begin
for J in Argument'Range loop
Ada.Text_IO.Put (
(case Argument (J) is
when ''' => "\'",
when '\' => "\\",
when others => "" & Argument (J)));
end loop;
end;
Ada.Text_IO.Put_Line ("'");
end loop;
end Echo_Arguments;
----------------------------------------------------------------------
When run in cmd.exe (which doesn't itself remove quotes):
>gnatmake echo_arguments.adb
>.\echo_arguments 'example
'exampl'
With the expected output being:
>.\echo_arguments 'example
'\'example'
A possible fix is to modify argument expansion so the quote detection checks
the characters removed by append_arg
(https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/ada/rtinit.c;hb=0c28cf56fe97bfd0ee4110ad2b8cac33bd513447#l316):
diff --git a/gcc/ada/rtinit.c b/gcc/ada/rtinit.c
--- a/gcc/ada/rtinit.c
+++ b/gcc/ada/rtinit.c
@@ -419,6 +419,7 @@ __gnat_runtime_initialize (int install_handler)
int last;
int argc_expanded = 0;
TCHAR result [MAX_PATH];
+ int arglen;
int quoted;
__gnat_get_argw (GetCommandLineW (), &wargv, &wargc);
@@ -436,7 +437,10 @@ __gnat_runtime_initialize (int install_handler)
for (k=1; k<wargc; k++)
{
- quoted = (wargv[k][0] == _T('\''));
+ arglen = _tcslen (wargv[k]);
+ quoted = (wargv[k][0] == _T('\'')
+ && 2 <= arglen
+ && wargv[k][arglen - 1] == _T('\''));
/* Check for wildcard expansion if the argument is not quoted. */
if (!quoted && __gnat_do_argv_expansion