Fix crash due to recursive function call when a counter references itself.

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
This commit is contained in:
Bernhard Roider 2008-02-23 20:38:57 +00:00
parent 21a3cd14d2
commit 52ccb98354
2 changed files with 43 additions and 11 deletions

View 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 (ls.empty()) {
if (!c.master().empty())
ls = from_ascii("\\the") + c.master() + from_ascii(".");
ls += from_ascii("\\arabic{") + counter + "}";
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);
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,7 +398,8 @@ 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);
}

View 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