]> git.lyx.org Git - features.git/commitdiff
Check encodability of math user macro names (#11855)
authorJuergen Spitzmueller <spitz@lyx.org>
Fri, 2 Dec 2022 10:23:32 +0000 (11:23 +0100)
committerJuergen Spitzmueller <spitz@lyx.org>
Fri, 2 Dec 2022 10:23:32 +0000 (11:23 +0100)
src/mathed/InsetMathMacro.cpp

index 7c9efa4859c0d2e49d1f45a0ddf92c72bb76dc0a..543bd2335dc2a14b13bbe005f3a6abb03a193c92 100644 (file)
@@ -27,6 +27,7 @@
 #include "BufferView.h"
 #include "CoordCache.h"
 #include "Cursor.h"
+#include "Encoding.h"
 #include "FuncStatus.h"
 #include "FuncRequest.h"
 #include "LaTeXFeatures.h"
@@ -34,6 +35,7 @@
 #include "LyXRC.h"
 #include "MetricsInfo.h"
 
+#include "frontends/alert.h"
 #include "frontends/Painter.h"
 
 #include "support/debug.h"
@@ -1146,10 +1148,53 @@ void InsetMathMacro::write(TeXMathStream & os) const
        mode_type mode = currentMode();
        MathEnsurer ensurer(os, mode == MATH_MODE, true, mode == TEXT_MODE);
 
+       // Check if the macro name is encodable. Otherwise we might crash (#11855).
+       docstring const name_in = name();
+       docstring name_recoded;
+       docstring uncodable;
+       for (char_type c : name_in) {
+               if (!os.encoding())
+                       break;
+               if (os.encoding()->encodable(c) || os.output() == TeXMathStream::wsSearchAdv)
+                       name_recoded += c;
+               else {
+                       switch (os.output()) {
+                       case TeXMathStream::wsDryrun: {
+                               os << "<" << _("LyX Warning: ")
+                                  << _("uncodable character") << " '";
+                               os << docstring(1, c);
+                               os << "'>";
+                               break;
+                       }
+                       case TeXMathStream::wsPreview: {
+                               // indicate the encoding error by a boxed '?'
+                               os << "{\\fboxsep=1pt\\fbox{?}}";
+                               LYXERR0("Uncodable character" << " '"
+                                       << docstring(1, c)
+                                       << "'");
+                               break;
+                       }
+                       case TeXMathStream::wsDefault:
+                       default:
+                               // record for error message
+                               uncodable += c;
+                               break;
+                       }
+               }
+       }
+       
+       if (!uncodable.empty()) {
+               frontend::Alert::warning(
+                       _("Uncodable characters in math macro"),
+                       support::bformat(_("The macro name '%1$s' contains a character.\n"
+                                          "that is not encodable in the current encoding (%2$s).\n"
+                                          "Please fix this macro."), name_in, uncodable));
+       }
+
        // non-normal mode
        if (d->displayMode_ != DISPLAY_NORMAL) {
-               os << "\\" << name();
-               if (name().size() != 1 || isAlphaASCII(name()[0]))
+               os << "\\" << name_recoded;
+               if (name_recoded.size() != 1 || isAlphaASCII(name_recoded[0]))
                        os.pendingSpace(true);
                return;
        }
@@ -1162,7 +1207,7 @@ void InsetMathMacro::write(TeXMathStream & os) const
        if (os.fragile())
                os << "\\protect";
 
-       os << "\\" << name();
+       os << "\\" << name_recoded;
        bool first = true;
 
        // Optional arguments: