]> git.lyx.org Git - features.git/commitdiff
Fix crash due to recursive function call when a counter references itself.
authorBernhard Roider <bernhard.roider@sonnenkinder.org>
Sat, 23 Feb 2008 20:38:57 +0000 (20:38 +0000)
committerBernhard Roider <bernhard.roider@sonnenkinder.org>
Sat, 23 Feb 2008 20:38:57 +0000 (20:38 +0000)
e.g.:

Counter
    Name                 Version
    LabelString          "\theVersion.0"
End

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23166 a592a061-630c-0410-9148-cb99ea01b6c8

src/Counters.cpp
src/Counters.h

index cec66729742ba6efe9d1b5b72dad1773389618b6..39e177b1f6b42b2a921599e88a14432ced912150 100644 (file)
@@ -339,23 +339,48 @@ docstring Counters::labelItem(docstring const & ctr,
 
 
 docstring Counters::theCounter(docstring const & counter)
+{
+       std::set<docstring> callers;
+       return theCounter(counter, callers);
+}
+
+docstring Counters::theCounter(docstring const & counter,
+                               std::set<docstring> & callers)
 {
        if (!hasCounter(counter))
                return from_ascii("??");
 
-       Counter const & c = counterList[counter];
-       docstring ls = appendix() ? c.labelStringAppendix() : c.labelString();
+       docstring label;
+
+       if (callers.find(counter) == callers.end()) {
+               
+               pair<std::set<docstring>::iterator, bool> result = callers.insert(counter);
+
+               Counter const & c = counterList[counter];
+               docstring ls = appendix() ? c.labelStringAppendix() : c.labelString();
+
+               if (ls.empty()) {
+                       if (!c.master().empty())
+                               ls = from_ascii("\\the") + c.master() + from_ascii(".");
+                       ls += from_ascii("\\arabic{") + counter + "}";
+               }
+
+               label = counterLabel(ls, &callers);
 
-       if (ls.empty()) {
-               if (!c.master().empty())
-                       ls = from_ascii("\\the") + c.master() + from_ascii(".");
-               ls += from_ascii("\\arabic{") + counter + "}";
+               callers.erase(result.first);
+       } else {
+               // recursion detected
+               lyxerr << "Warning: Recursion in label for counter `"
+                          << counter << "' detected"
+                          << endl;
        }
-       return counterLabel(ls);
+
+       return label;
 }
 
 
-docstring Counters::counterLabel(docstring const & format)
+docstring Counters::counterLabel(docstring const & format,
+                                 std::set<docstring> * callers)
 {
        docstring label = format;
 
@@ -373,10 +398,11 @@ docstring Counters::counterLabel(docstring const & format)
                       && lowercase(label[k]) <= 'z')
                        ++k;
                docstring counter = label.substr(j, k - j);
-               docstring repl = theCounter(counter);
+               docstring repl = callers? theCounter(counter, *callers): 
+                                             theCounter(counter);
                label.replace(i, k - j + 4, repl);
        }
-       
+
        while (true) {
                //lyxerr << "label=" << to_utf8(label) << endl;
 
index f2d4df71573f7abbec790e690f9471b0ff5ca813..f7d2cea1341e9ea73e1be86ee902b69d2e053c1f 100644 (file)
@@ -18,6 +18,7 @@
 #include "support/docstring.h"
 
 #include <map>
+#include <set>
 
 
 namespace lyx {
@@ -105,7 +106,8 @@ public:
        docstring theCounter(docstring const & c);
        /// Replace om format all the LaTeX-like macros that depend on
        /// counters.
-       docstring counterLabel(docstring const & format);
+       docstring counterLabel(docstring const & format, 
+                              std::set<docstring> * callers = 0);
        /// Are we in apendix?
        bool appendix() const { return appendix_; };
        /// Set the state variable indicating whether we are in appendix.
@@ -115,6 +117,10 @@ public:
        /// Sets the current enclosing float.
        void current_float(std::string const & f) { current_float_ = f; }
 private:
+       /// returns the expanded string representation of the counter
+       /// with recursion protection through callers.
+       docstring theCounter(docstring const & c, 
+                            std::set<docstring> & callers);
        /// Returns the value of the counter according to the
        /// numbering scheme numbertype.
        /* Available numbering schemes are arabic (1, 2,...), roman