[vte] parser: Accept C0 ST to terminate OSC, DCS



commit ada093ad1f965d90688ef05f33b87f0810570684
Author: Christian Persch <chpe src gnome org>
Date:   Tue Mar 27 19:40:13 2018 +0200

    parser: Accept C0 ST to terminate OSC, DCS
    
    ... as well as the ignored APC, PM, SOS.

 src/parser-test.cc |   57 +++++++++++++------------
 src/parser.cc      |  119 +++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 124 insertions(+), 52 deletions(-)
---
diff --git a/src/parser-test.cc b/src/parser-test.cc
index 72e6767..c2fa3fc 100644
--- a/src/parser-test.cc
+++ b/src/parser-test.cc
@@ -525,7 +525,7 @@ test_seq_control(void)
                 { 0x99, VTE_SEQ_CONTROL, VTE_CMD_NONE    },
                 { 0x9a, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
                 { 0x9b, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
-                { 0x9c, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
+                { 0x9c, VTE_SEQ_CONTROL, VTE_CMD_ST      },
                 { 0x9d, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
                 { 0x9e, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
                 { 0x9f, VTE_SEQ_IGNORE,  VTE_CMD_NONE    },
@@ -978,24 +978,27 @@ test_seq_dcs(uint32_t f,
         b.set_params(params);
         b.set_string(str);
 
-        int expected_rv = (f & 0xF0) == 0x30 ? VTE_SEQ_NONE : VTE_SEQ_DCS;
+        int expected_rv0 = (f & 0xF0) == 0x30 ? VTE_SEQ_ESCAPE /* the C0 ST */ : VTE_SEQ_DCS;
+        int expected_rv1 = (f & 0xF0) == 0x30 ? VTE_SEQ_NONE : VTE_SEQ_DCS;
 
         for (unsigned int n = 0; n <= 16; n++) {
                 b.set_n_params(n);
 
                 vte_parser_reset(parser);
                 struct vte_seq* seq;
-#if 0
+
                 /* First with C0 DCS */
-                auto rv = feed_parser(b, &seq, false);
-                g_assert_cmpint(rv, ==, expected_rv);
-                if (rv != VTE_SEQ_NONE)
+                auto rv0 = feed_parser(b, &seq, false);
+                g_assert_cmpint(rv0, ==, expected_rv0);
+                if (rv0 != VTE_SEQ_ESCAPE)
                         b.assert_equal_full(seq);
-#endif
+                if (rv0 == VTE_SEQ_ESCAPE)
+                        g_assert_cmpint(seq->command, ==, VTE_CMD_ST);
+
                 /* Now with C1 DCS */
-                auto rv = feed_parser(b, &seq, true);
-                g_assert_cmpint(rv, ==, expected_rv);
-                if (rv != VTE_SEQ_NONE)
+                auto rv1 = feed_parser(b, &seq, true);
+                g_assert_cmpint(rv1, ==, expected_rv1);
+                if (rv1 != VTE_SEQ_NONE)
                         b.assert_equal_full(seq);
         }
 }
@@ -1264,25 +1267,23 @@ feed_parser_st(vte_seq_builder& b,
         if (rv == VTE_SEQ_NONE)
                 return rv;
 
-        #if 0
         switch (st) {
-        case ST_NONE:
-                g_assert_cmpuint(seq.terminator(), ==, 0);
+        case vte_seq_builder::VariantST::ST_NONE:
+                g_assert_cmpuint((*seq)->terminator, ==, 0);
                 break;
-        case ST_DEFAULT:
-                g_assert_cmpuint(seq.terminator(), ==, c1 ? 0x9C /* ST */ : 0x50 /* BACKSLASH */);
+        case vte_seq_builder::VariantST::ST_DEFAULT:
+                g_assert_cmpuint((*seq)->terminator, ==, c1 ? 0x9c /* ST */ : 0x5c /* BACKSLASH */);
                 break;
-        case ST_C0:
-                g_assert_cmpuint(seq.terminator(), ==, 0x50 /* BACKSLASH */);
+        case vte_seq_builder::VariantST::ST_C0:
+                g_assert_cmpuint((*seq)->terminator, ==, 0x5c /* BACKSLASH */);
                 break;
-        case ST_C1:
-                g_assert_cmpuint(seq.terminator(), ==, 0x9C /* ST */);
+        case vte_seq_builder::VariantST::ST_C1:
+                g_assert_cmpuint((*seq)->terminator, ==, 0x9c /* ST */);
                 break;
-        case ST_BEL:
-                g_assert_cmpuint(seq.terminator(), ==, 0x7 /* BEL */);
+        case vte_seq_builder::VariantST::ST_BEL:
+                g_assert_cmpuint((*seq)->terminator, ==, 0x7 /* BEL */);
                 break;
         }
-        #endif
 
         return rv;
 }
@@ -1341,12 +1342,12 @@ test_seq_osc(void)
         //        test_seq_osc(std::u32string(VTE_SEQ_STRING_MAX_CAPACITY + 1, 0x100000), seq, VTE_SEQ_NONE);
 
         /* Test all introducer/ST combinations */
-        //        test_seq_osc(U"TEST"s, seq, VTE_SEQ_NONE, false, -1, vte_seq_builder::ST_NONE);
-        //        test_seq_osc(U"TEST"s, seq, VTE_SEQ_NONE, true, -1, vte_seq_builder::ST_NONE);
-        //        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, false, -1, vte_seq_builder::ST_DEFAULT);
-        //        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, true, -1, vte_seq_builder::ST_DEFAULT);
-        //        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, false, -1, vte_seq_builder::ST_C0);
-        //        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, true, -1, vte_seq_builder::ST_C0);
+        test_seq_osc(U"TEST"s, seq, VTE_SEQ_NONE, false, -1, vte_seq_builder::ST_NONE);
+        test_seq_osc(U"TEST"s, seq, VTE_SEQ_NONE, true, -1, vte_seq_builder::ST_NONE);
+        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, false, -1, vte_seq_builder::ST_DEFAULT);
+        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, true, -1, vte_seq_builder::ST_DEFAULT);
+        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, false, -1, vte_seq_builder::ST_C0);
+        test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, true, -1, vte_seq_builder::ST_C0);
         test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, false, -1, vte_seq_builder::ST_C1);
         test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, true, -1, vte_seq_builder::ST_C1);
         test_seq_osc(U"TEST"s, seq, VTE_SEQ_OSC, false, -1, vte_seq_builder::ST_BEL);
diff --git a/src/parser.cc b/src/parser.cc
index eaa648f..b4792dd 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -932,6 +932,8 @@ static unsigned int vte_parse_host_sci(const struct vte_seq *seq)
 enum parser_state {
         STATE_NONE,             /* placeholder */
         STATE_GROUND,           /* initial state and ground */
+        STATE_DCS_PASS_ESC,     /* ESC after DCS which may be ESC \ aka C0 ST */
+        STATE_OSC_STRING_ESC,   /* ESC after OSC which may be ESC \ aka C0 ST */
         STATE_ESC,              /* ESC sequence was started */
         STATE_ESC_INT,          /* intermediate escape characters */
         STATE_CSI_ENTRY,        /* starting CSI sequence */
@@ -1283,23 +1285,45 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                  */
         case STATE_GROUND:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
-                case 0x80 ... 0x9b:        /* C1 \ { ST } */
-                case 0x9d ... 0x9f:
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
+                case 0x80 ... 0x9f:        /* C1 */
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_EXECUTE);
-                case 0x9c:                /* ST */
-                        return parser_transition(parser, raw, STATE_NONE,
-                                                 ACTION_IGNORE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 }
 
                 return parser_transition(parser, raw,
                                          STATE_NONE, ACTION_PRINT);
+
+        case STATE_DCS_PASS_ESC:
+        case STATE_OSC_STRING_ESC:
+                if (raw == 0x5c /* '\' */) {
+                        switch (parser->state) {
+                        case STATE_DCS_PASS_ESC:
+                                return parser_transition(parser, raw, STATE_GROUND,
+                                                         ACTION_DCS_DISPATCH);
+                        case STATE_OSC_STRING_ESC:
+                                return parser_transition(parser, raw, STATE_GROUND,
+                                                         ACTION_OSC_DISPATCH);
+                        }
+                }
+
+                /* Do the deferred clear and fallthrough to STATE_ESC */
+                parser_transition(parser, 0x1b /* ESC */, STATE_ESC,
+                                  ACTION_CLEAR);
+                /* fallthrough */
         case STATE_ESC:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_EXECUTE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_ESC_INT,
                                                  ACTION_COLLECT);
@@ -1339,9 +1363,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_ESC_INT, ACTION_COLLECT);
         case STATE_ESC_INT:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_EXECUTE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_COLLECT);
@@ -1360,9 +1388,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_NONE, ACTION_COLLECT);
         case STATE_CSI_ENTRY:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_EXECUTE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_CSI_INT,
                                                  ACTION_COLLECT);
@@ -1388,9 +1420,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_CSI_IGNORE, ACTION_NONE);
         case STATE_CSI_PARAM:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_EXECUTE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_CSI_INT,
                                                  ACTION_COLLECT);
@@ -1416,9 +1452,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_CSI_IGNORE, ACTION_NONE);
         case STATE_CSI_INT:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_EXECUTE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_COLLECT);
@@ -1440,9 +1480,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_CSI_IGNORE, ACTION_NONE);
         case STATE_CSI_IGNORE:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_EXECUTE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x3f:        /* [' ' - '?'] */
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_NONE);
@@ -1461,9 +1505,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_NONE, ACTION_NONE);
         case STATE_DCS_ENTRY:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ ESC */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_IGNORE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_DCS_INT,
                                                  ACTION_COLLECT);
@@ -1489,9 +1537,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_DCS_PASS, ACTION_DCS_CONSUME);
         case STATE_DCS_PARAM:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_IGNORE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_DCS_INT,
                                                  ACTION_COLLECT);
@@ -1517,9 +1569,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_DCS_PASS, ACTION_DCS_CONSUME);
         case STATE_DCS_INT:
                 switch (raw) {
-                case 0x00 ... 0x1f:        /* C0 */
+                case 0x00 ... 0x1a:        /* C0 \ { ESC } */
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_IGNORE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x20 ... 0x2f:        /* [' ' - '\'] */
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_COLLECT);
@@ -1541,9 +1597,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_DCS_PASS, ACTION_DCS_CONSUME);
         case STATE_DCS_PASS:
                 switch (raw) {
-                case 0x00 ... 0x7e:        /* ASCII \ { DEL } */
+                case 0x00 ... 0x1a:        /* ASCII \ { ESC, DEL } */
+                case 0x1c ... 0x7e:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_DCS_COLLECT);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_DCS_PASS_ESC,
+                                                 ACTION_NONE);
                 case 0x7f:                /* DEL */
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_IGNORE);
@@ -1556,9 +1616,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_NONE, ACTION_DCS_COLLECT);
         case STATE_DCS_IGNORE:
                 switch (raw) {
-                case 0x00 ... 0x7f:        /* ASCII */
+                case 0x00 ... 0x1a:        /* ASCII \ { ESC } */
+                case 0x1c ... 0x7f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_IGNORE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x9c:                /* ST */
                         return parser_transition(parser, raw, STATE_GROUND,
                                                  ACTION_NONE);
@@ -1568,10 +1632,14 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_NONE, ACTION_NONE);
         case STATE_OSC_STRING:
                 switch (raw) {
-                case 0x00 ... 0x06:        /* C0 \ { BEL } */
-                case 0x08 ... 0x1f:
+                case 0x00 ... 0x06:        /* C0 \ { BEL, ESC } */
+                case 0x08 ... 0x1a:
+                case 0x1c ... 0x1f:
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_IGNORE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_OSC_STRING_ESC,
+                                                 ACTION_NONE);
                 case 0x20 ... 0x7f:        /* [' ' - DEL] */
                         return parser_transition(parser, raw, STATE_NONE,
                                                  ACTION_OSC_COLLECT);
@@ -1585,9 +1653,13 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_NONE, ACTION_OSC_COLLECT);
         case STATE_ST_IGNORE:
                 switch (raw) {
-                case 0x00 ... 0x7f:        /* ASCII */
+                case 0x00 ... 0x1a:        /* ASCII \ { ESC } */
+                case 0x1c ... 0x7f:
                         return parser_transition(parser, raw,
                                                  STATE_NONE, ACTION_IGNORE);
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw, STATE_ESC,
+                                                 ACTION_CLEAR);
                 case 0x9c:                /* ST */
                         return parser_transition(parser, raw,
                                                  STATE_GROUND, ACTION_IGNORE);
@@ -1597,6 +1669,9 @@ static int parser_feed_to_state(struct vte_parser *parser, uint32_t raw)
                                          STATE_NONE, ACTION_NONE);
         case STATE_SCI:
                 switch (raw) {
+                case 0x1b:                /* ESC */
+                        return parser_transition(parser, raw,
+                                                 STATE_ESC, ACTION_CLEAR);
                 case 0x08 ... 0x0d:        /* BS, HT, LF, VT, FF, CR */
                 case 0x20 ... 0x7e:        /* [' ' - '~'] */
                         return parser_transition(parser, raw, STATE_GROUND,
@@ -1644,10 +1719,6 @@ int vte_parser_feed(struct vte_parser *parser,
                 ret = parser_transition(parser, raw,
                                         STATE_GROUND, ACTION_EXECUTE);
                 break;
-        case 0x1b:                /* ESC */
-                ret = parser_transition(parser, raw,
-                                        STATE_ESC, ACTION_CLEAR);
-                break;
         case 0x98:                /* SOS */
         case 0x9e:                /* PM */
         case 0x9f:                /* APC */


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