From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2126) id 708CD3858297; Mon, 10 Oct 2022 17:38:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 708CD3858297 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1665423534; bh=ffmgoawYxA0BFcNLHFnZeETjg1lQJpNnrYF36IL7Z3s=; h=From:To:Subject:Date:From; b=G+SJNy2zsYcSlwEf+3I2Dj9nnVq4sUEvzPfipZaUxonGNqmG4OH4sAbed81asa5Bx 6liCi+qZYoYLrCCVrcz6Xi25L25+nFYjMUGRv949m6R4kshCmuj/zoskzUG8X0bcy2 tQ8r4PJukWJCn/EMJ4+P7nLJDl3Sgf7GEzAKZ+uI= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tom Tromey To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Fix a latent bug in print_wchar X-Act-Checkin: binutils-gdb X-Git-Author: Tom Tromey X-Git-Refname: refs/heads/master X-Git-Oldrev: 05328f9105ed738cc4fe96429abd33466e891699 X-Git-Newrev: 3041b9313e360af215e235e4d07f9557a22ffd13 Message-Id: <20221010173854.708CD3858297@sourceware.org> Date: Mon, 10 Oct 2022 17:38:54 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D3041b9313e36= 0af215e235e4d07f9557a22ffd13 commit 3041b9313e360af215e235e4d07f9557a22ffd13 Author: Tom Tromey Date: Sat Feb 12 18:41:34 2022 -0700 Fix a latent bug in print_wchar =20 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. =20 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. =20 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; =20 #define gdb_wcslen wcslen #define gdb_iswprint iswprint -#define gdb_iswdigit iswdigit +#define gdb_iswxdigit iswxdigit #define gdb_btowc btowc #define gdb_WEOF WEOF =20 @@ -103,7 +103,7 @@ typedef int gdb_wint_t; =20 #define gdb_wcslen strlen #define gdb_iswprint isprint -#define gdb_iswdigit isdigit +#define gdb_iswxdigit isxdigit #define gdb_btowc /* empty */ #define gdb_WEOF EOF =20 diff --git a/gdb/testsuite/gdb.base/charset.exp b/gdb/testsuite/gdb.base/ch= arset.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'" " =3D \[0-9\]+ '9'" # An octal escape can only be 3 digits. gdb_test "print \"\\1011\"" " =3D \"A1\"" =20 +# 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}\"" " =3D \"\\\\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" =20 gdb_test "print $L'a'" "=3D \[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 !=3D LCST ('8') - && w !=3D LCST ('9')))) + if (gdb_iswprint (w) && !(need_escape && gdb_iswxdigit (w))) { gdb_wchar_t wchar =3D w; =20 @@ -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 <=3D 0777) - xsnprintf (octal, sizeof (octal), "\\%.3o", - (int) (value & 0777)); + { + xsnprintf (octal, sizeof (octal), "\\%.3o", + (int) (value & 0777)); + *need_escapep =3D 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 =3D 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]; =20 xsnprintf (octal, sizeof (octal), "\\%.3o", orig[i] & 0xff); + *need_escapep =3D false; append_string_as_wide (octal, output); ++i; } - - *need_escapep =3D true; } break; }