Fix the line-resizing bug in scroll(). (Thanks to RDB for pointing
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 17 May 2001 08:53:13 +0000 (08:53 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 17 May 2001 08:53:13 +0000 (08:53 +0000)
it out. A line was removed from the scrollback, cleared, and placed
at the bottom of the screen. Fine, except that the clearing process
assumed the line was the right length already, and thanks to lazy
resizing this wasn't necessarily the case. Segfaults and memory
corruption ensued.)

git-svn-id: svn://svn.tartarus.org/sgt/putty@1129 cda61777-01e9-0310-a592-d414129be87e

terminal.c

index cf55f8e..7fb2029 100644 (file)
@@ -201,15 +201,40 @@ static FILE *lgfp = NULL;
 static void logtraffic(unsigned char c, int logmode);
 
 /*
+ * Resize a line to make it `cols' columns wide.
+ */
+unsigned long *resizeline(unsigned long *line, int cols)
+{
+    int i, oldlen;
+    unsigned long lineattrs;
+
+    if (line[0] != (unsigned long)cols) {
+       /*
+        * This line is the wrong length, which probably means it
+        * hasn't been accessed since a resize. Resize it now.
+        */
+       oldlen = line[0];
+       lineattrs = line[oldlen + 1];
+       line = srealloc(line, TSIZE * (2 + cols));
+       line[0] = cols;
+       for (i = oldlen; i < cols; i++)
+           line[i + 1] = ERASE_CHAR;
+       line[cols + 1] = lineattrs & LATTR_MODE;
+    }
+
+    return line;
+}
+
+/*
  * Retrieve a line of the screen or of the scrollback, according to
  * whether the y coordinate is non-negative or negative
  * (respectively).
  */
 unsigned long *lineptr(int y, int lineno)
 {
-    unsigned long *line, lineattrs;
+    unsigned long *line, *newline;
     tree234 *whichtree;
-    int i, treeindex, oldlen;
+    int treeindex;
 
     if (y >= 0) {
        whichtree = screen;
@@ -223,20 +248,10 @@ unsigned long *lineptr(int y, int lineno)
     /* We assume that we don't screw up and retrieve something out of range. */
     assert(line != NULL);
 
-    if (line[0] != cols) {
-       /*
-        * This line is the wrong length, which probably means it
-        * hasn't been accessed since a resize. Resize it now.
-        */
-       oldlen = line[0];
-       lineattrs = line[oldlen + 1];
+    newline = resizeline(line, cols);
+    if (newline != line) {
        delpos234(whichtree, treeindex);
-       line = srealloc(line, TSIZE * (2 + cols));
-       line[0] = cols;
-       for (i = oldlen; i < cols; i++)
-           line[i + 1] = ERASE_CHAR;
-       line[cols + 1] = lineattrs & LATTR_MODE;
-       addpos234(whichtree, line, treeindex);
+       addpos234(whichtree, newline, treeindex);
     }
 
     return line + 1;
@@ -568,6 +583,7 @@ static void scroll(int topline, int botline, int lines, int sb)
     if (lines < 0) {
        while (lines < 0) {
            line = delpos234(screen, botline);
+            line = resizeline(line, cols);
            for (i = 0; i < cols; i++)
                line[i + 1] = erase_char;
            line[cols + 1] = 0;
@@ -610,6 +626,7 @@ static void scroll(int topline, int botline, int lines, int sb)
                addpos234(scrollback, line, sblen);
                line = line2;
            }
+            line = resizeline(line, cols);
            for (i = 0; i < cols; i++)
                line[i + 1] = erase_char;
            line[cols + 1] = 0;