[evolution] I#884 - Composer: Text split for wrapping can produce invalid UTF-8 text



commit c9706b642e5bb159d74206d4c95b607356277aeb
Author: Milan Crha <mcrha redhat com>
Date:   Thu Apr 30 19:11:08 2020 +0200

    I#884 - Composer: Text split for wrapping can produce invalid UTF-8 text
    
    Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/884

 data/webkit/e-convert.js                 | 16 +++++---
 src/e-util/test-html-editor-units-bugs.c | 70 ++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 5 deletions(-)
---
diff --git a/data/webkit/e-convert.js b/data/webkit/e-convert.js
index 7211fbe022..b4a69cc589 100644
--- a/data/webkit/e-convert.js
+++ b/data/webkit/e-convert.js
@@ -500,10 +500,16 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
                if (worker.useWrapWidth < EvoConvert.MIN_PARAGRAPH_WIDTH)
                        worker.useWrapWidth = EvoConvert.MIN_PARAGRAPH_WIDTH;
 
-               var chr;
-
-               for (ii = 0; ii < str.length; ii++) {
-                       chr = str.charAt(ii);
+               var chr, isHighSurrogate = false;
+
+               for (ii = 0; ii < str.length; ii += 1 + (isHighSurrogate ? 1 : 0)) {
+                       // surrogate are two characters "high+low"; high: 0xD800 - 0xDBFF; low: 0xDC00 - 
0xDFFF
+                       // and cannot split after the high surrogate, because that would break the character 
encoding
+                       isHighSurrogate = str.charCodeAt(ii) >= 0xd800 && str.charCodeAt(ii) <= 0xdbff;
+                       if (isHighSurrogate)
+                               chr = str.substr(ii, 2);
+                       else
+                               chr = str.charAt(ii);
 
                        if (chr == EvoConvert.NOWRAP_CHAR_START)
                                worker.inAnchor++;
@@ -547,7 +553,7 @@ EvoConvert.formatParagraph = function(str, ltr, align, indent, whiteSpace, wrapW
                                if (chr == "\t")
                                        worker.lineLetters = worker.lineLetters - ((worker.lineLetters - 
worker.ignoreLineLetters) % EvoConvert.TAB_WIDTH) + EvoConvert.TAB_WIDTH;
                                else
-                                       worker.lineLetters++;
+                                       worker.lineLetters += chr.length;
 
                                if (chr == EvoConvert.NOWRAP_CHAR_START || chr == EvoConvert.NOWRAP_CHAR_END)
                                        worker.ignoreLineLetters++;
diff --git a/src/e-util/test-html-editor-units-bugs.c b/src/e-util/test-html-editor-units-bugs.c
index e35d2d8a3e..6cf21d4d76 100644
--- a/src/e-util/test-html-editor-units-bugs.c
+++ b/src/e-util/test-html-editor-units-bugs.c
@@ -1617,6 +1617,75 @@ test_issue_107 (TestFixture *fixture)
        }
 }
 
+static void
+test_issue_884 (TestFixture *fixture)
+{
+       if (!test_utils_process_commands (fixture,
+               "mode:plain\n")) {
+               g_test_fail ();
+               return;
+       }
+
+       test_utils_insert_content (fixture,
+               "<div>Xxxxx'x \"Xxxx 🡒 Xxxxxxxx 🡒 Xxxx Xxxxxxxxxx 🡒 Xxxxxxxx xxx xxxxxxxxxx xxxxxxxx\" 
xxxxxxx xxxxx xxxx? Xx xxx, xxxx xx xxxxxxx?</div>"
+               "<div><br></div>"
+               "<div>123456789 123456789 123456789 123456789 123456789 123456789 123456789 123</div>"
+               "<div><br></div>"
+               "<div>🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈"
+               "🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               "<div><br></div>"
+               "<div>a🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               "<div><br></div>"
+               "<div>ab🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               "<div><br></div>"
+               "<div>abc🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               /*"<div><br></div>"
+               "<div>abcd🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒</div>"*/,
+               E_CONTENT_EDITOR_INSERT_REPLACE_ALL | E_CONTENT_EDITOR_INSERT_TEXT_HTML);
+
+       if (!test_utils_run_simple_test (fixture,
+               "",
+               HTML_PREFIX
+               "<div style=\"width: 71ch;\">Xxxxx'x \"Xxxx 🡒 Xxxxxxxx 🡒 Xxxx Xxxxxxxxxx 🡒 Xxxxxxxx xxx 
xxxxxxxxxx xxxxxxxx\" xxxxxxx xxxxx xxxx? Xx xxx, xxxx xx xxxxxxx?</div>"
+               "<div style=\"width: 71ch;\"><br></div>"
+               "<div style=\"width: 71ch;\">123456789 123456789 123456789 123456789 123456789 123456789 
123456789 123</div>"
+               "<div style=\"width: 71ch;\"><br></div>"
+               "<div style=\"width: 71ch;\">🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈"
+               "🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               "<div style=\"width: 71ch;\"><br></div>"
+               "<div style=\"width: 71ch;\">a🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               "<div style=\"width: 71ch;\"><br></div>"
+               "<div style=\"width: 71ch;\">ab🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               "<div style=\"width: 71ch;\"><br></div>"
+               "<div style=\"width: 71ch;\">abc🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈</div>"
+               /*"<div style=\"width: 71ch;\"><br></div>"
+               "<div style=\"width: 71ch;\">abcd🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒</div>"*/
+               HTML_SUFFIX,
+               "Xxxxx'x \"Xxxx 🡒 Xxxxxxxx 🡒 Xxxx Xxxxxxxxxx 🡒 Xxxxxxxx xxx xxxxxxxxxx\n"
+               "xxxxxxxx\" xxxxxxx xxxxx xxxx? Xx xxx, xxxx xx xxxxxxx?\n"
+               "\n"
+               "123456789 123456789 123456789 123456789 123456789 123456789 123456789\n"
+               "123\n"
+               "\n"
+               "🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈\n"
+               "🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈\n"
+               "🐈🐈\n"
+               "\n"
+               "a🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈\n"
+               "🐈🐈🐈\n"
+               "\n"
+               "ab🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈\n"
+               "🐈🐈🐈\n"
+               "\n"
+               "abc🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈🐈\n"
+               "🐈🐈🐈🐈\n"
+               /*"\n"
+               "abcd🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒🡒\n"
+               "🡒🡒🡒\n"*/)) {
+               g_test_fail ();
+       }
+}
+
 void
 test_add_html_editor_bug_tests (void)
 {
@@ -1649,4 +1718,5 @@ test_add_html_editor_bug_tests (void)
        test_utils_add_test ("/issue/103", test_issue_103);
        test_utils_add_test ("/issue/104", test_issue_104);
        test_utils_add_test ("/issue/107", test_issue_107);
+       test_utils_add_test ("/issue/884", test_issue_884);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]