sc/inc/conditio.hxx              |    5 ++---
 sc/source/core/data/conditio.cxx |   23 ++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 4 deletions(-)

New commits:
commit 69aeb20d07a5b40e961e611b064e3f6a6cb261f9
Author:     Dennis Francis <[email protected]>
AuthorDate: Fri Nov 7 22:41:15 2025 +0530
Commit:     Dennis Francis <[email protected]>
CommitDate: Wed Nov 12 12:31:57 2025 +0100

    cool#13378: fix oom with conditional formatting
    
    oom results when whole rows with conditional formatting is copied and
    pasted. This is because for every column in the row a listening
    'mpCache' is created and the doc-broadcaster has to accomodate them
    before exhausting all memory. See ctor of ScColorFormatCache.
    
    One particular reproducer is:
    1. Create a new Calc spreadsheet and enter a value in a cell, say 42.
    2. Select the whole sheet.
    3. Conditional > Manage > Add, and create a condition where cell value
       is equal to the value in the cell from step 1.
    4. Click on the row header containing 42 and copy that row and paste it
       onto another row.
    
    Conflicts:
            sc/source/core/data/conditio.cxx
    
    Signed-off-by: Dennis Francis <[email protected]>
    Change-Id: Ifee510fe39131ed3c03febc3bed983f4962e546e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193589
    Reviewed-by: Tomaž Vajngerl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    (cherry picked from commit 5438e2fd66a0038a00692d2457d6c89b5bd14695)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193825
    Tested-by: Jenkins

diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index 08c39189f3d2..f38b81cc999e 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -546,15 +546,14 @@ private:
 
 class ScColorFormatCache final : public SvtListener
 {
-private:
-    ScDocument& mrDoc;
-
 public:
     explicit ScColorFormatCache(ScDocument& rDoc, const ScRangeList& rRanges);
     virtual ~ScColorFormatCache() override;
 
     void Notify( const SfxHint& rHint ) override;
 
+    ScDocument& mrDoc;
+    ScRangeList maRanges;
     std::vector<double> maValues;
 };
 
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 2e2dee288b30..76afe0e67a30 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -1740,7 +1740,7 @@ void ScCondDateFormatEntry::endRendering()
 }
 
 ScColorFormatCache::ScColorFormatCache(ScDocument& rDoc, const ScRangeList& 
rRanges) :
-    mrDoc(rDoc)
+    mrDoc(rDoc), maRanges(rRanges)
 {
     if (mrDoc.IsClipOrUndo())
         return;
@@ -2144,8 +2144,29 @@ void ScConditionalFormat::CalcAll()
     }
 }
 
+/// whether rRlist1 contains rRlist2.
+static bool lcl_RangeContains(const ScRangeList& rRlist1, const ScRangeList& 
rRlist2)
+{
+    for (const auto& rRange: rRlist2)
+    {
+        if (!rRlist1.Contains(rRange))
+            return false;
+    }
+
+    return true;
+}
+
 void ScConditionalFormat::ResetCache() const
 {
+    if (mpCache && &mrDoc == &mpCache->mrDoc && 
lcl_RangeContains(mpCache->maRanges, maRanges))
+    {
+        // Cache is already listening to a super-set of maRanges.
+        // Don't shrink the range of mpCache yet as it is expensive.
+        // Just clear the cache.
+        mpCache->maValues.clear();
+        return;
+    }
+
     if (!maRanges.empty())
         mpCache = std::make_unique<ScColorFormatCache>(mrDoc, maRanges);
     else

Reply via email to