This is an automated email from the ASF dual-hosted git repository. damjan pushed a commit to branch AOO41X in repository https://gitbox.apache.org/repos/asf/openoffice.git
commit 6c882b5c20df170aa3c6a6f38eba607112d35db7 Author: damjan <damjan@13f79535-47bb-0310-9956-ffa450edef68> AuthorDate: Sun Apr 3 15:02:59 2016 +0000 #i122754# Base does not properly parse CSV files as per RFC-4180 (while Calc does) The flat file driver, in file main/connectivity/source/drivers/flat/ETable.cxx, method OFlatTable::fillColumns(), which reads lines to initialize columns, assumes fields in the header and the first few lines never continue onto the next line(s). This causes truncation of columns when they do. Read all lines using the readLine() method instead of SvStream::ReadByteStringLine(), which takes overflow onto next lines into account. Also implement a new version of readLine() which allows reading into an arbitrary string, as opposed to m_aCurrentLine only. Patch by: me git-svn-id: https://svn.apache.org/repos/asf/openoffice/trunk@1737591 13f79535-47bb-0310-9956-ffa450edef68 (cherry picked from commit 6b41ff7abde450fb0368489eb47c02e30b544097) --- main/connectivity/source/drivers/flat/ETable.cxx | 30 ++++++++++++++---------- main/connectivity/source/inc/flat/ETable.hxx | 1 + 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/main/connectivity/source/drivers/flat/ETable.cxx b/main/connectivity/source/drivers/flat/ETable.cxx index 478e86efae..396d9df6d7 100644 --- a/main/connectivity/source/drivers/flat/ETable.cxx +++ b/main/connectivity/source/drivers/flat/ETable.cxx @@ -72,26 +72,26 @@ void OFlatTable::fillColumns(const ::com::sun::star::lang::Locale& _aLocale) QuotedTokenizedString aHeaderLine; OFlatConnection* pConnection = (OFlatConnection*)m_pConnection; - const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding(); const sal_Bool bHasHeaderLine = pConnection->isHeaderLine(); + sal_Int32 nCurPos; if ( bHasHeaderLine ) { while(bRead && !aHeaderLine.Len()) { - bRead = m_pFileStream->ReadByteStringLine(aHeaderLine,nEncoding); + bRead = readLine(aHeaderLine, nCurPos); } m_nStartRowFilePos = m_pFileStream->Tell(); } // read first row QuotedTokenizedString aFirstLine; - bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding); + bRead = readLine(aFirstLine, nCurPos); if ( !bHasHeaderLine || !aHeaderLine.Len()) { while(bRead && !aFirstLine.Len()) { - bRead = m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding); + bRead = readLine(aFirstLine, nCurPos); } // use first row as headerline because we need the number of columns aHeaderLine = aFirstLine; @@ -155,7 +155,7 @@ void OFlatTable::fillColumns(const ::com::sun::star::lang::Locale& _aLocale) } ++nRowCount; } - while(nRowCount < nMaxRowsToScan && m_pFileStream->ReadByteStringLine(aFirstLine,nEncoding) && !m_pFileStream->IsEof()); + while(nRowCount < nMaxRowsToScan && readLine(aFirstLine,nCurPos) && !m_pFileStream->IsEof()); for (xub_StrLen i = 0; i < nFieldCount; i++) { @@ -894,22 +894,27 @@ sal_Bool OFlatTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int } // ----------------------------------------------------------------------------- sal_Bool OFlatTable::readLine(sal_Int32& _rnCurrentPos) +{ + return readLine(m_aCurrentLine, _rnCurrentPos); +} +// ----------------------------------------------------------------------------- +sal_Bool OFlatTable::readLine(QuotedTokenizedString& line, sal_Int32& _rnCurrentPos) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "flat", "ocke.jans...@sun.com", "OFlatTable::readLine" ); const rtl_TextEncoding nEncoding = m_pConnection->getTextEncoding(); - m_pFileStream->ReadByteStringLine(m_aCurrentLine,nEncoding); - if (m_pFileStream->IsEof()) - return sal_False; + m_pFileStream->ReadByteStringLine(line,nEncoding); + if (m_pFileStream->IsEof()) + return sal_False; - QuotedTokenizedString sLine = m_aCurrentLine; // check if the string continues on next line + QuotedTokenizedString sLine = line; // check if the string continues on next line while( (sLine.GetString().GetTokenCount(m_cStringDelimiter) % 2) != 1 ) { m_pFileStream->ReadByteStringLine(sLine,nEncoding); if ( !m_pFileStream->IsEof() ) { - m_aCurrentLine.GetString().Append('\n'); - m_aCurrentLine.GetString() += sLine.GetString(); - sLine = m_aCurrentLine; + line.GetString().Append('\n'); + line.GetString() += sLine.GetString(); + sLine = line; } else break; @@ -917,4 +922,3 @@ sal_Bool OFlatTable::readLine(sal_Int32& _rnCurrentPos) _rnCurrentPos = m_pFileStream->Tell(); return sal_True; } - diff --git a/main/connectivity/source/inc/flat/ETable.hxx b/main/connectivity/source/inc/flat/ETable.hxx index af447194c5..58e3eff4e2 100644 --- a/main/connectivity/source/inc/flat/ETable.hxx +++ b/main/connectivity/source/inc/flat/ETable.hxx @@ -64,6 +64,7 @@ namespace connectivity void fillColumns(const ::com::sun::star::lang::Locale& _aLocale); sal_Bool CreateFile(const INetURLObject& aFile, sal_Bool& bCreateMemo); sal_Bool readLine(sal_Int32& _rnCurrentPos); + sal_Bool readLine(QuotedTokenizedString& line, sal_Int32& _rnCurrentPos); void impl_fillColumnInfo_nothrow(QuotedTokenizedString& aFirstLine,xub_StrLen& nStartPosFirstLine,xub_StrLen& nStartPosFirstLine2 ,sal_Int32& io_nType,sal_Int32& io_nPrecisions,sal_Int32& io_nScales,String& o_sTypeName ,const sal_Unicode cDecimalDelimiter,const sal_Unicode cThousandDelimiter,const CharClass& aCharClass);