Subject: bug#13399: 24.3.50; Word-wrap can't wrap at zero-width space U-200B

From: Eli Zaretskii <[email-masked]>
Date: Sun, 03 Feb 2013 21:45:29 +0200

> Date: Sun, 03 Feb 2013 19:57:31 +0100
> From: martin rudalics <[email-masked]>
> CC: [email-masked]
> 
> I now rewrote IT_DISPLAYING_WHITESPACE as
> 
> #define IT_DISPLAYING_WHITESPACE(it)					\
>    ((it->what == IT_CHARACTER						\
>      && !NILP (CHAR_TABLE_REF (Vword_wrap_chars, it->c)))		\
>     || ((STRINGP (it->string)						\
> 	&& !NILP (CHAR_TABLE_REF					\
> 		   (Vword_wrap_chars,					\
> 		      SREF (it->string, IT_STRING_BYTEPOS (*it)))))	\
>         || (it->s && !NILP (CHAR_TABLE_REF				\
> 			    (Vword_wrap_chars,				\
> 			       it->s[IT_BYTEPOS (*it)])))		\
>         || (IT_BYTEPOS (*it) < ZV_BYTE					\
> 	   && !NILP (CHAR_TABLE_REF					\
> 		      (Vword_wrap_chars,				\
> 			 (*BYTE_POS_ADDR (IT_BYTEPOS (*it))))))))	\
> 
> 
> and have a character table called `word-wrap-chars' such that
> (aref word-wrap-chars ?​) returns t, but it doesn't wrap at a
> U-200B character.  Is there some additional wrinkle like some
> hardcoded space/tab in the word-wrap code I have to observe?
> Or is my code wrong?

Does CHAR_TABLE_REF return the right value?

Also, the code is wrong here:

   SREF (it->string, IT_STRING_BYTEPOS (*it))

and here:

   it->s[IT_BYTEPOS (*it)]

and here:

   *BYTE_POS_ADDR (IT_BYTEPOS (*it))

in that that it assumes the character is always one byte, which is
clearly wrong with non-ASCII characters.  You should instead use
FETCH_CHAR and STRING_CHAR.