---
src/optinc.h    |  1 +
src/rsinc.h     |  1 +
src/screen.C    | 63 ++++++++++++++++++++++++++++++++++++++++++++-----
src/xdefaults.C |  1 +
4 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/src/optinc.h b/src/optinc.h
index 09f9a26..befc68a 100644
--- a/src/optinc.h
+++ b/src/optinc.h
@@ -29,6 +29,7 @@
 def(secondaryScroll)
 def(pastableTabs)
 def(cursorUnderline)
+ def(filterPastedControls)
#if ENABLE_FRILLS
 def(insecure)   // insecure esc sequences
 def(borderLess) // mwm borderless hints
diff --git a/src/rsinc.h b/src/rsinc.h
index 86d0dfe..0b40f62 100644
--- a/src/rsinc.h
+++ b/src/rsinc.h
@@ -67,6 +67,7 @@
#if XFT
  def (buffered)
#endif
+  def(filterPastedControls)
#if ENABLE_FRILLS
  def (depth)
  def (visual)
diff --git a/src/screen.C b/src/screen.C
index 9eb375a..4ba18bf 100644
--- a/src/screen.C
+++ b/src/screen.C
@@ -2703,15 +2703,66 @@ rxvt_term::selection_changed () NOTHROW
void
rxvt_term::tt_paste (char *data, unsigned int len) NOTHROW
{
-  /* convert normal newline chars into common keyboard Return key sequence */
-  for (unsigned int i = 0; i < len; i++)
-    if (data[i] == C0_LF)
-      data[i] = C0_CR;
-
  if (priv_modes & PrivMode_BracketPaste)
    tt_printf ("\x1b[200~");

-  tt_write (data, len);
+  if (option(Opt_filterPastedControls)) {
+    /* prepare lookup table for unwanted characters */
+    char lookup[256];
+    memset(lookup, 0, sizeof(lookup));
+    char drop[] = 
"\x01\x02\x03\x04\x05\x06\x07\x08\x0a\x0b\x0c\x0e\x0f\x10\x11"
+                  
"\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\xc2";
+    for (unsigned int i = sizeof(drop); i-- > 0u;) {
+      lookup[drop[i]] = 1;
+    }
+
+    /* skip the first run of good characters; no change is needed there */
+    char * rptr = data;
+    char * end = data + len;
+    while (rptr < end && lookup[*rptr] == 0) {
+      ++rptr;
+    }
+    /* encountered a bad symbol (or the end of buffer); from this point copy 
byte
+       by byte; we won't copy by segments since they are likely to overlap */
+    char * wptr = rptr;
+    while (rptr < end) {
+      /* consume the current character and process it */
+      switch (*rptr++) {
+      /* convert newline chars into common keyboard Return key sequence */
+      case '\x0a':
+        *wptr++ = '\x0d';
+        break;
+      /* filter pairs C2-80 to C2-9F which are UTF8 sequences for U+0080 to 
U+009F
+         codepoints (C1 Controls and Latin-1 Supplement) */
+      case '\xc2':
+        if (rptr < end) {
+          const char v = *rptr++;
+          if (v < '\x80' || v > '\x9f') {
+            /* not a bad pair, keep both */
+            *wptr++ = '\xc2';
+            *wptr++ = v;
+          }
+        } else {
+          /* write consumed C2 since it's at the buffer end with no pair */
+          *wptr++ = '\xc2';
+        }
+      default:
+        /* skip the consumed character */
+        break;
+      }
+      /* write one by one until the next bad character */
+      while (rptr < end && lookup[*rptr] == 0) {
+        *wptr++ = *rptr++;
+      }
+    }
+    tt_write (data, wptr - data);
+  } else {
+    for (unsigned int i = 0; i < len; i++)
+      if (data[i] == C0_LF)
+        data[i] = C0_CR;
+
+    tt_write (data, len);
+  }

  if (priv_modes & PrivMode_BracketPaste)
    tt_printf ("\x1b[201~");
diff --git a/src/xdefaults.C b/src/xdefaults.C
index 894aa8d..4e973bb 100644
--- a/src/xdefaults.C
+++ b/src/xdefaults.C
@@ -115,6 +115,7 @@ optList[] = {
              BOOL (Rs_scrollTtyOutput, NULL, "si",  Opt_scrollTtyOutput, 
Optflag_Reverse, "scroll-on-tty-output inhibit"),
              BOOL (Rs_scrollTtyKeypress, "scrollTtyKeypress", "sk", 
Opt_scrollTtyKeypress, 0, "scroll-on-keypress"),
              BOOL (Rs_scrollWithBuffer, "scrollWithBuffer", "sw", Opt_scrollWithBuffer, 
0, "scroll-with-buffer"),
+              BOOL (Rs_filterPastedControls, "filterPastedControls", "fc", 
Opt_filterPastedControls, 0, "filter control characters on paste"),
#if BG_IMAGE_FROM_ROOT
              BOOL (Rs_transparent, "inheritPixmap", "ip", Opt_transparent, 0, 
"inherit parent pixmap"),
              BOOL (Rs_transparent, "transparent", "tr", Opt_transparent, 0, 
"inherit parent pixmap"),
--
2.17.0


_______________________________________________
rxvt-unicode mailing list
rxvt-unicode@lists.schmorp.de
http://lists.schmorp.de/mailman/listinfo/rxvt-unicode

Reply via email to