Skip to content

Commit

Permalink
filter paste characters causing interrupt signals,
Browse files Browse the repository at this point in the history
according to the current stty settings;
added STTY to FilterPasteControls settings (xterm 388), as default
  • Loading branch information
mined committed Nov 11, 2023
1 parent 1b166fb commit 421e875
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 22 deletions.
4 changes: 3 additions & 1 deletion docs/mintty.1
Original file line number Diff line number Diff line change
Expand Up @@ -2849,7 +2849,7 @@ programming languages.
This string can list characters that are to be excluded from word selection.

.TQ
\fBFiltering pasted text\fP (FilterPasteControls=)
\fBFiltering pasted text\fP (FilterPasteControls=STTY)
With this setting, pasted text can be filtered for selected control
characters which are then replaced by space. Filtering is not applied
when Control is held while pasting. The option is a comma-separated list
Expand All @@ -2873,6 +2873,8 @@ of character tags:
.br
\(en \fBC1\fP control characters 0x80...0x9F
.br
\(en \fBSTTY\fP characters that are configured to cause INT, QUIT, TSTP signals, according to the current stty settings
.br
(Corresponds to the xterm resource \fBdisallowedPasteControls\fP.)

.TQ
Expand Down
8 changes: 8 additions & 0 deletions src/child.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,14 @@ child_tty(void)
return ptsname(pty_fd);
}

uchar *
child_termios_chars(void)
{
static struct termios attr;
tcgetattr(pty_fd, &attr);
return attr.c_cc;
}

#define patch_319

#ifdef debug_pty
Expand Down
1 change: 1 addition & 0 deletions src/child.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern bool child_is_parent(void);
extern char * procres(int pid, char * res);
extern wchar * grandchild_process_list(void);
extern char * child_tty(void);
extern uchar * child_termios_chars(void);
extern char * foreground_prog(void); // to be free()d
extern void user_command(wstring commands, int n);
extern wstring child_conv_path(wstring, bool adjust_dir);
Expand Down
2 changes: 1 addition & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ const config default_cfg = {
.suppress_osc = "",
.suppress_nrc = "", // unused
.suppress_wheel = "",
.filter_paste = "",
.filter_paste = "STTY",
.guard_path = 7,
.bracketed_paste_split = 0,
.suspbuf_max = 8080,
Expand Down
88 changes: 68 additions & 20 deletions src/termclip.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,35 +279,83 @@ term_open(void)
free(selstr);
}

static bool
contains(string s, wchar c)
static bool filter_NUL;
static char filter[69];

static void
set_filter(string s)
{
string tag;
switch (c) {
when '\b': tag = "BS";
when '\t': tag = "HT";
when '\n': tag = "NL";
when '\r': tag = "CR";
when '\f': tag = "FF";
when '\e': tag = "ESC";
when '\177': tag = "DEL";
otherwise:
if (c < ' ')
tag = "C0";
else if (c >= 0x80 && c < 0xA0)
tag = "C1";
bool do_filter(string tag)
{
#if CYGWIN_VERSION_API_MINOR >= 171
char * match = strcasestr(s, tag);
#else
char * match = strstr(s, tag);
#endif
//return match; // a bit simplistic, we should probably properly parse...
if (!match)
return false;
return (match == s || *(match - 1) < '@')
&& match[strlen(tag)] < '@';
}

filter_NUL = false;
*filter = 0;
if (do_filter("C0")) {
filter_NUL = true;
strcat(filter, "\t\n \r");
}
else {
if (do_filter("BS")) strcat(filter, "\b");
if (do_filter("HT")) strcat(filter, "\t");
if (do_filter("NL")) strcat(filter, "\n");
if (do_filter("CR")) strcat(filter, "\r");
if (do_filter("FF")) strcat(filter, "\f");
if (do_filter("ESC")) strcat(filter, "\e");
}
if (do_filter("DEL"))
strcat(filter, "\177");
if (do_filter("C1")) {
filter_NUL = true;
strcat(filter, "€‚ƒ„\205†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ");
}
if (do_filter("STTY")) {
int i = strlen(filter);
void addchar(wchar c)
{
if (c)
filter[i++] = c;
else
return false;
filter_NUL = true;
}
uchar * c_cc = child_termios_chars();
addchar(c_cc[VINTR]);
addchar(c_cc[VQUIT]);
addchar(c_cc[VSUSP]);
addchar(c_cc[VSWTC]);
filter[i] = 0;
}
return strstr(s, tag);
// a bit simplistic, we should probably properly parse...
}

static bool
isin_filter(wchar c)
{
if (c & 0xFFFFFF00)
return false;
if (!c)
return filter_NUL;
return strchr(filter, c);
}

void
term_paste(wchar *data, uint len, bool all)
{
term_cancel_paste();

// set/refresh list of characters to be filtered;
// stty settings may have changed
set_filter(cfg.filter_paste);

uint size = len;
term.paste_buffer = newn(wchar, len);
term.paste_len = term.paste_pos = 0;
Expand All @@ -331,7 +379,7 @@ term_paste(wchar *data, uint len, bool all)
wchar wc = data[i];
if (wc == '\n')
wc = '\r';
if (!all && *cfg.filter_paste && contains(cfg.filter_paste, wc))
if (!all && *cfg.filter_paste && isin_filter(wc))
wc = ' ';

if (data[i] != '\n')
Expand Down
2 changes: 2 additions & 0 deletions wiki/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
* Fix memory leak (mintty/wsltty#340) caused by dynamic emoji checking.
* Revise and unify handling of dynamic pathnames for terminal control.
* Guard network access via dynamic pathnames.
* Filter paste characters causing interrupt signals, according to the current stty settings.

Unicode and Emoji data
* Unicode 15.1 update.
Expand All @@ -21,6 +22,7 @@ Font rendering
Configuration
* Alternative font specification supports initial + for size increase (mintty/wsltty#341).
* New option GuardNetworkPaths.
* Added STTY to FilterPasteControls settings (xterm 388), as default.

### 3.6.5 (3 September 2023) ###

Expand Down

0 comments on commit 421e875

Please sign in to comment.