Emit NORMAL at newlines, like less, to deal with malformed input.
---
Fits a little akwardly into the output flow with a break and continue,
but it works.

 miscutils/less.c | 54 +++++++++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 24 deletions(-)

diff --git a/miscutils/less.c b/miscutils/less.c
index 8a0525cb7..392a3ef3c 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -139,7 +139,7 @@
 //usage:     "\n       -S      Truncate long lines"
 //usage:       )
 //usage:       IF_FEATURE_LESS_RAW(
-//usage:     "\n       -R      Remove color escape codes in input"
+//usage:     "\n       -R      Keep ANSI color escape codes in input"
 //usage:       )
 //usage:     "\n       -~      Suppress ~s displayed past EOF"
 
@@ -229,9 +229,6 @@ struct globals {
        regex_t pattern;
        smallint pattern_valid;
 #endif
-#if ENABLE_FEATURE_LESS_RAW
-       smallint in_escape;
-#endif
 #if ENABLE_FEATURE_LESS_ASK_TERMINAL
        smallint winsize_err;
 #endif
@@ -541,26 +538,6 @@ static void read_lines(void)
                                *--p = '\0';
                                continue;
                        }
-#if ENABLE_FEATURE_LESS_RAW
-                       if (option_mask32 & FLAG_R) {
-                               if (c == '\033')
-                                       goto discard;
-                               if (G.in_escape) {
-                                       if (isdigit(c)
-                                        || c == '['
-                                        || c == ';'
-                                        || c == 'm'
-                                       ) {
- discard:
-                                               G.in_escape = (c != 'm');
-                                               readpos++;
-                                               continue;
-                                       }
-                                       /* Hmm, unexpected end of "ESC [ N ; N 
m" sequence */
-                                       G.in_escape = 0;
-                               }
-                       }
-#endif
                        {
                                size_t new_last_line_pos = last_line_pos + 1;
                                if (c == '\t') {
@@ -780,6 +757,7 @@ static const char ctrlconv[] ALIGN1 =
         * '\n' is a former NUL - we subst it with @, not J */
        "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f"
        "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f";
+static const char colctrl[] ALIGN1 = "\x1b[0123456789;m";
 
 static void print_lineno(const char *line)
 {
@@ -864,13 +842,32 @@ static void print_found(const char *line)
 void print_found(const char *line);
 #endif
 
+static size_t count_colctrl(const char *str) {
+       size_t n = strspn(str, colctrl);
+       // must end with m, need at least '<ESC>[m'
+       if (n < 3 || *(str+n-1) != 'm')
+               return 0;
+       return n;
+}
+
 static void print_ascii(const char *str)
 {
        char buf[width+1];
        char *p;
        size_t n;
+#if ENABLE_FEATURE_LESS_RAW
+       size_t esc = 0;
+#endif
 
        while (*str) {
+#if ENABLE_FEATURE_LESS_RAW
+               if (esc) {
+                       printf("%.*s", (int) esc, str);
+                       str += esc;
+                       esc = 0;
+                       continue;
+               }
+#endif
                n = strcspn(str, controls);
                if (n) {
                        if (!str[n]) break;
@@ -886,6 +883,14 @@ static void print_ascii(const char *str)
                        /* VT100's CSI, aka Meta-ESC. Who's inventor? */
                        /* I want to know who committed this sin */
                                *p++ = '{';
+#if ENABLE_FEATURE_LESS_RAW
+                       else if ((option_mask32 & FLAG_R)
+                                        && *str == '\033'
+                                        // need at least '<ESC>[m'
+                                        && (esc = count_colctrl(str))) {
+                               break;
+                       }
+#endif
                        else
                                *p++ = ctrlconv[(unsigned char)*str];
                        str++;
@@ -894,6 +899,7 @@ static void print_ascii(const char *str)
                print_hilite(buf);
        }
        puts(str);
+       printf(NORMAL);
 }
 
 /* Print the buffer */
-- 
2.35.2

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to