Don't crash on very long inputs
[quassel.git] / src / uisupport / uistyle.cpp
index 6bd8494..8228b8f 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-2012 by the Quassel Project                        *
+ *   Copyright (C) 2005-2014 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -491,12 +491,16 @@ QList<QTextLayout::FormatRange> UiStyle::toTextLayoutList(const FormatList &form
 UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat)
 {
     QString s = s_;
+    StyledString result;
+    result.formatList.append(qMakePair((quint16)0, baseFormat));
+
     if (s.length() > 65535) {
+        // We use quint16 for indexes
         qWarning() << QString("String too long to be styled: %1").arg(s);
-        return StyledString();
+        result.plainText = s;
+        return result;
     }
-    StyledString result;
-    result.formatList.append(qMakePair((quint16)0, baseFormat));
+
     quint32 curfmt = baseFormat;
     int pos = 0; quint16 length = 0;
     for (;;) {
@@ -561,15 +565,42 @@ UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat
 
 QString UiStyle::mircToInternal(const QString &mirc_)
 {
-    QString mirc = mirc_;
-    mirc.replace('%', "%%");    // escape % just to be sure
-    mirc.replace('\t', "        ");    // tabs break layout, also this is italics in Konversation
-    mirc.replace('\x02', "%B");
-    mirc.replace('\x0f', "%O");
-    mirc.replace('\x12', "%R");
-    mirc.replace('\x16', "%R");
-    mirc.replace('\x1d', "%S");
-    mirc.replace('\x1f', "%U");
+    QString mirc;
+    mirc.reserve(mirc_.size());
+    foreach (const QChar &c, mirc_) {
+        if ((c < '\x20' || c == '\x7f') && c != '\x03') {
+            switch (c.unicode()) {
+                case '\x02':
+                    mirc += "%B";
+                    break;
+                case '\x0f':
+                    mirc += "%O";
+                    break;
+                case '\x09':
+                    mirc += "        ";
+                    break;
+                case '\x12':
+                case '\x16':
+                    mirc += "%R";
+                    break;
+                case '\x1d':
+                    mirc += "%S";
+                    break;
+                case '\x1f':
+                    mirc += "%U";
+                    break;
+                case '\x7f':
+                    mirc += QChar(0x2421);
+                    break;
+                default:
+                    mirc += QChar(0x2400 + c.unicode());
+            }
+        } else {
+            if (c == '%')
+                mirc += c;
+            mirc += c;
+        }
+    }
 
     // Now we bring the color codes (\x03) in a sane format that can be parsed more easily later.
     // %Dcfxx is foreground, %Dcbxx is background color, where xx is a 2 digit dec number denoting the color code.
@@ -687,8 +718,10 @@ void UiStyle::StyledMessage::style() const
         //: Error Message
         t = tr("%1").arg(txt); break;
     case Message::DayChange:
+    {
         //: Day Change Message
-        t = tr("{Day changed to %1}").arg(timestamp().toString());
+        t = tr("{Day changed to %1}").arg(timestamp().date().toString(Qt::DefaultLocaleLongDate));
+    }
         break;
     case Message::Topic:
         //: Topic Message