commit 724ca83161ac6a17d78538e7b91e11c812987a8e
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Sat Mar 15 22:09:23 2025 +0100

    Fixup 16e67d4e: replace incorrect code with with new mechanism
    
    The commit above tried to avoid recursion in InsetMathMacro::validate
    by readong macro definitions. Unfortunately, the code is broken (for
    example tokenPos does not return an index in a string) and Coverity
    Scan does not like it (because the pos variable can be used although
    it is negative).
    
    This is a fresh start: instead of avoiding calling validate, we return
    early when the recursion happens. To this end, we use a static
    set<docstring> that checks what macros are currently being validated.
    This still works when the recursion happens in a cycle of size 3 or
    more.
    
    Related to bug #12633.
---
 src/mathed/InsetMathMacro.cpp | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/mathed/InsetMathMacro.cpp b/src/mathed/InsetMathMacro.cpp
index 05eedc191b..6e209a0e5f 100644
--- a/src/mathed/InsetMathMacro.cpp
+++ b/src/mathed/InsetMathMacro.cpp
@@ -956,6 +956,14 @@ MacroData const * InsetMathMacro::macroBackup() const
 
 void InsetMathMacro::validate(LaTeXFeatures & features) const
 {
+       // Protect against recursive macros
+       static set<docstring> active_macros;
+       if (active_macros.count(name())) {
+               LYXERR0("Recursive nesting for "  << name());
+               return;
+       }
+       active_macros.insert(name());
+
        // Immediately after a document is loaded, in some cases the MacroData
        // of the global macros defined in the lib/symbols file may still not
        // be known to the macro machinery because it will be set only after
@@ -985,24 +993,15 @@ void InsetMathMacro::validate(LaTeXFeatures & features) 
const
                if (displayMode() == DISPLAY_NORMAL) {
                                d->definition_.validate(features);
                } else if (displayMode() == DISPLAY_INIT) {
-                       MathData ar(const_cast<Buffer *>(&buffer()));
-                       MacroData const * data = buffer().getMacro(name());
-                       if (data) {
-                               // Avoid recursion on a recursive macro 
definition
-                               docstring const & def = data->definition();
-                               int pos = tokenPos(def, '\\', name());
-                               char_type c = pos + name().size() < def.size()
-                                             ? def.at(pos + name().size()) : 0;
-                               if (pos < 0 || (name().size() > 1 &&
-                                               ((c >= 'a' && c <= 'z') ||
-                                                (c >= 'A' && c <= 'Z')))) {
-                                       asArray(def, ar);
-                                       ar.validate(features);
-                               }
+                       if (MacroData const * data = buffer().getMacro(name())) 
{
+                               MathData ar(const_cast<Buffer *>(&buffer()));
+                               asArray(data->definition(), ar);
+                               ar.validate(features);
                        }
                }
        }
        InsetMathNest::validate(features);
+       active_macros.erase(name());
 }
 
 
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to