Fix wrong parse of macro parameter and crash

Copy-pasting $#\n$ from text to LyX gives the error message:

    MathMacroArgument::MathMacroArgument: wrong Argument id

and it is not hard to get a crash soon after.

There are legitimate uses of # not followed by 1..9 in LaTeX and it is good to
parse them correctly when importing from LaTeX.
This commit is contained in:
Guillaume Munch 2017-01-03 20:17:20 +01:00
parent 981f065bde
commit eb2d373e4b
3 changed files with 70 additions and 36 deletions

View File

@ -16,15 +16,49 @@
#include "MathSupport.h"
#include "support/debug.h"
#include "support/lassert.h"
namespace lyx {
Inset * InsetMathHash::clone() const
{
return new InsetMathHash(*this);
}
void InsetMathHash::write(WriteStream & os) const
{
os << str_;
}
void InsetMathHash::metrics(MetricsInfo & mi, Dimension & dim) const
{
metricsStrRedBlack(mi, dim, str_);
}
void InsetMathHash::draw(PainterInfo & pi, int x, int y) const
{
drawStrRed(pi, x, y, str_);
}
void InsetMathHash::normalize(NormalStream & os) const
{
os << "[hash " << str_ << "] ";
}
MathMacroArgument::MathMacroArgument(int n)
: number_(n)
{
if (n < 1 || n > 9) {
LYXERR0("MathMacroArgument::MathMacroArgument: wrong Argument id: " << n);
LYXERR0("MathMacroArgument::MathMacroArgument: wrong Argument id: "
<< n);
LASSERT(false, n = 1);
}
// The profiler tells us not to use
@ -32,7 +66,6 @@ MathMacroArgument::MathMacroArgument(int n)
// so we do the conversion of n to ASCII manually.
// This works because 1 <= n <= 9.
str_.resize(2);
str_[0] = '#';
str_[1] = '0' + n;
}
@ -47,6 +80,7 @@ void MathMacroArgument::setNumber(int n)
{
if (n < 1 || n > 9) {
LYXERR0("MathMacroArgument::setNumber: wrong Argument id: " << n);
LASSERT(false, return);
}
number_ = n;
@ -54,24 +88,6 @@ void MathMacroArgument::setNumber(int n)
}
void MathMacroArgument::write(WriteStream & os) const
{
os << str_;
}
void MathMacroArgument::metrics(MetricsInfo & mi, Dimension & dim) const
{
metricsStrRedBlack(mi, dim, str_);
}
void MathMacroArgument::draw(PainterInfo & pi, int x, int y) const
{
drawStrRed(pi, x, y, str_);
}
void MathMacroArgument::normalize(NormalStream & os) const
{
os << "[macroarg " << str_ << "] ";

View File

@ -21,22 +21,14 @@
namespace lyx {
/// A macro argument.
class MathMacroArgument : public InsetMath {
// A # that failed to parse
class InsetMathHash : public InsetMath {
public:
///
explicit MathMacroArgument(int number);
InsetMathHash(docstring const & str = docstring()) : str_('#' + str) {};
///
void metrics(MetricsInfo & mi, Dimension & dim) const;
///
void draw(PainterInfo &, int x, int y) const;
///
int number() const { return number_; }
///
void setNumber(int n);
///
InsetCode lyxCode() const { return MATH_MACROARG_CODE; }
///
void normalize(NormalStream &) const;
///
@ -44,13 +36,35 @@ public:
private:
Inset * clone() const;
/// A number between 1 and 9
int number_;
protected:
///
docstring str_;
};
/// A macro argument.
class MathMacroArgument : public InsetMathHash {
public:
/// Assumes 0 < number <= 9
explicit MathMacroArgument(int number);
///
int number() const { return number_; }
/// Assumes 0 < n <= 9
void setNumber(int n);
///
InsetCode lyxCode() const { return MATH_MACROARG_CODE; }
///
void normalize(NormalStream &) const;
private:
Inset * clone() const;
/// A number between 1 and 9
int number_;
};
} // namespace lyx
#endif

View File

@ -929,9 +929,13 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
}
else if (t.cat() == catParameter) {
Token const & n = getToken();
if (n.character())
cell->push_back(MathAtom(new MathMacroArgument(n.character()-'0')));
Token const & n = nextToken();
char_type c = n.character();
if (c && '0' < c && c <= '9') {
cell->push_back(MathAtom(new MathMacroArgument(c - '0')));
getToken();
} else
cell->push_back(MathAtom(new InsetMathHash()));
}
else if (t.cat() == catActive)