filter/source/storagefilterdetect/filterdetect.cxx  |   52 ++++++++++----------
 sw/qa/extras/odfimport/data/unreferenced_stream.odt |binary
 sw/qa/extras/odfimport/odfimport.cxx                |   15 +++++
 3 files changed, 41 insertions(+), 26 deletions(-)

New commits:
commit 6c62129e64eb5ef00dfa5f2137c8689d55190163
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Feb 1 09:30:50 2024 +0600
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Feb 1 09:45:58 2024 +0100

    tdf#159474: fix handling of pre-set RepairPackage property
    
    StorageFilterDetect::detect had a wrong logic here, only honoring
    repair request in case it haappened interactively inside it. The
    pre-existing RepairPackage set to true was treated as "do not try
    to repair".
    
    Change-Id: I3fb63a5d72097a79977e8ed734f8e69dd2ea999a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162858
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/filter/source/storagefilterdetect/filterdetect.cxx 
b/filter/source/storagefilterdetect/filterdetect.cxx
index c73355e02a9d..1d0d7557d273 100644
--- a/filter/source/storagefilterdetect/filterdetect.cxx
+++ b/filter/source/storagefilterdetect/filterdetect.cxx
@@ -121,44 +121,44 @@ OUString SAL_CALL 
StorageFilterDetect::detect(uno::Sequence<beans::PropertyValue
         if ( ( aWrap.TargetException >>= aZipException ) && 
!aRequestedTypeName.isEmpty() )
         {
             // The package is a broken one.
-            uno::Reference< task::XInteractionHandler > xInteraction =
-                aMediaDesc.getUnpackedValueOrDefault( 
MediaDescriptor::PROP_INTERACTIONHANDLER, uno::Reference< 
task::XInteractionHandler >() );
-
-            if ( xInteraction.is() )
+            INetURLObject aParser(
+                
aMediaDesc.getUnpackedValueOrDefault(MediaDescriptor::PROP_URL, OUString()));
+            OUString aDocumentTitle = 
aParser.getName(INetURLObject::LAST_SEGMENT, true,
+                                                      
INetURLObject::DecodeMechanism::WithCharset);
+            bool bRepairPackage = 
aMediaDesc.getUnpackedValueOrDefault("RepairPackage", false);
+            // fdo#46310 Don't ask to repair if the user rejected it once.
+            if (!bRepairPackage && 
aMediaDesc.getUnpackedValueOrDefault("RepairAllowed", true))
             {
-                INetURLObject aParser( aMediaDesc.getUnpackedValueOrDefault( 
MediaDescriptor::PROP_URL, OUString() ) );
-                OUString aDocumentTitle = aParser.getName( 
INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset 
);
-                bool bRepairPackage = aMediaDesc.getUnpackedValueOrDefault( 
"RepairPackage", false );
-                // fdo#46310 Don't try to repair if the user rejected it once.
-                bool bRepairAllowed = aMediaDesc.getUnpackedValueOrDefault( 
"RepairAllowed", true );
+                uno::Reference< task::XInteractionHandler > xInteraction =
+                    aMediaDesc.getUnpackedValueOrDefault( 
MediaDescriptor::PROP_INTERACTIONHANDLER, uno::Reference< 
task::XInteractionHandler >() );
 
-                if ( !bRepairPackage && bRepairAllowed )
+                if ( xInteraction.is() )
                 {
                     // Ask the user whether he wants to try to repair.
-                    RequestPackageReparation aRequest( aDocumentTitle );
-                    xInteraction->handle( aRequest.GetRequest() );
-
-                    if ( aRequest.isApproved() )
-                    {
-                        aTypeName = aRequestedTypeName;
-                        // lok: we want to overwrite file in jail, so don't 
use template flag
-                        const bool bIsLOK = 
comphelper::LibreOfficeKit::isActive();
-                        aMediaDesc[MediaDescriptor::PROP_DOCUMENTTITLE] <<= 
aDocumentTitle;
-                        aMediaDesc[MediaDescriptor::PROP_ASTEMPLATE] <<= 
!bIsLOK;
-                        aMediaDesc["RepairPackage"] <<= true;
-                    }
-                    else
+                    RequestPackageReparation aRequest(aDocumentTitle);
+                    xInteraction->handle(aRequest.GetRequest());
+                    bRepairPackage = aRequest.isApproved();
+                    if (!bRepairPackage)
                     {
                         // Repair either not allowed or not successful.
                         NotifyBrokenPackage aNotifyRequest( aDocumentTitle );
                         xInteraction->handle( aNotifyRequest.GetRequest() );
                         aMediaDesc["RepairAllowed"] <<= false;
                     }
-
-                    // Write the changes back.
-                    aMediaDesc >> rDescriptor;
                 }
             }
+            if (bRepairPackage)
+            {
+                aTypeName = aRequestedTypeName;
+                // lok: we want to overwrite file in jail, so don't use 
template flag
+                const bool bIsLOK = comphelper::LibreOfficeKit::isActive();
+                aMediaDesc[MediaDescriptor::PROP_DOCUMENTTITLE] <<= 
aDocumentTitle;
+                aMediaDesc[MediaDescriptor::PROP_ASTEMPLATE] <<= !bIsLOK;
+                aMediaDesc["RepairPackage"] <<= true;
+            }
+
+            // Write the changes back.
+            aMediaDesc >> rDescriptor;
         }
     }
     catch( uno::RuntimeException& )
diff --git a/sw/qa/extras/odfimport/data/unreferenced_stream.odt 
b/sw/qa/extras/odfimport/data/unreferenced_stream.odt
new file mode 100644
index 000000000000..0cdba0d48529
Binary files /dev/null and 
b/sw/qa/extras/odfimport/data/unreferenced_stream.odt differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx 
b/sw/qa/extras/odfimport/odfimport.cxx
index 753551240ca3..aa158b43b132 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -1536,6 +1536,21 @@ CPPUNIT_TEST_FIXTURE(Test, testEmptyTrailingSpans)
     CPPUNIT_ASSERT_DOUBLES_EQUAL(184, height2, 1); // allow a bit of room for 
rounding just in case
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testBrokenPackage_Tdf159474)
+{
+    // Given an invalid ODF having a stream not referenced in manifest.xml
+    const OUString url = createFileURL(u"unreferenced_stream.odt");
+    // It expectedly fails to load normally:
+    CPPUNIT_ASSERT_ASSERTION_FAIL(loadFromDesktop(url, {}, {}));
+    // importing it must succeed with RepairPackage set to true.
+    mxComponent
+        = loadFromDesktop(url, {}, { 
comphelper::makePropertyValue(u"RepairPackage"_ustr, true) });
+    // The document imports in repair mode; the original broken package is 
used as a template,
+    // and the loaded document has no URL:
+    
CPPUNIT_ASSERT(mxComponent.queryThrow<frame::XModel>()->getURL().isEmpty());
+    CPPUNIT_ASSERT_EQUAL(u"Empty document"_ustr, getParagraph(1)->getString());
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to