Re: tin problem: Error: From: line missing.
Urs Janßen <[email protected]> Fri, 4 Jan 2013 17:34:20 +0100
| Newsgroups | gmane.network.tin.devel |
|---|---|
| Message-ID | <[email protected]> |
--M9NhX3UHpAaciwkO Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Jan 04, 2013 at 06:37:53PM +0700, Victor Sudakov wrote: > > > It may be a FreeBSD-specific bug > > as it seems to be locale related it might be a somewhat broken isacii() or > > the like. > It also seems to work with LANG=ru_RU.UTF-8. Only KOI8-R is somehow > problematic. Looks like I traced it down: if the locale charset is the same as the network charset (in your case both were KOI8-R) tin tries to convert the string in the local charset to the network charset (waste of cpu cycles, but sould work!). But FreeBSDs iconv(3) seems to have a problem with that, the mapage states: [...] | After calling iconv(), the values pointed to by src, | srcleft, dst, and dstleft are updated as follows: [...] | *dst Pointer to the byte just after the last character stored. [...] but this is not the case, right befor the conversion (misc.c:buffer_to_network()): (gdb) print inbuf $2 = 0x80163d200 "From: Urs Janssen <[email protected]>" (gdb) print &outbuf $3 = (char **) 0x7fffffffa5e0 (gdb) print outbuf $4 = 0x80144d6c0 "G" right after the conversin: (gdb) print *&outbuf $11 = 0x80144d6c0 "From: Urs Janssen <[email protected]>l" (gdb) print **&outbuf $17 = 70 'F' but it should point right behind the '>' to the tailing gargabe ('l'). (gdb) next 2560 **&outbuf = '\0'; now the entire converted string get's erased instead of being propperly terminated at the end. -> From (and everything else) is empty. attached is a patch which prevents tin from trying to convert local to network charset if both are the same. this should solve your problem (but the real bug seems to be in FreeBSDs iconv(3)). The binarie /home/urs/tin should behave like the one in /usr/local/bin/ and can be copied to any location. the already patched source is in /home/urs/tin-2.1.3.tar.gz if you like to recompile on your own. Thanks for the access to the machine, urs -- "Only whimps use tape backup: _real_ men just upload their important stuff on ftp, and let the rest of the world mirror it ;)" - Linus --M9NhX3UHpAaciwkO Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="charset.diff" diff -Nurp --exclude='.bzr*' tin-2.1.2/src/misc.c tin-2.1.3/src/misc.c --- tin-2.1.2/src/misc.c 2012-12-24 11:22:01.000000000 +0100 +++ tin-2.1.3/src/misc.c 2013-01-04 16:26:35.923587224 +0100 @@ -2521,46 +2521,48 @@ buffer_to_network( size_t inbytesleft, outbytesleft; t_bool conv_success = TRUE; - if ((cd = iconv_open(txt_mime_charsets[mmnwcharset], tinrc.mm_local_charset)) != (iconv_t) (-1)) { - inbytesleft = strlen(line); - inbuf = (char *) line; - outbytesleft = 1 + inbytesleft * 4; - osize = outbytesleft; - obuf = my_malloc(osize + 1); - outbuf = (char *) obuf; - - do { - errno = 0; - result = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); - if (result == (size_t) (-1)) { - switch (errno) { - case EILSEQ: - /* TODO: only one '?' for each multibyte sequence ? */ - **&outbuf = '?'; - outbuf++; - inbuf++; - inbytesleft--; - conv_success = FALSE; - break; - - case E2BIG: - obuf = my_realloc(obuf, osize * 2); - outbuf = (char *) (obuf + osize - outbytesleft); - outbytesleft += osize; - osize <<= 1; /* double size */ - break; - - default: /* EINVAL */ - inbytesleft = 0; - conv_success = FALSE; + if (strcasecmp(txt_mime_charsets[mmnwcharset], tinrc.mm_local_charset)) { + if ((cd = iconv_open(txt_mime_charsets[mmnwcharset], tinrc.mm_local_charset)) != (iconv_t) (-1)) { + inbytesleft = strlen(line); + inbuf = (char *) line; + outbytesleft = 1 + inbytesleft * 4; + osize = outbytesleft; + obuf = my_malloc(osize + 1); + outbuf = (char *) obuf; + + do { + errno = 0; + result = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + if (result == (size_t) (-1)) { + switch (errno) { + case EILSEQ: + /* TODO: only one '?' for each multibyte sequence ? */ + **&outbuf = '?'; + outbuf++; + inbuf++; + inbytesleft--; + conv_success = FALSE; + break; + + case E2BIG: + obuf = my_realloc(obuf, osize * 2); + outbuf = (char *) (obuf + osize - outbytesleft); + outbytesleft += osize; + osize <<= 1; /* double size */ + break; + + default: /* EINVAL */ + inbytesleft = 0; + conv_success = FALSE; + } } - } - } while (inbytesleft > 0); + } while (inbytesleft > 0); - **&outbuf = '\0'; - strcpy(line, obuf); /* FIXME: here we assume that line is big enough to hold obuf */ - free(obuf); - iconv_close(cd); + **&outbuf = '\0'; + strcpy(line, obuf); /* FIXME: here we assume that line is big enough to hold obuf */ + free(obuf); + iconv_close(cd); + } } return conv_success; } diff -Nurp --exclude='.bzr*' tin-2.1.2/src/post.c tin-2.1.3/src/post.c --- tin-2.1.2/src/post.c 2012-12-24 11:22:02.000000000 +0100 +++ tin-2.1.3/src/post.c 2013-01-04 16:29:26.658530322 +0100 @@ -876,7 +876,7 @@ check_article_to_be_posted( } #ifdef CHARSET_CONVERSION /* are all characters in article contained in network_charset? */ - if (strcmp(tinrc.mm_local_charset, txt_mime_charsets[mmnwcharset]) && !charset_conversion_fails) { /* local_charset != network_charset */ + if (strcasecmp(tinrc.mm_local_charset, txt_mime_charsets[mmnwcharset]) && !charset_conversion_fails) { /* local_charset != network_charset */ cp = my_malloc(strlen(line) * 4 + 1); strcpy(cp, line); charset_conversion_fails = !buffer_to_network(cp, mmnwcharset); @@ -1243,7 +1243,7 @@ check_article_to_be_posted( #ifdef CHARSET_CONVERSION /* are all characters in article contained in network_charset? */ - if (strcmp(tinrc.mm_local_charset, txt_mime_charsets[mmnwcharset]) && !charset_conversion_fails) { /* local_charset != network_charset */ + if (strcasecmp(tinrc.mm_local_charset, txt_mime_charsets[mmnwcharset]) && !charset_conversion_fails) { /* local_charset != network_charset */ cp = my_malloc(strlen(line) * 4 + 1); strcpy(cp, line); charset_conversion_fails = !buffer_to_network(cp, mmnwcharset); --M9NhX3UHpAaciwkO--