connectivity/source/drivers/dbase/DTable.cxx |   28 ++++++++++++++++++---------
 sc/qa/unit/data/dbf/pass/ooo83401-1.dbf      |binary
 2 files changed, 19 insertions(+), 9 deletions(-)

New commits:
commit c43f185a81e667c5e34a91f5dd1fd1a4e5a33b58
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Thu Sep 23 20:19:57 2021 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Sep 27 12:27:39 2021 +0200

    do some sanity checks on the number of records claimed
    
    while retaining the fix of #i83401# to recovered a broken case
    
    Change-Id: I283c45b10aaa24004a34bfe6faee517d4a443b98
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122543
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    (cherry picked from commit cea0753e18171bf9bcdd857535b20e6ed02222f5)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122445
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/connectivity/source/drivers/dbase/DTable.cxx 
b/connectivity/source/drivers/dbase/DTable.cxx
index c9c2991589db..ac51e4b53311 100644
--- a/connectivity/source/drivers/dbase/DTable.cxx
+++ b/connectivity/source/drivers/dbase/DTable.cxx
@@ -510,6 +510,24 @@ void ODbaseTable::construct()
         return;
     }
 
+    if (m_aHeader.recordLength)
+    {
+        std::size_t nMaxPossibleRecords = (nFileSize - m_aHeader.headerLength) 
/ m_aHeader.recordLength;
+        // #i83401# seems to be empty or someone wrote nonsense into the dbase
+        // file try and recover if m_aHeader.db_slng is sane
+        if (m_aHeader.nbRecords == 0)
+        {
+            SAL_WARN("connectivity.drivers", "Parsing warning: 0 records 
claimed, recovering");
+            m_aHeader.nbRecords = nMaxPossibleRecords;
+        }
+        else if (m_aHeader.nbRecords > nMaxPossibleRecords)
+        {
+            SAL_WARN("connectivity.drivers", "Parsing error: " << 
nMaxPossibleRecords <<
+                     " max possible records, but " << m_aHeader.nbRecords << " 
claimed, truncating");
+            m_aHeader.nbRecords = std::max(nMaxPossibleRecords, 
static_cast<size_t>(1));
+        }
+    }
+
     if (HasMemoFields())
     {
     // Create Memo-Filename (.DBT):
@@ -533,16 +551,8 @@ void ODbaseTable::construct()
     }
 
     fillColumns();
-
     m_pFileStream->Seek(STREAM_SEEK_TO_BEGIN);
-    // seems to be empty or someone wrote bullshit into the dbase file
-    // try and recover if m_aHeader.db_slng is sane
-    if (m_aHeader.nbRecords == 0 && m_aHeader.recordLength)
-    {
-        std::size_t nRecords = 
(nFileSize-m_aHeader.headerLength)/m_aHeader.recordLength;
-        if (nRecords > 0)
-            m_aHeader.nbRecords = nRecords;
-    }
+
 
     // Buffersize dependent on the file size
     m_pFileStream->SetBufferSize(nFileSize > 1000000 ? 32768 :
diff --git a/sc/qa/unit/data/dbf/pass/ooo83401-1.dbf 
b/sc/qa/unit/data/dbf/pass/ooo83401-1.dbf
new file mode 100644
index 000000000000..c916dc923e51
Binary files /dev/null and b/sc/qa/unit/data/dbf/pass/ooo83401-1.dbf differ

Reply via email to