irssi-import / bugs.irssi.org

bugs.irssi.org archive
https://github.com/irssi/irssi/issues
0 stars 0 forks source link

paste_buffer_join_lines() - Mangled text when line length exceeds 400 #905

Closed irssibot closed 8 years ago

irssibot commented 10 years ago

When paste_buffer_join_lines() joins lines together (by replacing newlines with spaces), it does so with a maximum length of 400 characters.

Once this length limit is reached, it will go back to the last position that used to be a newline (now space), insert a newline there, after moving everything after it one position further.

This shifting is done by the memmove() function, which allows moving overlapping areas of memory. However, this appears not to work correctly. The attached text (lorem.txt) will be joined up to the end of the secont to last line ("proident,"), then the new line will read " sunt in clpa qui officia deserunt mo llit anim id est laborum." - The "u" in "culpa" is missing and a space is added in "mollit".

Replacing memmove with an (as far as I can tell) equivalent for-loop (see patch, which also includes the changes to fix issue 904) fixes this problem. But I don't really see why memmove() produces different results?

irssibot commented 10 years ago

lorem.txt

Lorem ipsum dolor sit amet, consectetur adipisici elit, sed
  eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut
  enim ad minim veniam, quis nostrud exercitation ullamco laboris
  nisi ut aliquid ex ea commodi consequat.  Quis aute iure
  reprehenderit in voluptate velit esse cillum dolore eu fugiat
  nulla pariatur. Excepteur sint obcaecat cupiditat non proident,
  sunt in culpa qui officia deserunt mollit anim id est laborum.
irssibot commented 10 years ago

irssi-0.8.16-rc1-gui-readline2.patch

--- irssi-0.8.16-rc1.orig/src/fe-text/gui-readline.c    2013-11-09 09:17:43.000000000 +0100
+++ irssi-0.8.16-rc1/src/fe-text/gui-readline.c 2013-11-09 09:57:42.000000000 +0100
@@ -148,7 +148,7 @@
 static void paste_buffer_join_lines(GArray *buf)
 {
 #define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
-   unsigned int i, count, indent, line_len;
+   unsigned int i, j, count, indent, line_len;
    unichar *arr, *dest, *last_lf_pos;
    int last_lf;

@@ -177,7 +177,7 @@
    if (buf->len == 0)
        return;

-   arr = (unichar *) paste_buffer->data;
+   arr = (unichar *) buf->data;

    /* first line */
    if (IS_WHITE(arr[0]))
@@ -236,8 +236,8 @@
        } else {
            last_lf = FALSE;
            if (++line_len >= 400 && last_lf_pos != NULL) {
-               memmove(last_lf_pos+1, last_lf_pos,
-                   dest - last_lf_pos);
+               for (j = dest - last_lf_pos; j > 0; j--) 
+                   *(last_lf_pos + j) = *(last_lf_pos + j - 1);
                *last_lf_pos = '\n'; last_lf_pos = NULL;
                line_len = 0;
                dest++;
irssibot commented 8 years ago

Resolved in https://github.com/irssi/irssi/pull/292/files