commit 576159156ed99b5fa24a014da78f75a64b3ad0f4
Author: Jean-Marc Lasgouttes <[email protected]>
Date:   Tue Nov 3 15:20:09 2015 +0100

    Avoid using pointer after it has been invalidated
    
    The pointer macroInset points to a vector element. When another element is 
inserted in this vector, some reallocation occur and the pointer points to a 
deleted element.
    
    This does not crash LyX by default, but it is bad enough to make valgrind 
cry.
    
    See ticket #9804.

diff --git a/src/mathed/MathData.cpp b/src/mathed/MathData.cpp
index 2d3b153..01da608 100644
--- a/src/mathed/MathData.cpp
+++ b/src/mathed/MathData.cpp
@@ -492,6 +492,8 @@ void MathData::updateMacros(Cursor * cur, MacroContext 
const & mc,
 void MathData::detachMacroParameters(DocIterator * cur, const size_type 
macroPos)
 {
        MathMacro * macroInset = operator[](macroPos).nucleus()->asMacro();
+       // We store this now, because the inset pointer will be invalidated in 
the scond loop below
+       size_t const optionals = macroInset->optionals();
 
        // detach all arguments
        vector<MathData> detachedArgs;
@@ -517,7 +519,7 @@ void MathData::detachMacroParameters(DocIterator * cur, 
const size_type macroPos
 
        // only [] after the last non-empty argument can be dropped later
        size_t lastNonEmptyOptional = 0;
-       for (size_t l = 0; l < detachedArgs.size() && l < 
macroInset->optionals(); ++l) {
+       for (size_t l = 0; l < detachedArgs.size() && l < optionals; ++l) {
                if (!detachedArgs[l].empty())
                        lastNonEmptyOptional = l;
        }
@@ -525,7 +527,8 @@ void MathData::detachMacroParameters(DocIterator * cur, 
const size_type macroPos
        // optional arguments to be put back?
        pos_type p = macroPos + 1;
        size_t j = 0;
-       for (; j < detachedArgs.size() && j < macroInset->optionals(); ++j) {
+       // WARNING: do not use macroInset below, the insert() call in the lopp 
will invalidate it!
+       for (; j < detachedArgs.size() && j < optionals; ++j) {
                // another non-empty parameter follows?
                bool canDropEmptyOptional = j >= lastNonEmptyOptional;
 

Reply via email to