From 5168aa72cd43f42572ea32358c115a38f52a6032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 20 Jan 2021 19:20:03 +0100 Subject: [PATCH 1/6] selection: replace \r\n and \n with \r, and strip \e from pasted text Closes #305 Closes #306 --- selection.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/selection.c b/selection.c index 00292541..57553609 100644 --- a/selection.c +++ b/selection.c @@ -1608,12 +1608,36 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) if (count == 0) break; - /* Call cb while at same time replacing \r\n with \n */ + /* + * Call cb while at same time replace: + * - \r\n -> \r + * - \n -> \r + * - \e -> (i.e. strip ESC) + */ char *p = text; size_t left = count; again: - for (size_t i = 0; i < left - 1; i++) { - if (p[i] == '\r' && p[i + 1] == '\n') { + for (size_t i = 0; i < left; i++) { + switch (p[i]) { + default: + break; + + case '\n': + p[i] = '\r'; + break; + + case '\r': + if (i + 1 < left && p[i + 1] == '\n') { + ctx->decoder(ctx, p, i + 1); + + xassert(i + 2 <= left); + p += i + 2; + left -= i + 2; + goto again; + } + break; + + case '\x1b': ctx->decoder(ctx, p, i); xassert(i + 1 <= left); From b31d0c080b705f910132fe6b77aff09ff0bddd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Thu, 21 Jan 2021 15:18:33 +0100 Subject: [PATCH 2/6] =?UTF-8?q?selection:=20unbreak=20text/uri-list=20deco?= =?UTF-8?q?ding:=20we=E2=80=99re=20not=20using=20\r,=20not=20\n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before passing the pasted text to the decoder, we now replace \r\n, and \n, with \r. The URI decoder was looking for a \n, which meant we failed to split up the list and instead pasted a single “multi-line” URI. --- selection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selection.c b/selection.c index 57553609..5bf715fe 100644 --- a/selection.c +++ b/selection.c @@ -1559,7 +1559,7 @@ fdm_receive_decoder_uri(struct clipboard_receive *ctx, char *data, size_t size) char *start = ctx->buf.data; char *end = NULL; - while ((end = memchr(start, '\n', ctx->buf.idx - (start - ctx->buf.data))) != NULL) { + while ((end = memchr(start, '\r', ctx->buf.idx - (start - ctx->buf.data))) != NULL) { decode_one_uri(ctx, start, end - start); start = end + 1; } From 357af41d7e8889efb369deb7c61def5efd89b12e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 23 Jan 2021 11:22:22 +0100 Subject: [PATCH 3/6] selection: strip non-formatting C0, BS, HT and DEL from pasted text --- CHANGELOG.md | 2 ++ selection.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8206323..fd01e737 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,8 @@ * Extending a word/line-wise selection now uses the original selection mode instead of switching to character-wise. * The scrollback search box no longer accepts non-printable characters. +* Non-formatting C0 control characters, `BS`, `HT` and `DEL` are now + stripped from pasted text. ### Deprecated diff --git a/selection.c b/selection.c index 5bf715fe..8b13d2ad 100644 --- a/selection.c +++ b/selection.c @@ -1612,6 +1612,7 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) * Call cb while at same time replace: * - \r\n -> \r * - \n -> \r + * - C0 -> (stript non-formatting C0 characters) * - \e -> (i.e. strip ESC) */ char *p = text; @@ -1627,6 +1628,7 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) break; case '\r': + /* Convert \r\n -> \r */ if (i + 1 < left && p[i + 1] == '\n') { ctx->decoder(ctx, p, i + 1); @@ -1637,6 +1639,21 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) } break; + /* C0 non-formatting control characters (\b \t \n \r excluded) */ + case '\x01': case '\x02': case '\x03': case '\x04': case '\x05': + case '\x06': case '\x07': case '\x0b': case '\x0c': case '\x0e': + case '\x0f': case '\x10': case '\x11': case '\x12': case '\x13': + case '\x14': case '\x15': case '\x16': case '\x17': case '\x18': + case '\x19': case '\x1a': case '\x1b': case '\x1c': case '\x1d': + case '\x1e': case '\x1f': + /* FALLTHROUGH */ + + /* Additional control characters stripped by default (but + * configurable) in XTerm: BS, HT, DEL */ + case '\b': case '\t': case '\x1f': + /* FALLTHROUGH */ + + /* ESC */ case '\x1b': ctx->decoder(ctx, p, i); From 9e5ef6efac995672ea608b04927a5a5d3ce8b51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 23 Jan 2021 11:28:41 +0100 Subject: [PATCH 4/6] selection: codespell: stript -> strip --- selection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selection.c b/selection.c index 8b13d2ad..628c6718 100644 --- a/selection.c +++ b/selection.c @@ -1612,7 +1612,7 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) * Call cb while at same time replace: * - \r\n -> \r * - \n -> \r - * - C0 -> (stript non-formatting C0 characters) + * - C0 -> (strip non-formatting C0 characters) * - \e -> (i.e. strip ESC) */ char *p = text; From e70776fc8c24dee1d34029b3aa51a89ab899ef4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 23 Jan 2021 11:29:27 +0100 Subject: [PATCH 5/6] selection: DEL is 0x7f, not 0x1f --- selection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selection.c b/selection.c index 628c6718..b7aba2cd 100644 --- a/selection.c +++ b/selection.c @@ -1650,7 +1650,7 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) /* Additional control characters stripped by default (but * configurable) in XTerm: BS, HT, DEL */ - case '\b': case '\t': case '\x1f': + case '\b': case '\t': case '\x7f': /* FALLTHROUGH */ /* ESC */ From 49d6dbd761af1dded9e78076dd1a6049c68f82a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 23 Jan 2021 11:30:32 +0100 Subject: [PATCH 6/6] =?UTF-8?q?selection:=20remove=20duplicate=20=E2=80=98?= =?UTF-8?q?ESC=E2=80=99=20in=20switch=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- selection.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/selection.c b/selection.c index b7aba2cd..8ed9b0cc 100644 --- a/selection.c +++ b/selection.c @@ -1651,10 +1651,6 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) /* Additional control characters stripped by default (but * configurable) in XTerm: BS, HT, DEL */ case '\b': case '\t': case '\x7f': - /* FALLTHROUGH */ - - /* ESC */ - case '\x1b': ctx->decoder(ctx, p, i); xassert(i + 1 <= left);