]> git.lyx.org Git - features.git/commitdiff
Fix wrong parse of macro parameter and crash
authorGuillaume Munch <gm@lyx.org>
Tue, 3 Jan 2017 19:17:20 +0000 (20:17 +0100)
committerGuillaume Munch <gm@lyx.org>
Tue, 3 Jan 2017 19:35:41 +0000 (20:35 +0100)
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
src/mathed/MathMacroArgument.h
src/mathed/MathParser.cpp

index 76b43f3629f255a0fffc3f5a0ee4186ed8e95bc8..d3a16ff8d9af6ab88e87236d0bdac06a14b5d487 100644 (file)
 #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_ << "] ";
index 4a52b1a1d20fda1e63a2bae1096a095cd63f694b..bb9fa1dc304f8742229caf04065f5460b89445f6 100644 (file)
 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_;
 };
 
 
index d4ecc72f22ac82376fa689f22e583bb52bfd3e84..83fc9c7da602bfddc31d615bbf9ca92270220a3d 100644 (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)