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