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