From eb2d373e4bdc6169d42f42ff5a886e3d36e86510 Mon Sep 17 00:00:00 2001 From: Guillaume Munch Date: Tue, 3 Jan 2017 20:17:20 +0100 Subject: [PATCH] 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. --- src/mathed/MathMacroArgument.cpp | 56 ++++++++++++++++++++------------ src/mathed/MathMacroArgument.h | 32 +++++++++++++----- src/mathed/MathParser.cpp | 10 ++++-- 3 files changed, 66 insertions(+), 32 deletions(-) diff --git a/src/mathed/MathMacroArgument.cpp b/src/mathed/MathMacroArgument.cpp index 76b43f3629..d3a16ff8d9 100644 --- a/src/mathed/MathMacroArgument.cpp +++ b/src/mathed/MathMacroArgument.cpp @@ -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_ << "] "; diff --git a/src/mathed/MathMacroArgument.h b/src/mathed/MathMacroArgument.h index 4a52b1a1d2..bb9fa1dc30 100644 --- a/src/mathed/MathMacroArgument.h +++ b/src/mathed/MathMacroArgument.h @@ -21,33 +21,47 @@ 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 normalize(NormalStream &) const; + /// + void write(WriteStream & os) const; + +private: + Inset * clone() const; + +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; - /// - void write(WriteStream & os) const; private: Inset * clone() const; /// A number between 1 and 9 int number_; - /// - docstring str_; }; diff --git a/src/mathed/MathParser.cpp b/src/mathed/MathParser.cpp index d4ecc72f22..83fc9c7da6 100644 --- a/src/mathed/MathParser.cpp +++ b/src/mathed/MathParser.cpp @@ -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) -- 2.39.5