Commit message: tame some window operations, just in case
CVE: CVE-2021-28848
CWE: CWE-703
Vulnerability description: Mintty before 3.4.5 allows remote servers to cause a denial of service (Windows GUI hang) by telling the Mintty window to change its title repeatedly at high speed, which results in many SetWindowTextA or SetWindowTextW calls. In other words, it does not implement a usleep or similar delay upon processing a title change.

Project: mintty
File: termout.c

do_winop(void)
{
  int arg1 = term.csi_argv[1], arg2 = term.csi_argv[2];
  if (*cfg.suppress_win && contains(cfg.suppress_win, term.csi_argv[0]))
    // skip suppressed window operation
    return;
  switch (term.csi_argv[0]) {
    when 1: win_set_iconic(false);
    when 2: win_set_iconic(true);
    when 3: win_set_pos(arg1, arg2);
    when 4: win_set_pixels(arg1, arg2);
    when 5:
      if (term.csi_argc != 1)
        return;
      win_set_zorder(true);  // top
    when 6:
      if (term.csi_argc != 1)
        return;
      win_set_zorder(false); // bottom
    when 7: win_invalidate_all(false);  // refresh
    when 8: {
      int def1 = term.csi_argv_defined[1], def2 = term.csi_argv_defined[2];
      int rows, cols;
      win_get_screen_chars(&rows, &cols);
      win_set_chars(arg1 ?: def1 ? rows : term.rows, arg2 ?: def2 ? cols : term.cols);
    }
    when 9: {
      if (term.csi_argc != 2)
        return;
      // Ps = 9 ; 0  -> Restore maximized window.
      // Ps = 9 ; 1  -> Maximize window (i.e., resize to screen size).
      // Ps = 9 ; 2  -> Maximize window vertically.
      // Ps = 9 ; 3  -> Maximize window horizontally.
      int rows0 = term.rows0, cols0 = term.cols0;
      if (arg1 == 2) {
        // maximize window vertically
        win_set_geom(0, -1, 0, -1);
        term.rows0 = rows0; term.cols0 = cols0;
      }
      else if (arg1 == 3) {
        // maximize window horizontally
        win_set_geom(-1, 0, -1, 0);
        term.rows0 = rows0; term.cols0 = cols0;
      }
      else if (arg1 == 1) {
        win_maximise(1);
        term.rows0 = rows0; term.cols0 = cols0;
      }
      else if (arg1 == 0) {
        win_maximise(0);
        win_set_chars(rows0, cols0);
      }
    }
    when 10:
      if (term.csi_argc != 2)
        return;
      // Ps = 1 0 ; 0  -> Undo full-screen mode.
      // Ps = 1 0 ; 1  -> Change to full-screen.
      // Ps = 1 0 ; 2  -> Toggle full-screen.
      if (arg1 == 2)
        win_maximise(-2);
      else if (arg1 == 1 || arg1 == 0)
        win_maximise(arg1 ? 2 : 0);
    when 11: child_write(win_is_iconic() ? "\e[2t" : "\e[1t", 4);
    when 13: {
      int x, y;
      win_get_scrpos(&x, &y, arg1 == 2);
      child_printf("\e[3;%u;%ut", (ushort)x, (ushort)y);
    }
    when 14: {
      int height, width;
      win_get_pixels(&height, &width, arg1 == 2);
      child_printf("\e[4;%d;%dt", height, width);
    }
    when 15: {
      int w, h;
      search_monitors(&w, &h, 0, false, 0);
      child_printf("\e[5;%d;%dt", h, w);
    }
    when 16: child_printf("\e[6;%d;%dt", cell_height, cell_width);
    when 18: child_printf("\e[8;%d;%dt", term.rows, term.cols);
    when 19: {
#ifdef size_of_monitor_only
#warning not what xterm reports
      int rows, cols;
      win_get_screen_chars(&rows, &cols);
      child_printf("\e[9;%d;%dt", rows, cols);
#else
      int w, h;
      search_monitors(&w, &h, 0, false, 0);
      child_printf("\e[9;%d;%dt", h / cell_height, w / cell_width);
#endif
    }
    when 22:
      if (arg1 == 0 || arg1 == 2)
        win_save_title();
    when 23:
      if (arg1 == 0 || arg1 == 2)
        win_restore_title();
  }
}