[vte] emulation: Clamp cursor column



commit 21e79fd3642809bf626b52dc2a67af33a6711115
Author: Christian Persch <chpe src gnome org>
Date:   Thu Aug 9 21:56:22 2018 +0200

    emulation: Clamp cursor column
    
    When setting/unsetting tab stops, make sure to clamp the cursor
    column to 0..m_column_count-1. This is necessary because vte's
    weird autowrap handling where it puts the cursor on column
    m_column_count if there's a wrap pending, instead of keeping
    the cursor at the right margin and using a flag, like every other
    terminal emulator does.
    
    Fixes a crash when setting/unsetting a tabstop while the cursor
    is in that pending autowrap state.

 src/vteinternal.hh |  8 ++++++--
 src/vteseq.cc      | 23 +++++++++++------------
 2 files changed, 17 insertions(+), 14 deletions(-)
---
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 28e336e7..31cbe476 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -1236,14 +1236,18 @@ public:
         inline void delete_character();
         inline void set_cursor_column(vte::grid::column_t col);
         inline void set_cursor_column1(vte::grid::column_t col); /* 1-based */
+        inline int get_cursor_column() const noexcept { return CLAMP(m_screen->cursor.col, 0, m_column_count 
- 1); }
+        inline int get_cursor_column1() const noexcept { return get_cursor_column() + 1; }
         inline void set_cursor_row(vte::grid::row_t row /* relative to scrolling region */);
         inline void set_cursor_row1(vte::grid::row_t row /* relative to scrolling region */); /* 1-based */
+        inline int get_cursor_row() const noexcept { return CLAMP(m_screen->cursor.row, 0, m_row_count - 1); 
}
+        inline int get_cursor_row1() const noexcept { return get_cursor_row() + 1; }
         inline void set_cursor_coords(vte::grid::row_t row /* relative to scrolling region */,
                                       vte::grid::column_t column);
         inline void set_cursor_coords1(vte::grid::row_t row /* relative to scrolling region */,
                                        vte::grid::column_t column); /* 1-based */
-        inline vte::grid::row_t get_cursor_row() const;
-        inline vte::grid::column_t get_cursor_column() const;
+        inline vte::grid::row_t get_cursor_row_unclamped() const;
+        inline vte::grid::column_t get_cursor_column_unclamped() const;
         inline void move_cursor_up(vte::grid::row_t rows);
         inline void move_cursor_down(vte::grid::row_t rows);
         inline void erase_characters(long count);
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 46f0b606..ebe0d37e 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -837,7 +837,7 @@ Terminal::set_cursor_row1(vte::grid::row_t row)
  * if set (regardless of origin mode).
  */
 vte::grid::row_t
-Terminal::get_cursor_row() const
+Terminal::get_cursor_row_unclamped() const
 {
         auto row = m_screen->cursor.row - m_screen->insert_delta;
         /* Note that we do NOT check DEC_ORIGIN mode here! */
@@ -848,7 +848,7 @@ Terminal::get_cursor_row() const
 }
 
 vte::grid::column_t
-Terminal::get_cursor_column() const
+Terminal::get_cursor_column_unclamped() const
 {
         return m_screen->cursor.col;
 }
@@ -991,7 +991,7 @@ Terminal::move_cursor_backward(vte::grid::column_t columns)
 {
         ensure_cursor_is_onscreen();
 
-        auto col = get_cursor_column();
+        auto col = get_cursor_column_unclamped();
         columns = CLAMP(columns, 1, col);
         set_cursor_column(col - columns);
 }
@@ -1004,7 +1004,7 @@ Terminal::move_cursor_forward(vte::grid::column_t columns)
         ensure_cursor_is_onscreen();
 
         /* The cursor can be further to the right, don't move in that case. */
-        auto col = get_cursor_column();
+        auto col = get_cursor_column_unclamped();
         if (col < m_column_count) {
                /* There's room to move right. */
                 set_cursor_column(col + columns);
@@ -1024,7 +1024,7 @@ Terminal::move_cursor_tab_backward(int count)
         if (count == 0)
                 return;
 
-        auto const newcol = m_tabstops.get_previous(m_screen->cursor.col, count, 0);
+        auto const newcol = m_tabstops.get_previous(get_cursor_column(), count, 0);
         set_cursor_column(newcol);
 }
 
@@ -1034,11 +1034,10 @@ Terminal::move_cursor_tab_forward(int count)
         if (count == 0)
                 return;
 
-        auto const col = m_screen->cursor.col;
-       g_assert (col >= 0);
+        auto const col = get_cursor_column();
 
        /* Find the next tabstop, but don't go beyond the end of the line */
-        auto const newcol = m_tabstops.get_next(col, count, m_column_count - 1);
+        int const newcol = m_tabstops.get_next(col, count, m_column_count - 1);
 
        /* Make sure we don't move cursor back (see bug #340631) */
         // FIXMEchpe how could this happen!?
@@ -2005,7 +2004,7 @@ Terminal::CTC(vte::parser::Sequence const& seq)
         case -1:
         case 0:
                 /* Set tabstop at the current cursor position */
-                m_tabstops.set(m_screen->cursor.col);
+                m_tabstops.set(get_cursor_column());
                 break;
 
         case 1:
@@ -2014,7 +2013,7 @@ Terminal::CTC(vte::parser::Sequence const& seq)
 
         case 2:
                 /* Clear tabstop at the current cursor position */
-                m_tabstops.unset(m_screen->cursor.col);
+                m_tabstops.unset(get_cursor_column());
                 break;
 
         case 3:
@@ -5758,7 +5757,7 @@ Terminal::HTS(vte::parser::Sequence const& seq)
          *             VT525
          */
 
-        m_tabstops.set(m_screen->cursor.col);
+        m_tabstops.set(get_cursor_column());
 }
 
 void
@@ -7674,7 +7673,7 @@ Terminal::TBC(vte::parser::Sequence const& seq)
         case -1:
         case 0:
                 /* Clear character tabstop at the current presentation position */
-                m_tabstops.unset(m_screen->cursor.col);
+                m_tabstops.unset(get_cursor_column());
                 break;
         case 1:
                 /* Clear line tabstop at the current line */


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