[PATCH 1/1] strings patch for bug 33360

Andrew C Aitchison werdna@aitchison.me.uk
Thu Sep 4 10:31:24 GMT 2025


On Wed, 3 Sep 2025, Alice Carlotti wrote:

> On Wed, Sep 03, 2025 at 03:08:33PM +0100, Andrew C Aitchison wrote:
>> ---
>>  binutils/strings.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/binutils/strings.c b/binutils/strings.c
>> index f5c022b50a1..38da6381edf 100644
>> --- a/binutils/strings.c
>> +++ b/binutils/strings.c
>> @@ -757,8 +757,8 @@ display_utf8_char (const unsigned char * buffer)
>>
>>  	case 4:
>>  	  printf ("\\u%02x%02x%02x",
>
> Should 5 digit outputs be allowed?

We don't have 1 or 3 digit outputs.

Some source suggest that the $'\uxxxx' and $'\Uxxxxxxxx' notations
must be 4 and 8 digits respectively. Does that mean we should
replace the 6digits with 8 ?

I note that
   echo $'\U10D703' | strings -n1 -Uh
and
  echo $'\u01d703' | strings -n1 -Uh
both give
   \u01d703
but the "03" is only highlighted with the \U version.
I would like to make case 4: produce
   \U01d703
but that would break existing behaviour.
 	What do people think ?

> Your updated bit arithmetic looks correct to me, but I do wonder whether we
> should simplify things by building the whole value into a 32 bit integer and
> printing that.  Is there any reason we can't do that?

[ This is not a formal patch,
   and is against my previous patch, which is now live. ]
        switch (utf8_len)
         {
         case 2:
-         printf ("\\u%02x%02x",
-                 ((buffer[0] & 0x1c) >> 2),
-                 ((buffer[0] & 0x03) << 6) | (buffer[1] & 0x3f));
+         printf ("\\u%04x",
+                 ((buffer[0] & 0x1f) << 6) |
+                  (buffer[1] & 0x3f) );
           break;

         case 3:
-         printf ("\\u%02x%02x",
-                 ((buffer[0] & 0x0f) << 4) | ((buffer[1] & 0x3c) >> 2),
-                 ((buffer[1] & 0x03) << 6) | ((buffer[2] & 0x3f)));
+         printf ("\\u%04x",
+                 ((buffer[0] & 0x0f) << 12) |
+                 ((buffer[1] & 0x3f) << 6) |
+                 ((buffer[2] & 0x3f)) );
           break;

         case 4:
-         printf ("\\u%02x%02x%02x",
-                 ((buffer[0] & 0x07) << 2) | ((buffer[1] & 0x30) >> 4),
-                 ((buffer[1] & 0x0f) << 4) | ((buffer[2] & 0x3c) >> 2),
-                 ((buffer[2] & 0x03) << 6) | ((buffer[3] & 0x3f)));
+         printf ("\\u%06x",
+                 ((buffer[0] & 0x07) << 18) |
+                 ((buffer[1] & 0x3f) << 12) |
+                 ((buffer[2] & 0x3f) << 6) |
+                 ((buffer[3] & 0x3f)) );
           break;
         default:

The 32bit version does read better than the Nx8bit version.
I like your suggestion.

-- 
Andrew C. Aitchison                      Kendal, UK
                    andrew@aitchison.me.uk


More information about the Binutils mailing list