[Libreoffice-commits] .: sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Nov 22 09:15:29 PST 2011


 sc/source/filter/excel/read.cxx     |   23 ++++++++++++++++-------
 sc/source/filter/excel/xistream.cxx |   13 +++++++++++++
 sc/source/filter/inc/xistream.hxx   |    2 ++
 3 files changed, 31 insertions(+), 7 deletions(-)

New commits:
commit 799c944cc11aa6eeb20e5f24bf33434908c4556b
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Nov 22 12:12:50 2011 -0500

    fdo#40304: Check if BOUNDSHEET points to valid BOF record.
    
    Some (presumably Russian) 3rd party programs generate invalid xls docs
    that have BOUNDSHEET record pointing to invalid BOF record position.
    The real BOF position may be before or after the record pointed to by
    the BOUNDSHEET.
    
    So, let's check if the BOUNDSHEET points to a valid BOF, and if not,
    manually search for one from the BOUNDSHEET record position.

diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index 8b7eaca..b8c8585 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -847,14 +847,23 @@ FltError ImportExcel8::Read( void )
             {
                 nProgressBaseSize += (aIn.GetSvStreamPos() - nProgressBasePos);
                 nProgressBasePos = maSheetOffsets[ nScTab ];
-                aIn.StartNextRecord( nProgressBasePos );
-                while (aIn.GetRecId() != EXC_ID5_BOF)
+                if (aIn.PeekRecId(nProgressBasePos) == EXC_ID5_BOF)
+                    // BOUNDSHEET points to a valid BOF record.  Good.
+                    aIn.StartNextRecord(nProgressBasePos);
+                else
                 {
-                    // i#115255 Some malformed documents generated by 3rd
-                    // party Russian program(s) occasionally insert non BOF
-                    // record(s) at position indicated by BOUNDSHEET.  Skip
-                    // them.
-                    aIn.StartNextRecord();
+                    // i#115255 fdo#40304 BOUNDSHEET doesn't point to a valid
+                    // BOF record position.  Scan the records manually (from
+                    // the BOUNDSHEET position) until we find a BOF.  Some 3rd
+                    // party Russian programs generate invalid xls docs with
+                    // this kind of silliness.
+                    bool bValid = true;
+                    while (bValid && aIn.GetRecId() != EXC_ID5_BOF)
+                        bValid = aIn.StartNextRecord();
+
+                    if (!bValid)
+                        // Safeguard ourselves from potential infinite loop.
+                        eAkt = EXC_STATE_END;
                 }
             }
             else
diff --git a/sc/source/filter/excel/xistream.cxx b/sc/source/filter/excel/xistream.cxx
index e5ec510..81c536f 100644
--- a/sc/source/filter/excel/xistream.cxx
+++ b/sc/source/filter/excel/xistream.cxx
@@ -600,6 +600,19 @@ sal_uInt16 XclImpStream::GetNextRecId()
     return nRecId;
 }
 
+sal_uInt16 XclImpStream::PeekRecId( sal_Size nPos )
+{
+    sal_uInt16 nRecId = EXC_ID_UNKNOWN;
+    if (mbValidRec && nPos < mnStreamSize)
+    {
+        sal_Size nCurPos = mrStrm.Tell();
+        mrStrm.Seek(nPos);
+        mrStrm >> nRecId;
+        mrStrm.Seek(nCurPos);
+    }
+    return nRecId;
+}
+
 // ----------------------------------------------------------------------------
 
 XclImpStream& XclImpStream::operator>>( sal_Int8& rnValue )
diff --git a/sc/source/filter/inc/xistream.hxx b/sc/source/filter/inc/xistream.hxx
index ac5a84a..89dab91 100644
--- a/sc/source/filter/inc/xistream.hxx
+++ b/sc/source/filter/inc/xistream.hxx
@@ -332,6 +332,8 @@ public:
     /** Returns the record ID of the following record. */
     sal_uInt16          GetNextRecId();
 
+    sal_uInt16          PeekRecId( sal_Size nPos );
+
     XclImpStream&       operator>>( sal_Int8& rnValue );
     XclImpStream&       operator>>( sal_uInt8& rnValue );
     XclImpStream&       operator>>( sal_Int16& rnValue );


More information about the Libreoffice-commits mailing list