log4cxx中文输出错误补丁


已提交Bug:https://issues.apache.org/jira/browse/LOGCXX-399

log4cxx_0.10.0及主干代码,Windows下输出中文,发现有多余输出。

void main()
{
    setlocale(LC_ALL, "");
    LOG4CXX_INFO(pLog, "一二");  // log 2 chinese characters.
}



输出为:一二二。

错误在 MbstowcsCharsetDecoder::decode().

size_t converted = mbsrtowcs(...
   if (converted == (size_t) -1) {
       ...
   } else {
       stat = append(out, buf);
       in.position(in.position() + converted);  // ERROR!
   }



mbsrtowcs()返回的是汉字的字数,而输入缓冲区in的position是按字节计数的,
对于汉字,position应该增加2*converted,而不是converted.
因为position少增加了一半,所以后半部分字符串会重复解码。

可如下更改:

if (converted == (size_t) -1) {
       ...
   } else {
       stat = append(out, buf);
       // in.position(in.position() + converted);  // ERROR!
       if (src)
           in.position(src - in.data());
       else  // mbsrtowcs() set src to NULL.
           in.position(in.position() + strnlen(in.current(), in.remaining()));
   }


此处的in是个二进制块,其中可能会有0,而mbsrtowcs()的输入应该是0结尾的字符串。
碰到0时,mbsrtowcs()认为已经成功转换到串尾,并将src重设为NULL。
代码中已经有对0的处理。

有可能mbsrtowcs()会越过输入缓冲区的尾部一直读取,最多为256字节,仍有可能出现垃圾字符。
但是现在的std::string实现有0结尾,所有才没有出错。若要更正这个错误,就需要在输入缓冲区尾部添0。