https://gcc.gnu.org/g:a87954610f5e48a89b63a3194df9f5087bdc2f77

commit r15-2062-ga87954610f5e48a89b63a3194df9f5087bdc2f77
Author: Andrew Burgess <aburg...@redhat.com>
Date:   Wed Dec 6 16:45:31 2023 +0000

    libiberty/buildargv: POSIX behaviour for backslash handling
    
    GDB makes use of the libiberty function buildargv for splitting the
    inferior (program being debugged) argument string in the case where
    the inferior is not being started under a shell.
    
    I have recently been working to improve this area of GDB, and have
    tracked done some of the unexpected behaviour to the libiberty
    function buildargv, and how it handles backslash escapes.
    
    For reference, I've been mostly reading:
    
      https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
    
    The issues that I would like to fix are:
    
      1. Backslashes within single quotes should not be treated as an
      escape, thus: '\a' should split to \a, retaining the backslash.
    
      2. Backslashes within double quotes should only act as an escape if
      they are immediately before one of the characters $ (dollar),
      ` (backtick), " (double quote), ` (backslash), or \n (newline).  In
      all other cases a backslash should not be treated as an escape
      character.  Thus: "\a" should split to \a, but "\$" should split to
      $.
    
      3. A backslash-newline sequence should be treated as a line
      continuation, both the backslash and the newline should be removed.
    
    I've updated libiberty and also added some tests.  All the existing
    libiberty tests continue to pass, but I'm not sure if there is more
    testing that should be done, buildargv is used within lto-wraper.cc,
    so maybe there's some testing folk can suggest that I run?
    
    2024-07-16  Andrew Burgess  <aburg...@redhat.com>
    
    libiberty/
    
            * argv.c (buildargv): Backslashes within single quotes are
            literal, backslashes only escape POSIX defined special characters
            within double quotes, and backslashed newlines should act as line
            continuations.
            * testsuite/test-expandargv.c: Add new tests 7, 8, and 9.

Diff:
---
 libiberty/argv.c                      |  8 ++++++--
 libiberty/testsuite/test-expandargv.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/libiberty/argv.c b/libiberty/argv.c
index 45f168546032..d9d32e59e720 100644
--- a/libiberty/argv.c
+++ b/libiberty/argv.c
@@ -224,9 +224,13 @@ char **buildargv (const char *input)
                  if (bsquote)
                    {
                      bsquote = 0;
-                     *arg++ = *input;
+                     if (*input != '\n')
+                       *arg++ = *input;
                    }
-                 else if (*input == '\\')
+                 else if (*input == '\\'
+                          && !squote
+                          && (!dquote
+                              || strchr ("$`\"\\\n", *(input + 1)) != NULL))
                    {
                      bsquote = 1;
                    }
diff --git a/libiberty/testsuite/test-expandargv.c 
b/libiberty/testsuite/test-expandargv.c
index 1e9cb0a0d5a8..ea1aeb0eda2b 100644
--- a/libiberty/testsuite/test-expandargv.c
+++ b/libiberty/testsuite/test-expandargv.c
@@ -142,6 +142,40 @@ const char *test_data[] = {
   "b",
   0,
 
+  /* Test 7 - No backslash removal within single quotes.  */
+  "'a\\$VAR' '\\\"'",    /* Test 7 data */
+  ARGV0,
+  "@test-expandargv-7.lst",
+  0,
+  ARGV0,
+  "a\\$VAR",
+  "\\\"",
+  0,
+
+  /* Test 8 - Remove backslash / newline pairs.  */
+  "\"ab\\\ncd\" ef\\\ngh",    /* Test 8 data */
+  ARGV0,
+  "@test-expandargv-8.lst",
+  0,
+  ARGV0,
+  "abcd",
+  "efgh",
+  0,
+
+  /* Test 9 - Backslash within double quotes.  */
+  "\"\\$VAR\" \"\\`\" \"\\\"\" \"\\\\\" \"\\n\" \"\\t\"",    /* Test 9 data */
+  ARGV0,
+  "@test-expandargv-9.lst",
+  0,
+  ARGV0,
+  "$VAR",
+  "`",
+  "\"",
+  "\\",
+  "\\n",
+  "\\t",
+  0,
+
   0 /* Test done marker, don't remove. */
 };

Reply via email to