From 6ea793020f453af93161be185800b4419e7a06cb Mon Sep 17 00:00:00 2001 From: cyanpencil Date: Tue, 12 Jun 2018 16:36:14 +0200 Subject: [PATCH] Fix overflow in canvas.c + fix utf8 crop --- libr/cons/canvas.c | 37 ++++++++++++++++--------------------- libr/core/panels.c | 4 ++-- libr/util/str.c | 4 ++++ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/libr/cons/canvas.c b/libr/cons/canvas.c index e650ca6386d26..f07067831feed 100644 --- a/libr/cons/canvas.c +++ b/libr/cons/canvas.c @@ -57,7 +57,6 @@ static int _get_piece(const char *p, char *chr) { return p - q; } -//XXX todo static const char **attr_at(RConsCanvas *c, int loc) { int i, j, delta; if (!c->color || c->attrslen == 0) { @@ -94,7 +93,6 @@ static const char **attr_at(RConsCanvas *c, int loc) { return NULL; } -//XXX todo static void sort_attrs(RConsCanvas *c) { int i, j; RConsCanvasAttr value; @@ -107,7 +105,6 @@ static void sort_attrs(RConsCanvas *c) { } } -//XXX todo static void stamp_attr(RConsCanvas *c, int loc, int length) { int i; const char **s; @@ -131,7 +128,6 @@ static void stamp_attr(RConsCanvas *c, int loc, int length) { } } -//XXX todo /* check for ANSI sequences and use them as attr */ static const char *set_attr(RConsCanvas *c, const char *s) { if (!c || !s) { @@ -168,26 +164,26 @@ R_API bool r_cons_canvas_gotoxy(RConsCanvas *c, int x, int y) { y += c->sy; x += c->sx; - if (x > c->blen[y] * 2) { - return false; - } if (y > c->h * 2) { return false; } - if (x >= c->blen[y]) { - c->x = c->blen[y]; + if (y >= c->h) { + y = c->h - 1; ret = false; } - if (y >= c->h) { - c->y = c->h; + if (y < 0) { + y = 0; ret = false; } if (x < 0) { //c->x = 0; ret = false; } - if (y < 0) { - c->y = 0; + if (x > c->blen[y] * 2) { + return false; + } + if (x >= c->blen[y]) { + c->x = c->blen[y]; ret = false; } if (x < c->blen[y] && x >= 0) { @@ -269,19 +265,19 @@ static int utf8len_fixed(const char *s, int n) { return j; } -static int bytes_utf8len(const char *s, int n) { +static int bytes_utf8len(const char *s, int n, int left) { int i = 0; - while (s[i] && n > 0) { + while (s[i] && n > -1 && i < left) { if ((s[i] & 0xc0) != 0x80) { n--; } i++; } - return i; + return i - 1; } static int expand_line (RConsCanvas *c, int real_len, int utf8_len) { - int buf_utf8_len = bytes_utf8len (c->b[c->y] + c->x, utf8_len); + int buf_utf8_len = bytes_utf8len (c->b[c->y] + c->x, utf8_len, c->blen[c->y] - c->x); int goback = R_MAX (0, (buf_utf8_len - real_len)); int padding = (real_len - utf8_len) - goback; @@ -320,8 +316,7 @@ R_API void r_cons_canvas_write(RConsCanvas *c, const char *s) { int left, slen, attr_len, piece_len; int orig_x = c->x, attr_x = c->x; - int x_padding = c->x - utf8len_fixed (c->b[c->y], c->x); - c->x += x_padding; + c->x = bytes_utf8len (c->b[c->y], c->x, c->blen[c->y]); /* split the string into pieces of non-ANSI chars and print them normally, ** using the ANSI chars to set the attr of the canvas */ @@ -336,6 +331,7 @@ R_API void r_cons_canvas_write(RConsCanvas *c, const char *s) { left = c->blen[c->y] - c->x; slen = R_MIN (left, piece_len); attr_len = slen <= 0 && s_part != s? 1: slen; + if (attr_len > 0 && attr_x < c->blen[c->y]) { stamp_attr (c, c->y*c->w + attr_x, attr_len); } @@ -358,8 +354,7 @@ R_API void r_cons_canvas_write(RConsCanvas *c, const char *s) { if (*s == '\0' || c->y >= c->h) { break; } - x_padding = utf8len_fixed (c->b[c->y], orig_x); - c->x = 2*orig_x - x_padding; + c->x = bytes_utf8len (c->b[c->y], orig_x, c->blen[c->y]); attr_x = orig_x; } else { c->x += slen; diff --git a/libr/core/panels.c b/libr/core/panels.c index 8cfbf8fa493ef..0124c49fb123b 100644 --- a/libr/core/panels.c +++ b/libr/core/panels.c @@ -193,7 +193,7 @@ static void panelPrint(RCore *core, RConsCanvas *can, RPanel *panel, int color) } white[idx] = 0; text = r_str_ansi_crop (cmdStr, - 0, delta_y, panel->w + delta_x - 2, panel->h - 2 + delta_y); + 0, delta_y, panel->w + delta_x - 3, panel->h - 2 + delta_y); char *newText = r_str_prefix_all (text, white); if (newText) { free (text); @@ -201,7 +201,7 @@ static void panelPrint(RCore *core, RConsCanvas *can, RPanel *panel, int color) } } else { text = r_str_ansi_crop (cmdStr, - delta_x, delta_y, panel->w + delta_x - 2, panel->h - 2 + delta_y); + delta_x, delta_y, panel->w + delta_x - 3, panel->h - 2 + delta_y); } if (text) { r_cons_canvas_write (can, text); diff --git a/libr/util/str.c b/libr/util/str.c index 7d2ef894697d9..1c5ae94f42711 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -1552,6 +1552,10 @@ R_API char *r_str_ansi_crop(const char *str, ut32 x, ut32 y, ut32 x2, ut32 y2) { cw = 0; } else { if (ch >= y && ch < y2) { + if ((*str & 0xc0) == 0x80) { + *r++ = *str++; + continue; + } if (*str == 0x1b && *(str + 1) == '[') { const char *ptr = str; if ((r_end - r) > 2) {