commit b087fd578cdca8559abe3956528e91338a82fac0
Author: Juergen Spitzmueller <[email protected]>
Date:   Fri May 2 11:41:08 2025 +0200

    Do not attempt to access external (xr) filenames when buffer is closed
    
    This will crash upon dangling pointers (and the accesses are not needed)
---
 src/Buffer.cpp               | 18 +++++++++++++++++-
 src/Buffer.h                 |  5 +++++
 src/frontends/qt/GuiView.cpp |  2 ++
 src/insets/InsetRef.cpp      | 14 +++++++++++---
 4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index 97c92c7d6a..dec9f4d635 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -366,6 +366,9 @@ public:
        ///
        mutable bool need_update;
 
+       ///
+       bool is_closing;
+
        ///
        Statistics statistics_;
 
@@ -453,7 +456,8 @@ Buffer::Impl::Impl(Buffer * owner, FileName const & file, 
bool readonly_,
          have_bibitems_(false), lyx_clean(true), bak_clean(true), 
unnamed(false),
          internal_buffer(false), read_only(readonly_), 
file_fully_loaded(false),
          need_format_backup(false), ignore_parent(false), macro_lock(false),
-         externally_modified_(false), bibinfo_cache_valid_(false), 
need_update(false)
+         externally_modified_(false), bibinfo_cache_valid_(false), 
need_update(false),
+         is_closing(false)
 {
        refreshFileMonitor();
        if (!cloned_buffer_) {
@@ -5483,6 +5487,18 @@ bool Buffer::needUpdate() const
 }
 
 
+bool Buffer::isClosing() const
+{
+       return d->is_closing;
+}
+
+
+void Buffer::setClosing(bool const b)
+{
+       d->is_closing = b;
+}
+
+
 int Buffer::spellCheck(DocIterator & from, DocIterator & to,
        WordLangTuple & word_lang, docstring_list & suggestions) const
 {
diff --git a/src/Buffer.h b/src/Buffer.h
index f081932ba0..d51776d3ff 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -825,6 +825,11 @@ public:
        void popIncludedBuffer() const;
        bool isBufferIncluded(Buffer const * buf) const;
 
+       /// Is this buffer about to be closed?
+       bool isClosing()const;
+       /// Is this buffer about to be closed?
+       void setClosing(bool const b);
+
        ///
        void registerExternalRefs(support::FileName) const;
        ///
diff --git a/src/frontends/qt/GuiView.cpp b/src/frontends/qt/GuiView.cpp
index c09e6329a1..54920785b7 100644
--- a/src/frontends/qt/GuiView.cpp
+++ b/src/frontends/qt/GuiView.cpp
@@ -3875,6 +3875,7 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa, bool 
close_buffer)
 
 bool GuiView::closeBuffer(Buffer & buf)
 {
+       buf.setClosing(true);
        bool success = true;
        for (Buffer * child_buf : buf.getChildren()) {
                if (theBufferList().isOthersChild(&buf, child_buf)) {
@@ -3934,6 +3935,7 @@ bool GuiView::closeBuffer(Buffer & buf)
                        return true;
                }
        }
+       buf.setClosing(false);
        // open all children again to avoid a crash because of dangling
        // pointers (bug 6603)
        buf.updateBuffer();
diff --git a/src/insets/InsetRef.cpp b/src/insets/InsetRef.cpp
index e50b4ea786..b7b3c8327e 100644
--- a/src/insets/InsetRef.cpp
+++ b/src/insets/InsetRef.cpp
@@ -820,7 +820,8 @@ void InsetRef::updateBuffer(ParIterator const & it, 
UpdateType, bool const /*del
        // not be in the label cache yet.)
        broken_ = false;
        setBroken(broken_);
-       cleanUpExternalFileNames();
+       if (!buffer().isClosing())
+               cleanUpExternalFileNames();
 }
 
 
@@ -1008,9 +1009,11 @@ bool InsetRef::useRange() const
 vector<FileName> InsetRef::externalFilenames(bool const warn) const
 {
        vector<FileName> res;
-       if (buffer().isInternal())
-               // internal buffers (with their own filenames)
+       if (buffer().isInternal() || buffer().isClosing())
+               // Internal buffers (with their own filenames)
                // are excluded from this.
+               // We also do not proceed on closing buffers
+               // since we might stumple upon dangling pointers.
                return res;
 
        vector<string> incFileNames = 
getVectorFromString(ltrim(to_utf8(params()["filenames"])));
@@ -1052,6 +1055,11 @@ vector<FileName> InsetRef::externalFilenames(bool const 
warn) const
 
 FileName InsetRef::getExternalFileName(docstring const & inlabel) const
 {
+       if (buffer().isClosing())
+               // We do not proceed on closing buffers
+               // since we might stumple upon dangling pointers.
+               return FileName();
+
        vector<string> incFileNames = 
getVectorFromString(ltrim(to_utf8(params()["filenames"])));
        if (incFileNames.empty())
                // nothing to do
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to