public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
From: Tom Tromey <tromey@sourceware.org>
To: gdb-cvs@sourceware.org
Subject: [binutils-gdb] Fix a latent bug in print_wchar
Date: Mon, 10 Oct 2022 17:38:54 +0000 (GMT)	[thread overview]
Message-ID: <20221010173854.708CD3858297@sourceware.org> (raw)

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3041b9313e360af215e235e4d07f9557a22ffd13

commit 3041b9313e360af215e235e4d07f9557a22ffd13
Author: Tom Tromey <tom@tromey.com>
Date:   Sat Feb 12 18:41:34 2022 -0700

    Fix a latent bug in print_wchar
    
    print_wchar keeps track of when escape sequences are emitted, to force
    an escape sequence if needed by a subsequent character.  For example
    for the string concatenation "\0" "1", gdb will print "\000\061" --
    because printing "\0001" might be confusing.
    
    However, this code has two errors.  First, this logic is not needed
    for octal escapes, because there is a length limit of 3 for octal
    escapes, and gdb always prints these with "%.3o".  Second, though,
    this *is* needed for hex escapes, because those do not have a length
    limit.
    
    This patch fixes these problems and adds the appropriate tests.

Diff:
---
 gdb/gdb_wchar.h                    |  4 ++--
 gdb/testsuite/gdb.base/charset.exp |  8 ++++++++
 gdb/valprint.c                     | 22 ++++++++++++++--------
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/gdb/gdb_wchar.h b/gdb/gdb_wchar.h
index ba5baf3a2a0..8c6e4fc9fd6 100644
--- a/gdb/gdb_wchar.h
+++ b/gdb/gdb_wchar.h
@@ -66,7 +66,7 @@ typedef wint_t gdb_wint_t;
 
 #define gdb_wcslen wcslen
 #define gdb_iswprint iswprint
-#define gdb_iswdigit iswdigit
+#define gdb_iswxdigit iswxdigit
 #define gdb_btowc btowc
 #define gdb_WEOF WEOF
 
@@ -103,7 +103,7 @@ typedef int gdb_wint_t;
 
 #define gdb_wcslen strlen
 #define gdb_iswprint isprint
-#define gdb_iswdigit isdigit
+#define gdb_iswxdigit isxdigit
 #define gdb_btowc /* empty */
 #define gdb_WEOF EOF
 
diff --git a/gdb/testsuite/gdb.base/charset.exp b/gdb/testsuite/gdb.base/charset.exp
index 5df2ec1a8de..359968df696 100644
--- a/gdb/testsuite/gdb.base/charset.exp
+++ b/gdb/testsuite/gdb.base/charset.exp
@@ -503,6 +503,11 @@ gdb_test "print '\\9'" " = \[0-9\]+ '9'"
 # An octal escape can only be 3 digits.
 gdb_test "print \"\\1011\"" " = \"A1\""
 
+# The final digit does not need to be escaped here.
+foreach val {0 1 2 3 4 5 6 7 8 9 a b c d e f} {
+    gdb_test "print \"\\0\" \"${val}\"" " = \"\\\\000${val}\""
+}
+
 # Tests for wide- or unicode- strings.  L is the prefix letter to use,
 # either "L" (for wide strings), "u" (for UTF-16), or "U" (for UTF-32).
 # NAME is used in the test names and should be related to the prefix
@@ -519,6 +524,9 @@ proc test_wide_or_unicode {L name} {
     gdb_test "print $L\"\" \"abcdef\" \"g\"" \
       "$L\"abcdefg\"" \
       "concatenate three strings with empty $name string"
+    gdb_test "print $L\"\\xffef\" $L\"f\"" \
+	"$L\"\\\\xffef\\\\146\"" \
+	"test multi-char escape sequence case for $name"
 
     gdb_test "print $L'a'" "= \[0-9\]+ $L'a'" \
       "basic $name character"
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 5a2f4dfc62a..f079f31fa7b 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -2108,9 +2108,7 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
 	break;
       default:
 	{
-	  if (gdb_iswprint (w) && (!need_escape || (!gdb_iswdigit (w)
-						    && w != LCST ('8')
-						    && w != LCST ('9'))))
+	  if (gdb_iswprint (w) && !(need_escape && gdb_iswxdigit (w)))
 	    {
 	      gdb_wchar_t wchar = w;
 
@@ -2132,10 +2130,19 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
 		  /* If the value fits in 3 octal digits, print it that
 		     way.  Otherwise, print it as a hex escape.  */
 		  if (value <= 0777)
-		    xsnprintf (octal, sizeof (octal), "\\%.3o",
-			       (int) (value & 0777));
+		    {
+		      xsnprintf (octal, sizeof (octal), "\\%.3o",
+				 (int) (value & 0777));
+		      *need_escapep = false;
+		    }
 		  else
-		    xsnprintf (octal, sizeof (octal), "\\x%lx", (long) value);
+		    {
+		      xsnprintf (octal, sizeof (octal), "\\x%lx", (long) value);
+		      /* A hex escape might require the next character
+			 to be escaped, because, unlike with octal,
+			 hex escapes have no length limit.  */
+		      *need_escapep = true;
+		    }
 		  append_string_as_wide (octal, output);
 		}
 	      /* If we somehow have extra bytes, print them now.  */
@@ -2144,11 +2151,10 @@ print_wchar (gdb_wint_t w, const gdb_byte *orig,
 		  char octal[5];
 
 		  xsnprintf (octal, sizeof (octal), "\\%.3o", orig[i] & 0xff);
+		  *need_escapep = false;
 		  append_string_as_wide (octal, output);
 		  ++i;
 		}
-
-	      *need_escapep = true;
 	    }
 	  break;
 	}

                 reply	other threads:[~2022-10-10 17:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221010173854.708CD3858297@sourceware.org \
    --to=tromey@sourceware.org \
    --cc=gdb-cvs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).