Subject: bug#29189: 25.3; Dired does not work with binary filenames

From: Allen Li <[email-masked]>
Date: Fri, 1 Dec 2017 21:21:14 -0800

On Mon, Nov 20, 2017 at 10:15 AM, Eli Zaretskii <[email-masked]> wrote:
> Right you are, thanks.  Updated patch below.
>
> diff --git a/src/coding.c b/src/coding.c
> index d790ad0..ac55f87 100644
> --- a/src/coding.c
> +++ b/src/coding.c
> @@ -7423,10 +7423,23 @@ decode_coding (struct coding_system *coding)
>
>           while (nbytes-- > 0)
>             {
> -             int c = *src++;
> +             int c;
>
> -             if (c & 0x80)
> -               c = BYTE8_TO_CHAR (c);
> +             /* Copy raw bytes in their 2-byte forms from multibyte
> +                text as single characters.  */
> +             if (coding->src_multibyte
> +                 && CHAR_BYTE8_HEAD_P (*src) && nbytes > 0)
> +               {
> +                 c = STRING_CHAR_ADVANCE (src);
> +                 nbytes--;
> +               }
> +             else
> +               {
> +                 c = *src++;
> +
> +                 if (c & 0x80)
> +                   c = BYTE8_TO_CHAR (c);
> +               }
>               coding->charbuf[coding->charbuf_used++] = c;
>             }
>           produce_chars (coding, Qnil, 1);

I applied this patch to master (0b6f4f2c60) and it fixes the bug and
doesn't crash Emacs immediately.  The code also looks right, but I am
not familiar with Emacs's C code.  A few questions.

Why do we have to handle multibyte strings in this function
decode_coding?  (I found the answer in the docs)

Can you briefly explain how Emacs internally stores unibyte and
multibyte strings?  (I found the answer in character.h)

After doing the above research, I can more confidently say this is
right, but having an expert opinion would be nice.