sc/qa/unit/data/xlsb/pivottable_error_item_filter.xlsb |binary
 sc/qa/unit/data/xlsx/tdf122471.xlsx                    |binary
 sc/qa/unit/pivottable_filters_test.cxx                 |   56 +++++++++++++++++
 sc/source/filter/inc/pivotcachebuffer.hxx              |    2 
 sc/source/filter/oox/pivotcachebuffer.cxx              |   10 +--
 sc/source/filter/oox/pivotcachefragment.cxx            |    2 
 6 files changed, 63 insertions(+), 7 deletions(-)

New commits:
commit 789fbf732ad6db002fd83b307385940c392cc457
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Mon Feb 28 15:36:08 2022 +0200
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Wed Mar 2 18:58:17 2022 +0100

    tdf#122471 xlsx import: pivottable error OUString, not uInt8
    
    This fixes a LO 6.0 regression from
    commit 9fa34e9f2cebe2cfc551668f2a67ddcb799d3fb8
    which only half-way changed to OUString from uInt8.
    
    An exception was raised because in XLSX, an INT was written
    while the corresponding read function was expecting an OUString.
    
    However, doing this runs into problems with binary files (xlsb),
    which were still setting the value to an int.
    Unit test shows the need to use OUString for xlsb too,
    which now matches what I see in Excel 2003.
    
    make CppunitTest_sc_pivottable_filters_test \
      CPPUNIT_TEST_NAME=testPivotTableErrorItem2FilterXLSX
    
    Change-Id: I399c9e34984bb1ff71695a87aa56f53063d37b3d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130714
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>
    (cherry picked from commit 6961f6732954742415413fa53bdeebd1b03d9ec5)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130678
    Reviewed-by: Eike Rathke <er...@redhat.com>

diff --git a/sc/qa/unit/data/xlsb/pivottable_error_item_filter.xlsb 
b/sc/qa/unit/data/xlsb/pivottable_error_item_filter.xlsb
new file mode 100644
index 000000000000..c32b8f3743e6
Binary files /dev/null and 
b/sc/qa/unit/data/xlsb/pivottable_error_item_filter.xlsb differ
diff --git a/sc/qa/unit/data/xlsx/tdf122471.xlsx 
b/sc/qa/unit/data/xlsx/tdf122471.xlsx
new file mode 100644
index 000000000000..febac5c73506
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf122471.xlsx differ
diff --git a/sc/qa/unit/pivottable_filters_test.cxx 
b/sc/qa/unit/pivottable_filters_test.cxx
index 80557c5b12aa..f6507d6cfccf 100644
--- a/sc/qa/unit/pivottable_filters_test.cxx
+++ b/sc/qa/unit/pivottable_filters_test.cxx
@@ -79,6 +79,8 @@ public:
     void testPivotTableBoolFieldFilterXLSX();
     void testPivotTableRowColPageFieldFilterXLSX();
     void testPivotTableErrorItemFilterXLSX();
+    void testPivotTableErrorItemFilterXLSB();
+    void testPivotTableErrorItem2FilterXLSX();
     void testPivotTableOutlineModeXLSX();
     void testPivotTableDuplicatedMemberFilterXLSX();
     void testPivotTableTabularModeXLSX();
@@ -130,6 +132,8 @@ public:
     CPPUNIT_TEST(testPivotTableBoolFieldFilterXLSX);
     CPPUNIT_TEST(testPivotTableRowColPageFieldFilterXLSX);
     CPPUNIT_TEST(testPivotTableErrorItemFilterXLSX);
+    CPPUNIT_TEST(testPivotTableErrorItemFilterXLSB);
+    CPPUNIT_TEST(testPivotTableErrorItem2FilterXLSX);
     CPPUNIT_TEST(testPivotTableOutlineModeXLSX);
     CPPUNIT_TEST(testPivotTableDuplicatedMemberFilterXLSX);
     CPPUNIT_TEST(testPivotTableTabularModeXLSX);
@@ -2370,6 +2374,58 @@ void 
ScPivotTableFiltersTest::testPivotTableErrorItemFilterXLSX()
     xDocSh->DoClose();
 }
 
+void ScPivotTableFiltersTest::testPivotTableErrorItemFilterXLSB()
+{
+    ScDocShellRef xDocSh = loadDoc(u"pivottable_error_item_filter.", 
FORMAT_XLSB);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+    ScDocument& rDoc = xDocSh->GetDocument();
+    ScDPCollection* pDPs = rDoc.GetDPCollection();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+    const ScDPObject* pDPObj = &(*pDPs)[0];
+    CPPUNIT_ASSERT(pDPObj);
+    ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+    CPPUNIT_ASSERT(pSaveData);
+
+    ScDPSaveDimension* pSaveDim = pSaveData->GetExistingDimensionByName(u"b");
+    CPPUNIT_ASSERT(pSaveDim);
+    const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+    CPPUNIT_ASSERT_EQUAL(size_t(4), rMembers.size());
+    ScDPSaveMember* pMember = pSaveDim->GetExistingMemberByName("#DIV/0!");
+    CPPUNIT_ASSERT(pMember);
+    CPPUNIT_ASSERT(pMember->HasIsVisible());
+    CPPUNIT_ASSERT(!pMember->GetIsVisible());
+
+    xDocSh->DoClose();
+}
+
+void ScPivotTableFiltersTest::testPivotTableErrorItem2FilterXLSX()
+{
+    ScDocShellRef xDocSh = loadDoc(u"tdf122471.", FORMAT_XLSX);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+    ScDocument& rDoc = xDocSh->GetDocument();
+    ScDPCollection* pDPs = rDoc.GetDPCollection();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+
+    // Reload and check whether filtering is preserved
+    xDocSh = saveAndReload(&(*xDocSh), FORMAT_XLSX);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
+    ScDocument& rLoadedDoc = xDocSh->GetDocument();
+    pDPs = rLoadedDoc.GetDPCollection();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDPs->GetCount());
+    const ScDPObject* pDPObj = &(*pDPs)[0];
+    CPPUNIT_ASSERT(pDPObj);
+    ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+    CPPUNIT_ASSERT(pSaveData);
+
+    ScDPSaveDimension* pSaveDim = 
pSaveData->GetExistingDimensionByName(u"PPP");
+    CPPUNIT_ASSERT(pSaveDim);
+    const ScDPSaveDimension::MemberList& rMembers = pSaveDim->GetMembers();
+    // prior to the patch, columns were missing due to an exception dropping 
the column data
+    CPPUNIT_ASSERT_EQUAL(size_t(21), rMembers.size());
+
+    xDocSh->DoClose();
+}
+
 void ScPivotTableFiltersTest::testPivotTableOutlineModeXLSX()
 {
     ScDocShellRef xShell = loadDoc(u"pivottable_outline_mode.", FORMAT_XLSX);
diff --git a/sc/source/filter/inc/pivotcachebuffer.hxx 
b/sc/source/filter/inc/pivotcachebuffer.hxx
index 6f7e75a7151b..5997d8db3d2c 100644
--- a/sc/source/filter/inc/pivotcachebuffer.hxx
+++ b/sc/source/filter/inc/pivotcachebuffer.hxx
@@ -71,7 +71,7 @@ public:
     /** Reads the boolean value from a pivot cache item. */
     void                readBool( SequenceInputStream& rStrm );
     /** Reads the error code value from a pivot cache item. */
-    void                readError( SequenceInputStream& rStrm );
+    void                readError(SequenceInputStream& rStrm, const 
UnitConverter& rUnitConverter);
     /** Reads the index of a shared item. */
     void                readIndex( SequenceInputStream& rStrm );
 
diff --git a/sc/source/filter/oox/pivotcachebuffer.cxx 
b/sc/source/filter/oox/pivotcachebuffer.cxx
index 52c57d002a0b..b1b12ba435e8 100644
--- a/sc/source/filter/oox/pivotcachebuffer.cxx
+++ b/sc/source/filter/oox/pivotcachebuffer.cxx
@@ -202,9 +202,9 @@ void PivotCacheItem::readBool( SequenceInputStream& rStrm )
     mnType = XML_b;
 }
 
-void PivotCacheItem::readError( SequenceInputStream& rStrm )
+void PivotCacheItem::readError(SequenceInputStream& rStrm, const 
UnitConverter& rUnitConverter)
 {
-    maValue <<= static_cast< sal_Int32 >( rStrm.readuInt8() );
+    maValue <<= rUnitConverter.calcErrorString(rStrm.readuInt8());
     mnType = XML_e;
 }
 
@@ -294,7 +294,7 @@ void PivotCacheItemList::importItem( sal_Int32 nRecId, 
SequenceInputStream& rStr
         case BIFF12_ID_PCITEM_BOOL:
         case BIFF12_ID_PCITEMA_BOOL:    rItem.readBool( rStrm );    break;
         case BIFF12_ID_PCITEM_ERROR:
-        case BIFF12_ID_PCITEMA_ERROR:   rItem.readError( rStrm );   break;
+        case BIFF12_ID_PCITEMA_ERROR: rItem.readError(rStrm, 
getUnitConverter()); break;
         default:    OSL_FAIL( "PivotCacheItemList::importItem - unknown record 
type" );
     }
 }
@@ -339,7 +339,7 @@ void PivotCacheItemList::importArray( SequenceInputStream& 
rStrm )
         {
             case BIFF12_PCITEM_ARRAY_DOUBLE: createItem().readDouble( rStrm ); 
  break;
             case BIFF12_PCITEM_ARRAY_STRING: createItem().readString( rStrm ); 
  break;
-            case BIFF12_PCITEM_ARRAY_ERROR:  createItem().readError( rStrm );  
  break;
+            case BIFF12_PCITEM_ARRAY_ERROR: createItem().readError(rStrm, 
getUnitConverter()); break;
             case BIFF12_PCITEM_ARRAY_DATE:   createItem().readDate( rStrm );   
  break;
             default:
                 OSL_FAIL( "PivotCacheItemList::importArray - unknown data 
type" );
@@ -831,7 +831,7 @@ void PivotCacheField::writeItemToSourceDataCell( const 
WorksheetHelper& rSheetHe
         case XML_i: rSheetData.setValueCell( aModel, rItem.getValue().get< 
sal_Int16 >() );                             break;
         case XML_d: rSheetData.setDateTimeCell( aModel, rItem.getValue().get< 
css::util::DateTime >() );                           break;
         case XML_b: rSheetData.setBooleanCell( aModel, rItem.getValue().get< 
bool >() );                                break;
-        case XML_e: rSheetData.setErrorCell( aModel, static_cast< sal_uInt8 >( 
rItem.getValue().get< sal_Int32 >() ) ); break;
+        case XML_e: rSheetData.setErrorCell(aModel, 
rItem.getValue().get<OUString>()); break;
         default:    OSL_FAIL( "PivotCacheField::writeItemToSourceDataCell - 
unexpected item data type" );
     }
 }
diff --git a/sc/source/filter/oox/pivotcachefragment.cxx 
b/sc/source/filter/oox/pivotcachefragment.cxx
index a8db4426be33..f508c36cf8cc 100644
--- a/sc/source/filter/oox/pivotcachefragment.cxx
+++ b/sc/source/filter/oox/pivotcachefragment.cxx
@@ -311,7 +311,7 @@ void PivotCacheRecordsFragment::importPCRecordItem( 
sal_Int32 nRecId, SequenceIn
         case BIFF12_ID_PCITEM_DOUBLE:   aItem.readDouble( rStrm );  break;
         case BIFF12_ID_PCITEM_DATE:     aItem.readDate( rStrm );    break;
         case BIFF12_ID_PCITEM_BOOL:     aItem.readBool( rStrm );    break;
-        case BIFF12_ID_PCITEM_ERROR:    aItem.readError( rStrm );   break;
+        case BIFF12_ID_PCITEM_ERROR:    aItem.readError( rStrm, 
getUnitConverter() ); break;
         case BIFF12_ID_PCITEM_INDEX:    aItem.readIndex( rStrm );   break;
         default:    OSL_FAIL( 
"OoxPivotCacheRecordsFragment::importPCRecordItem - unexpected record" );
     }

Reply via email to