なかだです。

At Mon, 18 Mar 2002 18:25:41 +0900,
Akinori MUSHA wrote:
> > FreeBSDのiconv 2.0で、'iso-8859-1'から'iso-8859-1'へのiconv()で1024バ
> > イトまでしか変換されないという報告があるんですが、これはFreeBSDのほう
> > ではなにか報告されてないでしょうか。
> 
>  調査していただいてありがとうございます。メンテナが忙しいらしく、
> いくつか見つかっているバグが放置されている状態です。ご指摘の件に
> ついては報告しておきました。

どうも。

>  そんな有様なので、 FreeBSD ports では近々 GNU libiconv を標準と
> して使うように修正することになっています。どっちの実装もバグが
> あるなら、よりメジャーでメンテナンスされている方がましと。

GNU libiconvはたぶんそのうち、わたなべさんとかからなんか出てく
るでしょう。やっぱりiconvって使われてないみたい。

>  LGPL なのがいまいちですが、 BSDL な iconv は gettext とともに
> いずれ CITRUS が実装するのかな、とか。できれば、せっかくすでに
> ある上記実装をちゃんと直したいんですが。

見てみたら、すべてUnicode経由なんですね。

>  添付のような平凡な修正でいいでしょうか?
(snip)
> @@ -163,8 +163,10 @@
>  		*inbytesleft -= len;
>  		*outbuf += len;
>  		*outbytesleft -= len;
> +		return 0;
>  	}
> -	return 0;
> +
> +	return (size_t)(-1);
>  }
>  
>  iconv_converter *

これだと常に失敗してしまうことになるのでまずいでしょう。あと
errnoも設定しないと。全然確認してないですが、私のやってみた修正
はこんなのです。unicode_conv()のほうはまったく同じなので省略。

# bcopyはerrnoを変更しないことが保証されてる?

diff -rup iconv-2.0.orig/lib/converter.c iconv-2.0/lib/converter.c
--- iconv-2.0.orig/lib/converter.c	Sun Nov 26 22:10:22 2000
+++ iconv-2.0/lib/converter.c	Mon Mar 18 15:41:56 2002
@@ -156,13 +156,21 @@ null_conv(void *data, const unsigned cha
 {
 	if (inbuf && *inbuf && inbytesleft && *inbytesleft > 0 && outbuf
 			&& *outbuf && outbytesleft && *outbytesleft > 0) {
-		size_t len = *inbytesleft < *outbytesleft ? *inbytesleft
-							  : *outbytesleft;
+		size_t result, len;
+		if (*inbytesleft < *outbytesleft) {
+			result = 0;
+			len = *inbytesleft;
+		} else {
+			result = (size_t)-1;
+			len = *outbytesleft;
+		}
 		bcopy(*inbuf, *outbuf, len);
 		*inbuf += len;
 		*inbytesleft -= len;
 		*outbuf += len;
 		*outbytesleft -= len;
+		if (result) errno = E2BIG;
+		return result;
 	}
 	return 0;
 }

-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦