On 8/13/06, Bram Moolenaar <[EMAIL PROTECTED]> wrote:

[removed the Vim maillist, this is development only]

Edward L. Fox wrote:

> On 8/12/06, Bram Moolenaar <[EMAIL PROTECTED]> wrote:
> > [...]
> > You may have uncovered a bug that went unnoticed so far.  Please try to
> > discover what causes this problem.  I can't guess why the last character
> > is messed up, looks strange.
>
> I think I solved the problem! That was caused by iconv.
>
>        size_t iconv(iconv_t cd,
>                      char **inbuf, size_t *inbytesleft,
>                      char **outbuf, size_t *outbytesleft);
>
> The parameter "inbytesleft" and "outbytesleft" should all include the
> trailing '\0' byte. In the previous version of gvim, we passed the
> parameter as the length of the string, excluding the trailing '\0'. So
> it is 1 byte less than the correct value.

This is not quite so.  iconv() does not require the terminating NUL (it
can also be used to convert part of a string).  If it does require the
NUL then iconv() is broken.  That's unlikely though.

I wrote a short piece of testing code to test iconv with Chinese
characters. The fact is, if the last character is a Chinese character,
it is always malformed after converting. So I think it should be
necessary to pass the length including the trailing '\0' to iconv.

--------------------8<--------------------
#include <iconv.h>

int main(void)
{
   char inbuffer[256];
   char outbuffer[256];
   int fd;

   fd = iconv_open("cp936", "euc-cn");

   for (;;)
   {
       int inlength, outlength;
       char *inptr, *outptr;
       gets(inbuffer);
       inlength = strlen(inbuffer);
       outlength = 256;
       if (inlength == 0)
           break;
       inptr = inbuffer;
       outptr = outbuffer;
       iconv(fd, &inptr, &inlength, &outptr, &outlength);
       printf("%s\n", outbuffer);
   }

   iconv_close(fd);

   return 0;
}
--------------------8<--------------------

Your change suggests that the length that is passed should be one more.
Thus only one byte of the last double-byte character is currently
converted.  I can't quickly figure out where the wrong length is
computed or passed.  You probably already know the call stack, please
have a look at where the length comes from.  It's probably an off-by-one
error somewhere.

I traced the code again and again but nothing special happened. You
called string_convert and pass 0 as the length of the string, so in
string_convert_ext you calculates the length of the string with
STRLEN, then call iconv_string, last iconv. There is nothing wrong
with the length anywhere. So... Maybe it is still iconv's fault.

[...]


Regards,

Edward L. Fox

Reply via email to