]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - terminal.c
Merge tag '0.66'
[PuTTY.git] / terminal.c
index ca47c8335f79eabaf581bd71b8b55f28b8718ee6..c5fdeeb0245643a3c9584211f7664505e9b23761 100644 (file)
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <limits.h>
 
 #include <time.h>
 #include <assert.h>
@@ -2343,7 +2344,7 @@ static void check_boundary(Terminal *term, int x, int y)
     termline *ldata;
 
     /* Validate input coordinates, just in case. */
-    if (x == 0 || x > term->cols)
+    if (x <= 0 || x > term->cols)
        return;
 
     ldata = scrlineptr(y);
@@ -3493,8 +3494,15 @@ static void term_out(Terminal *term)
                    if (term->esc_nargs <= ARGS_MAX) {
                        if (term->esc_args[term->esc_nargs - 1] == ARG_DEFAULT)
                            term->esc_args[term->esc_nargs - 1] = 0;
-                       term->esc_args[term->esc_nargs - 1] =
-                           10 * term->esc_args[term->esc_nargs - 1] + c - '0';
+                       if (term->esc_args[term->esc_nargs - 1] <=
+                           UINT_MAX / 10 &&
+                           term->esc_args[term->esc_nargs - 1] * 10 <=
+                           UINT_MAX - c - '0')
+                           term->esc_args[term->esc_nargs - 1] =
+                               10 * term->esc_args[term->esc_nargs - 1] +
+                               c - '0';
+                       else
+                           term->esc_args[term->esc_nargs - 1] = UINT_MAX;
                    }
                    term->termstate = SEEN_CSI;
                } else if (c == ';') {
@@ -3510,8 +3518,10 @@ static void term_out(Terminal *term)
                        term->esc_query = c;
                    term->termstate = SEEN_CSI;
                } else
+#define CLAMP(arg, lim) ((arg) = ((arg) > (lim)) ? (lim) : (arg))
                    switch (ANSI(c, term->esc_query)) {
                      case 'A':       /* CUU: move up N lines */
+                       CLAMP(term->esc_args[0], term->rows);
                        move(term, term->curs.x,
                             term->curs.y - def(term->esc_args[0], 1), 1);
                        seen_disp_event(term);
@@ -3520,6 +3530,7 @@ static void term_out(Terminal *term)
                        compatibility(ANSI);
                        /* FALLTHROUGH */
                      case 'B':         /* CUD: Cursor down */
+                       CLAMP(term->esc_args[0], term->rows);
                        move(term, term->curs.x,
                             term->curs.y + def(term->esc_args[0], 1), 1);
                        seen_disp_event(term);
@@ -3535,23 +3546,27 @@ static void term_out(Terminal *term)
                        compatibility(ANSI);
                        /* FALLTHROUGH */
                      case 'C':         /* CUF: Cursor right */ 
+                       CLAMP(term->esc_args[0], term->cols);
                        move(term, term->curs.x + def(term->esc_args[0], 1),
                             term->curs.y, 1);
                        seen_disp_event(term);
                        break;
                      case 'D':       /* CUB: move left N cols */
+                       CLAMP(term->esc_args[0], term->cols);
                        move(term, term->curs.x - def(term->esc_args[0], 1),
                             term->curs.y, 1);
                        seen_disp_event(term);
                        break;
                      case 'E':       /* CNL: move down N lines and CR */
                        compatibility(ANSI);
+                       CLAMP(term->esc_args[0], term->rows);
                        move(term, 0,
                             term->curs.y + def(term->esc_args[0], 1), 1);
                        seen_disp_event(term);
                        break;
                      case 'F':       /* CPL: move up N lines and CR */
                        compatibility(ANSI);
+                       CLAMP(term->esc_args[0], term->rows);
                        move(term, 0,
                             term->curs.y - def(term->esc_args[0], 1), 1);
                        seen_disp_event(term);
@@ -3559,12 +3574,14 @@ static void term_out(Terminal *term)
                      case 'G':       /* CHA */
                      case '`':       /* HPA: set horizontal posn */
                        compatibility(ANSI);
+                       CLAMP(term->esc_args[0], term->cols);
                        move(term, def(term->esc_args[0], 1) - 1,
                             term->curs.y, 0);
                        seen_disp_event(term);
                        break;
                      case 'd':       /* VPA: set vertical posn */
                        compatibility(ANSI);
+                       CLAMP(term->esc_args[0], term->rows);
                        move(term, term->curs.x,
                             ((term->dec_om ? term->marg_t : 0) +
                              def(term->esc_args[0], 1) - 1),
@@ -3575,6 +3592,8 @@ static void term_out(Terminal *term)
                      case 'f':      /* HVP: set horz and vert posns at once */
                        if (term->esc_nargs < 2)
                            term->esc_args[1] = ARG_DEFAULT;
+                       CLAMP(term->esc_args[0], term->rows);
+                       CLAMP(term->esc_args[1], term->cols);
                        move(term, def(term->esc_args[1], 1) - 1,
                             ((term->dec_om ? term->marg_t : 0) +
                              def(term->esc_args[0], 1) - 1),
@@ -3610,6 +3629,7 @@ static void term_out(Terminal *term)
                        break;
                      case 'L':       /* IL: insert lines */
                        compatibility(VT102);
+                       CLAMP(term->esc_args[0], term->rows);
                        if (term->curs.y <= term->marg_b)
                            scroll(term, term->curs.y, term->marg_b,
                                   -def(term->esc_args[0], 1), FALSE);
@@ -3617,6 +3637,7 @@ static void term_out(Terminal *term)
                        break;
                      case 'M':       /* DL: delete lines */
                        compatibility(VT102);
+                       CLAMP(term->esc_args[0], term->rows);
                        if (term->curs.y <= term->marg_b)
                            scroll(term, term->curs.y, term->marg_b,
                                   def(term->esc_args[0], 1),
@@ -3626,11 +3647,13 @@ static void term_out(Terminal *term)
                      case '@':       /* ICH: insert chars */
                        /* XXX VTTEST says this is vt220, vt510 manual says vt102 */
                        compatibility(VT102);
+                       CLAMP(term->esc_args[0], term->cols);
                        insch(term, def(term->esc_args[0], 1));
                        seen_disp_event(term);
                        break;
                      case 'P':       /* DCH: delete chars */
                        compatibility(VT102);
+                       CLAMP(term->esc_args[0], term->cols);
                        insch(term, -def(term->esc_args[0], 1));
                        seen_disp_event(term);
                        break;
@@ -3708,6 +3731,8 @@ static void term_out(Terminal *term)
                        compatibility(VT100);
                        if (term->esc_nargs <= 2) {
                            int top, bot;
+                           CLAMP(term->esc_args[0], term->rows);
+                           CLAMP(term->esc_args[1], term->rows);
                            top = def(term->esc_args[0], 1) - 1;
                            bot = (term->esc_nargs <= 1
                                   || term->esc_args[1] == 0 ?
@@ -4063,6 +4088,7 @@ static void term_out(Terminal *term)
                        }
                        break;
                      case 'S':         /* SU: Scroll up */
+                       CLAMP(term->esc_args[0], term->rows);
                        compatibility(SCOANSI);
                        scroll(term, term->marg_t, term->marg_b,
                               def(term->esc_args[0], 1), TRUE);
@@ -4070,6 +4096,7 @@ static void term_out(Terminal *term)
                        seen_disp_event(term);
                        break;
                      case 'T':         /* SD: Scroll down */
+                       CLAMP(term->esc_args[0], term->rows);
                        compatibility(SCOANSI);
                        scroll(term, term->marg_t, term->marg_b,
                               -def(term->esc_args[0], 1), TRUE);
@@ -4112,6 +4139,7 @@ static void term_out(Terminal *term)
                        /* XXX VTTEST says this is vt220, vt510 manual
                         * says vt100 */
                        compatibility(ANSIMIN);
+                       CLAMP(term->esc_args[0], term->cols);
                        {
                            int n = def(term->esc_args[0], 1);
                            pos cursplus;
@@ -4145,6 +4173,7 @@ static void term_out(Terminal *term)
                        break;
                      case 'Z':         /* CBT */
                        compatibility(OTHER);
+                       CLAMP(term->esc_args[0], term->cols);
                        {
                            int i = def(term->esc_args[0], 1);
                            pos old_curs = term->curs;
@@ -4205,7 +4234,7 @@ static void term_out(Terminal *term)
                        break;
                      case ANSI('F', '='):      /* set normal foreground */
                        compatibility(SCOANSI);
-                       if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
+                       if (term->esc_args[0] < 16) {
                            long colour =
                                (sco2ansicolour[term->esc_args[0] & 0x7] |
                                 (term->esc_args[0] & 0x8)) <<
@@ -4219,7 +4248,7 @@ static void term_out(Terminal *term)
                        break;
                      case ANSI('G', '='):      /* set normal background */
                        compatibility(SCOANSI);
-                       if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
+                       if (term->esc_args[0] < 16) {
                            long colour =
                                (sco2ansicolour[term->esc_args[0] & 0x7] |
                                 (term->esc_args[0] & 0x8)) <<
@@ -4343,7 +4372,11 @@ static void term_out(Terminal *term)
                  case '7':
                  case '8':
                  case '9':
-                   term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
+                   if (term->esc_args[0] <= UINT_MAX / 10 &&
+                       term->esc_args[0] * 10 <= UINT_MAX - c - '0')
+                       term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
+                   else
+                       term->esc_args[0] = UINT_MAX;
                    break;
                  case 'L':
                    /*
@@ -4425,7 +4458,11 @@ static void term_out(Terminal *term)
                  case '7':
                  case '8':
                  case '9':
-                   term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
+                   if (term->esc_args[0] <= UINT_MAX / 10 &&
+                       term->esc_args[0] * 10 <= UINT_MAX - c - '0')
+                       term->esc_args[0] = 10 * term->esc_args[0] + c - '0';
+                   else
+                       term->esc_args[0] = UINT_MAX;
                    break;
                  default:
                    term->termstate = OSC_STRING;