fix the bug which could have resulted in failing to read config file if a chunk boundary fell in a middle of a multibyte character (patch 1674488) [backport from HEAD]
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@44680 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -492,16 +492,16 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, const wxMBConv& conv)
|
|||||||
m_linesHead =
|
m_linesHead =
|
||||||
m_linesTail = NULL;
|
m_linesTail = NULL;
|
||||||
|
|
||||||
// translate everything to the current (platform-dependent) line
|
// read the entire stream contents in memory
|
||||||
// termination character
|
wxString str;
|
||||||
wxString strTrans;
|
|
||||||
{
|
{
|
||||||
wxString strTmp;
|
static const size_t chunkLen = 1024;
|
||||||
|
|
||||||
char buf[1024];
|
wxMemoryBuffer buf(chunkLen);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
inStream.Read(buf, WXSIZEOF(buf)-1); // leave room for the NULL
|
inStream.Read(buf.GetAppendBuf(chunkLen), chunkLen);
|
||||||
|
buf.UngetAppendBuf(inStream.LastRead());
|
||||||
|
|
||||||
const wxStreamError err = inStream.GetLastError();
|
const wxStreamError err = inStream.GetLastError();
|
||||||
|
|
||||||
@@ -510,19 +510,27 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, const wxMBConv& conv)
|
|||||||
wxLogError(_("Error reading config options."));
|
wxLogError(_("Error reading config options."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this is broken because if we have part of multibyte
|
|
||||||
// character in the buffer (and another part hasn't been
|
|
||||||
// read yet) we're going to lose data because of conversion
|
|
||||||
// errors
|
|
||||||
buf[inStream.LastRead()] = '\0';
|
|
||||||
strTmp += conv.cMB2WX(buf);
|
|
||||||
}
|
}
|
||||||
while ( !inStream.Eof() );
|
while ( !inStream.Eof() );
|
||||||
|
|
||||||
strTrans = wxTextBuffer::Translate(strTmp);
|
#if wxUSE_UNICODE
|
||||||
|
size_t len;
|
||||||
|
str = conv.cMB2WC((char *)buf.GetData(), buf.GetDataLen(), &len);
|
||||||
|
if ( !len && buf.GetDataLen() )
|
||||||
|
{
|
||||||
|
wxLogError(_("Failed to read config options."));
|
||||||
|
}
|
||||||
|
#else // !wxUSE_UNICODE
|
||||||
|
// no need for conversion
|
||||||
|
str.assign((char *)buf.GetData(), buf.GetDataLen());
|
||||||
|
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// translate everything to the current (platform-dependent) line
|
||||||
|
// termination character
|
||||||
|
str = wxTextBuffer::Translate(str);
|
||||||
|
|
||||||
wxMemoryText memText;
|
wxMemoryText memText;
|
||||||
|
|
||||||
// Now we can add the text to the memory text. To do this we extract line
|
// Now we can add the text to the memory text. To do this we extract line
|
||||||
@@ -534,21 +542,21 @@ wxFileConfig::wxFileConfig(wxInputStream &inStream, const wxMBConv& conv)
|
|||||||
const wxChar *pEOL = wxTextBuffer::GetEOL(wxTextBuffer::typeDefault);
|
const wxChar *pEOL = wxTextBuffer::GetEOL(wxTextBuffer::typeDefault);
|
||||||
const size_t EOLLen = wxStrlen(pEOL);
|
const size_t EOLLen = wxStrlen(pEOL);
|
||||||
|
|
||||||
int posLineStart = strTrans.Find(pEOL);
|
int posLineStart = str.Find(pEOL);
|
||||||
while ( posLineStart != -1 )
|
while ( posLineStart != -1 )
|
||||||
{
|
{
|
||||||
wxString line(strTrans.Left(posLineStart));
|
wxString line(str.Left(posLineStart));
|
||||||
|
|
||||||
memText.AddLine(line);
|
memText.AddLine(line);
|
||||||
|
|
||||||
strTrans = strTrans.Mid(posLineStart + EOLLen);
|
str = str.Mid(posLineStart + EOLLen);
|
||||||
|
|
||||||
posLineStart = strTrans.Find(pEOL);
|
posLineStart = str.Find(pEOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// also add whatever we have left in the translated string.
|
// also add whatever we have left in the translated string.
|
||||||
if ( !strTrans.empty() )
|
if ( !str.empty() )
|
||||||
memText.AddLine(strTrans);
|
memText.AddLine(str);
|
||||||
|
|
||||||
// Finally we can parse it all.
|
// Finally we can parse it all.
|
||||||
Parse(memText, true /* local */);
|
Parse(memText, true /* local */);
|
||||||
|
Reference in New Issue
Block a user