log4cxx中文輸出錯誤補丁
(金慶的專欄)
已提交Bug:https://issues.apache.org/jira/browse/LOGCXX-399
log4cxx_0.10.0及主干代碼,Windows下輸出中文,發(fā)現(xiàn)有多余輸出。
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()返回的是漢字的字數(shù),而輸入緩沖區(qū)in的position是按字節(jié)計數(shù)的,
對于漢字,position應(yīng)該增加2*converted,而不是converted.
因為position少增加了一半,所以后半部分字符串會重復(fù)解碼。
可如下更改:
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()的輸入應(yīng)該是0結(jié)尾的字符串。
碰到0時,mbsrtowcs()認為已經(jīng)成功轉(zhuǎn)換到串尾,并將src重設(shè)為NULL。
代碼中已經(jīng)有對0的處理。
有可能mbsrtowcs()會越過輸入緩沖區(qū)的尾部一直讀取,最多為256字節(jié),仍有可能出現(xiàn)垃圾字符。
但是現(xiàn)在的std::string實現(xiàn)有0結(jié)尾,所有才沒有出錯。若要更正這個錯誤,就需要在輸入緩沖區(qū)尾部添0。
(金慶的專欄)
已提交Bug:https://issues.apache.org/jira/browse/LOGCXX-399
log4cxx_0.10.0及主干代碼,Windows下輸出中文,發(fā)現(xiàn)有多余輸出。
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()返回的是漢字的字數(shù),而輸入緩沖區(qū)in的position是按字節(jié)計數(shù)的,
對于漢字,position應(yīng)該增加2*converted,而不是converted.
因為position少增加了一半,所以后半部分字符串會重復(fù)解碼。
可如下更改:
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()的輸入應(yīng)該是0結(jié)尾的字符串。
碰到0時,mbsrtowcs()認為已經(jīng)成功轉(zhuǎn)換到串尾,并將src重設(shè)為NULL。
代碼中已經(jīng)有對0的處理。
有可能mbsrtowcs()會越過輸入緩沖區(qū)的尾部一直讀取,最多為256字節(jié),仍有可能出現(xiàn)垃圾字符。
但是現(xiàn)在的std::string實現(xiàn)有0結(jié)尾,所有才沒有出錯。若要更正這個錯誤,就需要在輸入緩沖區(qū)尾部添0。