On 31/03/2024 22:02, Bruno Haible wrote:
Pádraig Brady wrote:
If a string starts with a sequence that requires $'' quoting followed
by a \' and then another charactrer requiring $'' quoting, the '$' at
the start of the quoted string ends up missing:

      $ env printf '%q\n' $'\1\'\2'
      '\001'\'''$'\002'

Indeed that is a bug.
I'll be able to have a look at this tomorrow.

The '$' at the beginning is only missing in specific cases:

$ ./printf '%q\n' $'\1\'\2'
'\001'\'''$'\002'
$ ./printf '%q\n' $'a\1\'\2'
'''a'$'\001'\'''$'\002'
$ ./printf '%q\n' $'\1\'\2x'
''$'\001'\'''$'\002''x'

Also, let me apply some documentation improvement to the .h file (attached).

The attached should fix this issue.

cheers,
Pádraig
From c0962db4411fceeb9b5c170f567aa0d06718e335 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Wed, 3 Apr 2024 15:46:47 +0100
Subject: [PATCH] quotearg: fix shell-escape quoting with single quotes

With shell-escape quoting, we misquoted strings
where the first and last characters required escaping,
while the string also contained single quotes.

* lib/quotearg.c (quotearg_buffer_restyled): Ensure that
pending_shell_escape_end is reset to the initial state
when reprocessing input due to single quotes.
* tests/test-quotearg-simple.c: Add a minimal test case.
* tests/test-quotearg.c: Likewise.
* tests/test-quotearg.h: Likewise.
Reported by Grisha Levit
---
 ChangeLog                    |  15 +++
 lib/quotearg.c               |   2 +-
 tests/test-quotearg-simple.c | 176 +++++++++++++++++++----------------
 tests/test-quotearg.c        |  12 +--
 tests/test-quotearg.h        |   7 +-
 5 files changed, 123 insertions(+), 89 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d6b9f731bc..226d0d5311 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2024-04-03  Pádraig Brady  <p...@draigbrady.com>
+
+	quotearg: fix shell-escape quoting with single quotes
+	With shell-escape quoting, we misquoted strings
+	where the first and last characters required escaping,
+	while the string also contained single quotes.
+
+	* lib/quotearg.c (quotearg_buffer_restyled): Ensure that
+	pending_shell_escape_end is reset to the initial state
+	when reprocessing input due to single quotes.
+	* tests/test-quotearg-simple.c: Add a minimal test case.
+	* tests/test-quotearg.c: Likewise.
+	* tests/test-quotearg.h: Likewise.
+	Reported by Grisha Levit
+
 2024-04-02  Collin Funk  <collin.fu...@gmail.com>
 
 	gnulib-tool.py: Use [] instead of list() to initialize empty lists.
diff --git a/lib/quotearg.c b/lib/quotearg.c
index 847101e605..958f589e52 100644
--- a/lib/quotearg.c
+++ b/lib/quotearg.c
@@ -260,7 +260,6 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
   bool backslash_escapes = false;
   bool unibyte_locale = MB_CUR_MAX == 1;
   bool elide_outer_quotes = (flags & QA_ELIDE_OUTER_QUOTES) != 0;
-  bool pending_shell_escape_end = false;
   bool encountered_single_quote = false;
   bool all_c_and_shell_quote_compat = true;
 
@@ -304,6 +303,7 @@ quotearg_buffer_restyled (char *buffer, size_t buffersize,
     while (0)
 
  process_input:
+  bool pending_shell_escape_end = false;
 
   switch (quoting_style)
     {
diff --git a/tests/test-quotearg-simple.c b/tests/test-quotearg-simple.c
index 5a9a7695e8..18d33d4344 100644
--- a/tests/test-quotearg-simple.c
+++ b/tests/test-quotearg-simple.c
@@ -33,124 +33,138 @@
 
 static struct result_groups results_g[] = {
   /* literal_quoting_style */
-  { { "", "\0""1\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+  { { "", "\0""1\0", 3, "simple", "\t'\t", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
       "a' b", LQ RQ, LQ RQ },
-    { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+    { "", "1", 1, "simple", "\t'\t", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
       "a' b", LQ RQ, LQ RQ },
-    { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+    { "", "1", 1, "simple", "\t'\t", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
       "a' b", LQ RQ, LQ RQ } },
 
   /* shell_quoting_style */
-  { { "''", "\0""1\0", 3, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
-      "'a\\b'", "\"a' b\"", LQ RQ, LQ RQ },
-    { "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "a:b",
-      "'a\\b'", "\"a' b\"", LQ RQ, LQ RQ },
-    { "''", "1", 1, "simple", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
-      "'a\\b'", "\"a' b\"", LQ RQ, LQ RQ } },
+  { { "''", "\0""1\0", 3, "simple", "'\t'\\''\t'",
+      "' \t\n'\\''\"\033?""?/\\'", "a:b", "'a\\b'", "\"a' b\"",
+      LQ RQ, LQ RQ },
+    { "''", "1", 1, "simple", "'\t'\\''\t'",
+      "' \t\n'\\''\"\033?""?/\\'", "a:b", "'a\\b'", "\"a' b\"",
+      LQ RQ, LQ RQ },
+    { "''", "1", 1, "simple", "'\t'\\''\t'",
+      "' \t\n'\\''\"\033?""?/\\'", "'a:b'", "'a\\b'", "\"a' b\"",
+      LQ RQ, LQ RQ } },
 
   /* shell_always_quoting_style */
-  { { "''", "'\0""1\0'", 5, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
-      "'a\\b'", "\"a' b\"", "'" LQ RQ "'", "'" LQ RQ "'" },
-    { "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
-      "'a\\b'", "\"a' b\"", "'" LQ RQ "'", "'" LQ RQ "'" },
-    { "''", "'1'", 3, "'simple'", "' \t\n'\\''\"\033?""?/\\'", "'a:b'",
-      "'a\\b'", "\"a' b\"", "'" LQ RQ "'", "'" LQ RQ "'" } },
+  { { "''", "'\0""1\0'", 5, "'simple'", "'\t'\\''\t'",
+      "' \t\n'\\''\"\033?""?/\\'", "'a:b'", "'a\\b'", "\"a' b\"",
+      "'" LQ RQ "'", "'" LQ RQ "'" },
+    { "''", "'1'", 3, "'simple'", "'\t'\\''\t'",
+      "' \t\n'\\''\"\033?""?/\\'", "'a:b'", "'a\\b'", "\"a' b\"",
+      "'" LQ RQ "'", "'" LQ RQ "'" },
+    { "''", "'1'", 3, "'simple'", "'\t'\\''\t'",
+      "' \t\n'\\''\"\033?""?/\\'", "'a:b'", "'a\\b'", "\"a' b\"",
+      "'" LQ RQ "'", "'" LQ RQ "'" } },
 
   /* shell_escape_quoting_style */
-  { { "''", "''$'\\0''1'$'\\0'", 15, "simple",
+  { { "''", "''$'\\0''1'$'\\0'", 15, "simple", "''$'\\t'\\'''$'\\t'",
       "' '$'\\t\\n'\\''\"'$'\\033''?""?/\\'", "a:b",
       "'a\\b'", "\"a' b\"", "''$'" LQ_ENC RQ_ENC "'", LQ RQ },
-    { "''", "''$'\\0''1'$'\\0'", 15, "simple",
+    { "''", "''$'\\0''1'$'\\0'", 15, "simple", "''$'\\t'\\'''$'\\t'",
       "' '$'\\t\\n'\\''\"'$'\\033''?""?/\\'", "a:b",
       "'a\\b'", "\"a' b\"", "''$'" LQ_ENC RQ_ENC "'", LQ RQ },
-    { "''", "''$'\\0''1'$'\\0'", 15, "simple",
+    { "''", "''$'\\0''1'$'\\0'", 15, "simple", "''$'\\t'\\'''$'\\t'",
       "' '$'\\t\\n'\\''\"'$'\\033''?""?/\\'", "'a:b'",
       "'a\\b'", "\"a' b\"", "''$'" LQ_ENC RQ_ENC "'", LQ RQ } },
 
   /* shell_escape_always_quoting_style */
-  { { "''", "''$'\\0''1'$'\\0'", 15, "'simple'",
+  { { "''", "''$'\\0''1'$'\\0'", 15, "'simple'", "''$'\\t'\\'''$'\\t'",
       "' '$'\\t\\n'\\''\"'$'\\033''?""?/\\'", "'a:b'",
       "'a\\b'", "\"a' b\"", "''$'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
-    { "''", "''$'\\0''1'$'\\0'", 15, "'simple'",
+    { "''", "''$'\\0''1'$'\\0'", 15, "'simple'", "''$'\\t'\\'''$'\\t'",
       "' '$'\\t\\n'\\''\"'$'\\033''?""?/\\'", "'a:b'",
       "'a\\b'", "\"a' b\"", "''$'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
-    { "''", "''$'\\0''1'$'\\0'", 15, "'simple'",
+    { "''", "''$'\\0''1'$'\\0'", 15, "'simple'", "''$'\\t'\\'''$'\\t'",
       "' '$'\\t\\n'\\''\"'$'\\033''?""?/\\'", "'a:b'",
       "'a\\b'", "\"a' b\"", "''$'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" } },
 
   /* c_quoting_style */
-  { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+  { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
-    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
-    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } },
 
   /* c_maybe_quoting_style */
-  { { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
-      "a:b", "a\\b", "a' b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
-    { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
-      "a:b", "a\\b", "a' b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
-    { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
-      "\"a:b\"", "a\\b", "a' b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
+  { { "", "\"\\0001\\0\"", 9, "simple", "\"\\t'\\t\"",
+      "\" \\t\\n'\\\"\\033?""?/\\\\\"", "a:b", "a\\b", "a' b",
+      "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+    { "", "\"\\0001\\0\"", 9, "simple", "\"\\t'\\t\"",
+      "\" \\t\\n'\\\"\\033?""?/\\\\\"", "a:b", "a\\b", "a' b",
+      "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+    { "", "\"\\0001\\0\"", 9, "simple", "\"\\t'\\t\"",
+      "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "a\\b", "a' b",
+      "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
 
   /* escape_quoting_style */
-  { { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
-      "a\\\\b", "a' b", LQ_ENC RQ_ENC, LQ RQ },
-    { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a:b",
-      "a\\\\b", "a' b", LQ_ENC RQ_ENC, LQ RQ },
-    { "", "\\0001\\0", 7, "simple", " \\t\\n'\"\\033?""?/\\\\", "a\\:b",
-      "a\\\\b", "a' b", LQ_ENC RQ_ENC, LQ RQ } },
+  { { "", "\\0001\\0", 7, "simple", "\\t'\\t", " \\t\\n'\"\\033?""?/\\\\",
+      "a:b", "a\\\\b", "a' b", LQ_ENC RQ_ENC, LQ RQ },
+    { "", "\\0001\\0", 7, "simple", "\\t'\\t", " \\t\\n'\"\\033?""?/\\\\",
+      "a:b", "a\\\\b", "a' b", LQ_ENC RQ_ENC, LQ RQ },
+    { "", "\\0001\\0", 7, "simple", "\\t'\\t", " \\t\\n'\"\\033?""?/\\\\",
+      "a\\:b", "a\\\\b", "a' b", LQ_ENC RQ_ENC, LQ RQ } },
 
   /* locale_quoting_style */
-  { { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
-      "'a:b'", "'a\\\\b'", "'a\\' b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
-    { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
-      "'a:b'", "'a\\\\b'", "'a\\' b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
-    { "''", "'\\0001\\0'", 9, "'simple'", "' \\t\\n\\'\"\\033?""?/\\\\'",
-      "'a\\:b'", "'a\\\\b'", "'a\\' b'",
+  { { "''", "'\\0001\\0'", 9, "'simple'", "'\\t\\'\\t'",
+      "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'", "'a\\' b'",
+      "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
+    { "''", "'\\0001\\0'", 9, "'simple'", "'\\t\\'\\t'",
+      "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'", "'a\\' b'",
+      "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
+    { "''", "'\\0001\\0'", 9, "'simple'", "'\\t\\'\\t'",
+      "' \\t\\n\\'\"\\033?""?/\\\\'", "'a\\:b'", "'a\\\\b'", "'a\\' b'",
       "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" } },
 
   /* clocale_quoting_style */
-  { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+  { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
-    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
-    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } }
 };
 
 static struct result_groups flag_results[] = {
   /* literal_quoting_style and QA_ELIDE_NULL_BYTES */
-  { { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", "a' b",
-      LQ RQ, LQ RQ },
-    { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", "a' b",
-      LQ RQ, LQ RQ },
-    { "", "1", 1, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b", "a' b",
-      LQ RQ, LQ RQ } },
+  { { "", "1", 1, "simple", "\t'\t", " \t\n'\"\033?""?/\\",
+      "a:b", "a\\b", "a' b", LQ RQ, LQ RQ },
+    { "", "1", 1, "simple", "\t'\t", " \t\n'\"\033?""?/\\",
+      "a:b", "a\\b", "a' b", LQ RQ, LQ RQ },
+    { "", "1", 1, "simple", "\t'\t", " \t\n'\"\033?""?/\\",
+      "a:b", "a\\b", "a' b", LQ RQ, LQ RQ } },
 
   /* c_quoting_style and QA_ELIDE_OUTER_QUOTES */
-  { { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
-      "a:b", "a\\b", "a' b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
-    { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
-      "a:b", "a\\b", "a' b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
-    { "", "\"\\0001\\0\"", 9, "simple", "\" \\t\\n'\\\"\\033?""?/\\\\\"",
-      "\"a:b\"", "a\\b", "a' b", "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
+  { { "", "\"\\0001\\0\"", 9, "simple", "\"\\t'\\t\"",
+      "\" \\t\\n'\\\"\\033?""?/\\\\\"", "a:b", "a\\b", "a' b",
+      "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+    { "", "\"\\0001\\0\"", 9, "simple", "\"\\t'\\t\"",
+      "\" \\t\\n'\\\"\\033?""?/\\\\\"", "a:b", "a\\b", "a' b",
+      "\"" LQ_ENC RQ_ENC "\"", LQ RQ },
+    { "", "\"\\0001\\0\"", 9, "simple", "\"\\t'\\t\"",
+      "\" \\t\\n'\\\"\\033?""?/\\\\\"", "\"a:b\"", "a\\b", "a' b",
+      "\"" LQ_ENC RQ_ENC "\"", LQ RQ } },
 
   /* c_quoting_style and QA_SPLIT_TRIGRAPHS */
-  { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+  { { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
-    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" },
-    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"",
+    { "\"\"", "\"\\0001\\0\"", 9, "\"simple\"", "\"\\t'\\t\"",
       "\" \\t\\n'\\\"\\033?\"\"?/\\\\\"", "\"a\\:b\"", "\"a\\\\b\"",
       "\"a' b\"", "\"" LQ_ENC RQ_ENC "\"", "\"" LQ RQ "\"" } }
 };
@@ -167,79 +181,79 @@ static char const *custom_quotes[][2] = {
 
 static struct result_groups custom_results[] = {
   /* left_quote = right_quote = "" */
-  { { "", "\\0001\\0", 7, "simple",
+  { { "", "\\0001\\0", 7, "simple", "\\t'\\t",
       " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
       "a' b", LQ_ENC RQ_ENC, LQ RQ },
-    { "", "\\0001\\0", 7, "simple",
+    { "", "\\0001\\0", 7, "simple", "\\t'\\t",
       " \\t\\n'\"\\033?""?/\\\\", "a:b", "a\\\\b",
       "a' b", LQ_ENC RQ_ENC, LQ RQ },
-    { "", "\\0001\\0", 7, "simple",
+    { "", "\\0001\\0", 7, "simple", "\\t'\\t",
       " \\t\\n'\"\\033?""?/\\\\", "a\\:b", "a\\\\b",
       "a' b", LQ_ENC RQ_ENC, LQ RQ } },
 
   /* left_quote = right_quote = "'" */
-  { { "''", "'\\0001\\0'", 9, "'simple'",
+  { { "''", "'\\0001\\0'", 9, "'simple'", "'\\t\\'\\t'",
       "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
       "'a\\' b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
-    { "''", "'\\0001\\0'", 9, "'simple'",
+    { "''", "'\\0001\\0'", 9, "'simple'", "'\\t\\'\\t'",
       "' \\t\\n\\'\"\\033?""?/\\\\'", "'a:b'", "'a\\\\b'",
       "'a\\' b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" },
-    { "''", "'\\0001\\0'", 9, "'simple'",
+    { "''", "'\\0001\\0'", 9, "'simple'", "'\\t\\'\\t'",
       "' \\t\\n\\'\"\\033?""?/\\\\'", "'a\\:b'", "'a\\\\b'",
       "'a\\' b'", "'" LQ_ENC RQ_ENC "'", "'" LQ RQ "'" } },
 
   /* left_quote = "(" and right_quote = ")" */
-  { { "()", "(\\0001\\0)", 9, "(simple)",
+  { { "()", "(\\0001\\0)", 9, "(simple)", "(\\t'\\t)",
       "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
       "(a' b)", "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" },
-    { "()", "(\\0001\\0)", 9, "(simple)",
+    { "()", "(\\0001\\0)", 9, "(simple)", "(\\t'\\t)",
       "( \\t\\n'\"\\033?""?/\\\\)", "(a:b)", "(a\\\\b)",
       "(a' b)", "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" },
-    { "()", "(\\0001\\0)", 9, "(simple)",
+    { "()", "(\\0001\\0)", 9, "(simple)", "(\\t'\\t)",
       "( \\t\\n'\"\\033?""?/\\\\)", "(a\\:b)", "(a\\\\b)",
       "(a' b)", "(" LQ_ENC RQ_ENC ")", "(" LQ RQ ")" } },
 
   /* left_quote = ":" and right_quote = " " */
-  { { ": ", ":\\0001\\0 ", 9, ":simple ",
+  { { ": ", ":\\0001\\0 ", 9, ":simple ", ":\\t'\\t ",
       ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
       ":a'\\ b ", ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " },
-    { ": ", ":\\0001\\0 ", 9, ":simple ",
+    { ": ", ":\\0001\\0 ", 9, ":simple ", ":\\t'\\t ",
       ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a:b ", ":a\\\\b ",
       ":a'\\ b ", ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " },
-    { ": ", ":\\0001\\0 ", 9, ":simple ",
+    { ": ", ":\\0001\\0 ", 9, ":simple ", ":\\t'\\t ",
       ":\\ \\t\\n'\"\\033?""?/\\\\ ", ":a\\:b ", ":a\\\\b ",
       ":a'\\ b ", ":" LQ_ENC RQ_ENC " ", ":" LQ RQ " " } },
 
   /* left_quote = " " and right_quote = ":" */
-  { { " :", " \\0001\\0:", 9, " simple:",
+  { { " :", " \\0001\\0:", 9, " simple:", " \\t'\\t:",
       "  \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
       " a' b:", " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" },
-    { " :", " \\0001\\0:", 9, " simple:",
+    { " :", " \\0001\\0:", 9, " simple:", " \\t'\\t:",
       "  \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
       " a' b:", " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" },
-    { " :", " \\0001\\0:", 9, " simple:",
+    { " :", " \\0001\\0:", 9, " simple:", " \\t'\\t:",
       "  \\t\\n'\"\\033?""?/\\\\:", " a\\:b:", " a\\\\b:",
       " a' b:", " " LQ_ENC RQ_ENC ":", " " LQ RQ ":" } },
 
   /* left_quote = "# " and right_quote = "\n" */
-  { { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+  { { "# \n", "# \\0001\\0\n", 10, "# simple\n", "# \\t'\\t\n",
       "#  \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
       "# a' b\n", "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" },
-    { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+    { "# \n", "# \\0001\\0\n", 10, "# simple\n", "# \\t'\\t\n",
       "#  \\t\\n'\"\\033?""?/\\\\\n", "# a:b\n", "# a\\\\b\n",
       "# a' b\n", "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" },
-    { "# \n", "# \\0001\\0\n", 10, "# simple\n",
+    { "# \n", "# \\0001\\0\n", 10, "# simple\n", "# \\t'\\t\n",
       "#  \\t\\n'\"\\033?""?/\\\\\n", "# a\\:b\n", "# a\\\\b\n",
       "# a' b\n", "# " LQ_ENC RQ_ENC "\n", "# " LQ RQ "\n" } },
 
   /* left_quote = "\"'" and right_quote = "'\"" */
-  { { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+  { { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"", "\"'\\t'\\t'\"",
       "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
       "\"'a' b'\"", "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" },
-    { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+    { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"", "\"'\\t'\\t'\"",
       "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a:b'\"", "\"'a\\\\b'\"",
       "\"'a' b'\"", "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" },
-    { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"",
+    { "\"''\"", "\"'\\0001\\0'\"", 11, "\"'simple'\"", "\"'\\t'\\t'\"",
       "\"' \\t\\n\\'\"\\033?""?/\\\\'\"", "\"'a\\:b'\"", "\"'a\\\\b'\"",
       "\"'a' b'\"", "\"'" LQ_ENC RQ_ENC "'\"", "\"'" LQ RQ "'\"" } }
 };
diff --git a/tests/test-quotearg.c b/tests/test-quotearg.c
index 335bbd5aee..c9889496d9 100644
--- a/tests/test-quotearg.c
+++ b/tests/test-quotearg.c
@@ -34,24 +34,24 @@
 
 static struct result_groups locale_results[] = {
   /* locale_quoting_style */
-  { { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+  { { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ, LQ "\\t'\\t" RQ,
       LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
       LQ "a' b" RQ, LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ },
-    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ, LQ "\\t'\\t" RQ,
       LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
       LQ "a' b" RQ, LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ},
-    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ, LQ "\\t'\\t" RQ,
       LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ,
       LQ "a' b" RQ, LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ } },
 
   /* clocale_quoting_style */
-  { { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+  { { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ, LQ "\\t'\\t" RQ,
       LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
       LQ "a' b" RQ, LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ },
-    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ, LQ "\\t'\\t" RQ,
       LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a:b" RQ, LQ "a\\\\b" RQ,
       LQ "a' b" RQ, LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ },
-    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ,
+    { LQ RQ, LQ "\\0001\\0" RQ, 11, LQ "simple" RQ, LQ "\\t'\\t" RQ,
       LQ " \\t\\n'\"\\033?""?/\\\\" RQ, LQ "a\\:b" RQ, LQ "a\\\\b" RQ,
       LQ "a' b" RQ, LQ LQ RQ_ESC RQ, LQ LQ RQ_ESC RQ } }
 };
diff --git a/tests/test-quotearg.h b/tests/test-quotearg.h
index 47de7fee9f..b0e0296c79 100644
--- a/tests/test-quotearg.h
+++ b/tests/test-quotearg.h
@@ -21,6 +21,7 @@ struct result_strings {
   char const *str2; /* Translation of "\0""1\0".  */
   size_t len2; /* Length of str2.  */
   char const *str3; /* Translation of "simple".  */
+  char const *str4q; /* Translation of "\t'\t".  */
   char const *str4; /* Translation of " \t\n'\"\033?""?/\\".  */
   char const *str5; /* Translation of "a:b".  */
   char const *str6; /* Translation of "a\\b".  */
@@ -43,7 +44,7 @@ struct result_groups {
 # define RQ_ESC "\\\302\273"
 
 static struct result_strings inputs = {
-  "", "\0001\0", 3, "simple", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
+  "", "\0001\0", 3, "simple", "\t'\t", " \t\n'\"\033?""?/\\", "a:b", "a\\b",
   "a' b", LQ RQ, NULL
 };
 
@@ -74,6 +75,10 @@ compare_strings (char *(func) (char const *, size_t *),
   p = func (inputs.str3, &len);
   compare (results->str3, strlen (results->str3), p, len);
 
+  len = strlen (inputs.str4q);
+  p = func (inputs.str4q, &len);
+  compare (results->str4q, strlen (results->str4q), p, len);
+
   len = strlen (inputs.str4);
   p = func (inputs.str4, &len);
   compare (results->str4, strlen (results->str4), p, len);
-- 
2.44.0

Reply via email to