commit 724ca83161ac6a17d78538e7b91e11c812987a8e
Author: Jean-Marc Lasgouttes <[email protected]>
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
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs