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

Reply via email to