diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/compat.h | 6 | ||||
| -rw-r--r-- | src/escape.c | 11 | ||||
| -rw-r--r-- | src/input.c | 9 | ||||
| -rw-r--r-- | src/screen.c | 11 | ||||
| -rw-r--r-- | src/selection.c | 20 | ||||
| -rw-r--r-- | src/text_run.c | 7 |
6 files changed, 38 insertions, 26 deletions
diff --git a/src/compat.h b/src/compat.h index c0ae6fa..dc345d0 100644 --- a/src/compat.h +++ b/src/compat.h @@ -209,10 +209,8 @@ static inline bool term_has_prefix_ci(const char *s, const char *prefix) for (; *prefix; prefix++, s++) { unsigned char a = (unsigned char)*s; unsigned char b = (unsigned char)*prefix; - if (a >= 'A' && a <= 'Z') - a += 'a' - 'A'; - if (b >= 'A' && b <= 'Z') - b += 'a' - 'A'; + a |= ((unsigned)(a - 'A') < 26) ? 0x20 : 0; + b |= ((unsigned)(b - 'A') < 26) ? 0x20 : 0; if (a != b) return false; } diff --git a/src/escape.c b/src/escape.c index 1e56d77..7956017 100644 --- a/src/escape.c +++ b/src/escape.c @@ -76,7 +76,16 @@ static int dcs_decode_hex(const char *s, int len, char *out, int cap) { if (len & 1) return -1; int n = 0; - for (int i = 0; i < len; i += 2) { + int i = 0; + for (; i + 4 <= len; i += 4) { + int h0 = hex_val[(unsigned char)s[i]], l0 = hex_val[(unsigned char)s[i + 1]]; + int h1 = hex_val[(unsigned char)s[i + 2]], l1 = hex_val[(unsigned char)s[i + 3]]; + if ((h0 | l0 | h1 | l1) < 0 || n + 2 > cap) return -1; + out[n] = (char)(h0 << 4 | l0); + out[n + 1] = (char)(h1 << 4 | l1); + n += 2; + } + if (i < len) { int hi = hex_val[(unsigned char)s[i]], lo = hex_val[(unsigned char)s[i + 1]]; if ((hi | lo) < 0 || n >= cap) return -1; out[n++] = (char)(hi << 4 | lo); diff --git a/src/input.c b/src/input.c index 798ffc0..960f488 100644 --- a/src/input.c +++ b/src/input.c @@ -716,11 +716,10 @@ struct term_input_result term_input_encode_paste(const struct term_modes *m, size_t body = sb_len(&sb, buf); for (size_t i = 0; i < len;) { if (sb.overflow) break; - size_t start = i; - while (i < len && (unsigned char)text[i] >= 0x20 && (unsigned char)text[i] < 0x7f) - i++; - if (i > start) { - sb_bytes(&sb, text + start, i - start); + size_t run = term_scan_printable_span(text + i, len - i, 0x7f); + if (run > 0) { + sb_bytes(&sb, text + i, run); + i += run; continue; } unsigned char c = (unsigned char)text[i]; diff --git a/src/screen.c b/src/screen.c index e3f0191..99e788c 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1024,10 +1024,13 @@ void term_free(struct term *t) screen_free(&t->scr); screen_free(&t->alt_scr); screen_free(&t->spare); - struct grow_buf *bufs[] = { &t->resize.row, &t->resize.rows, &t->resize.cells, &t->resize.line, - &t->resize.pull, &t->resize.rest, &t->resize.lens }; - for (size_t i = 0; i < sizeof(bufs) / sizeof(bufs[0]); i++) - free(bufs[i]->data); + free(t->resize.row.data); + free(t->resize.rows.data); + free(t->resize.cells.data); + free(t->resize.line.data); + free(t->resize.pull.data); + free(t->resize.rest.data); + free(t->resize.lens.data); free(t->ascii_ends.data); free(t->ascii_tail.data); term_hist_free(&t->hist); diff --git a/src/selection.c b/src/selection.c index 4602d8f..e4a3e35 100644 --- a/src/selection.c +++ b/src/selection.c @@ -26,7 +26,15 @@ static char *link_at_text(const struct term *t, struct term_vector2i cell) while (end < t->cols && cells[end].c > ' ' && cells[end].c < 127) end++; char *text = malloc((size_t)(end - start) + 1); if (!text) return NULL; - for (int c = start; c < end; c++) text[c - start] = cells[c].c; + int c = start; + for (; c + 4 <= end; c += 4) { + uint32_t packed = (cells[c].c & 0xff) | + ((cells[c + 1].c & 0xff) << 8) | + ((cells[c + 2].c & 0xff) << 16) | + ((cells[c + 3].c & 0xff) << 24); + memcpy(text + (c - start), &packed, 4); + } + for (; c < end; c++) text[c - start] = (char)cells[c].c; text[end - start] = 0; size_t scheme = 8; char *url = strstr(text, "https://"); @@ -307,9 +315,8 @@ static struct term_sel_point view_to_sel_point(const struct lines *L, int x, int if (!view_row_line(L, y, &id, &seg)) return (struct term_sel_point){ .line_id = L->first }; const struct cell *cells = line_seg_cells(L, id, seg, NULL, NULL); - if (cells) - while (x > 0 && (cells[x].flags & CELL_WRAP_PAD)) - x--; + if (cells && x > 0 && (cells[x].flags & CELL_WRAP_PAD)) + x--; return (struct term_sel_point){ .line_id = id, .cell_off = line_seg_start_off(L, id, seg) + (uint32_t)x, @@ -385,9 +392,8 @@ static void unit_span(const struct lines *L, int x, int y, bool right_half, } const struct cell *row = term_screen_view_row(t, y); - if (row) - while (x > 0 && (row[x].flags & CELL_WRAP_PAD)) - x--; + if (row && x > 0 && (row[x].flags & CELL_WRAP_PAD)) + x--; int left = x, right = x; int kind = row ? word_class(row[x].c) : 0; while (left > 0 && row && word_class(row[left - 1].c) == kind) diff --git a/src/text_run.c b/src/text_run.c index 9df7ac0..bf0e8a9 100644 --- a/src/text_run.c +++ b/src/text_run.c @@ -326,11 +326,8 @@ struct text_run_bytes term_text_run_bytes(uint8_t *restrict dst, const char *res unsigned char c = (unsigned char)buf[i]; if (c >= 0x20 && c < 0x7f) { int room = max_cols - cx < len - i ? max_cols - cx : len - i; - int n = 1; - while (n < room && n < 16 && (unsigned char)(buf[i + n] - 0x20) < 0x5f) - n++; - if (n == 16 && n < room) - n += (int)scan_printable_span(buf + i + 16, (size_t)(room - 16), 0x7f); + int n = (int)scan_printable_span(buf + i, (size_t)room, 0x7f); + if (!n) n = 1; bytes_copy_small(dst + o, buf + i, n); i += n; o += n; |
