aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2023-12-06 16:45:31 +0000
committerAndrew Burgess <aburgess@redhat.com>2024-07-16 13:51:15 +0100
commita87954610f5e48a89b63a3194df9f5087bdc2f77 (patch)
treed43e7b45ecfb7589808de85c2da74bae319b11b3
parentacd4ab8d6e8938d48e74ad04adf22ece280e35c0 (diff)
downloadgcc-a87954610f5e48a89b63a3194df9f5087bdc2f77.zip
gcc-a87954610f5e48a89b63a3194df9f5087bdc2f77.tar.gz
gcc-a87954610f5e48a89b63a3194df9f5087bdc2f77.tar.bz2
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 <aburgess@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.
-rw-r--r--libiberty/argv.c8
-rw-r--r--libiberty/testsuite/test-expandargv.c34
2 files changed, 40 insertions, 2 deletions
diff --git a/libiberty/argv.c b/libiberty/argv.c
index 45f1685..d9d32e5 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 1e9cb0a..ea1aeb0 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. */
};