#! perl =head1 NAME confirm-paste - ask for confirmation before pasting control characters =head1 DESCRIPTION Displays a confirmation dialog when a paste containing control characters is detected. The user can choose C to either paste a sanitized variant where all control characters are removed, C

to paste the string unmodified or C to drop the paste request completely. This is mostly meant as a defense-in-depth mechanism to protect against the common web browser bug of you selecting some text but the browser pasting a completely different text, which has some attack potential. It can also be useful to prevent you from accidentally pasting large amounts of text. =head2 DETAILS If a string containing unicode control characters (specifically U+0000 .. U+001F currrently) is pasted into the terminal, this extension will ask whether it should be pasted. Strings without control characters get pasted without prompt. When a sanitized version is pasted (choice C), then contiguous sequences of those control characters will be replaced by a single spaces. The exact detection and sanitization algorithm is subject to change in future versions. =cut sub msg { my ($self, $msg) = @_; $self->{overlay} = $self->overlay (0, -1, $self->ncol, 2, urxvt::OVERLAY_RSTYLE, 0); $self->{overlay}->set (0, 0, $msg); } sub on_tt_paste { my ($self, $str) = @_; my $count = ($str =~ tr/\x00-\x1f//) or return; $self->{paste} = \$str; $self->msg ("Pasting $count control characters, continue? (y/p/n)"); my $preview = substr $self->locale_decode ($str), 0, $self->ncol; $preview =~ s/\n/\\n/g; $preview =~ s/([\x00-\x1f\x80-\x9f])/sprintf "\\x%02x", ord $1/ge; $self->{overlay}->set (0, 1, $self->special_encode ($preview)); $self->enable (key_press => \&key_press); 1 } sub leave { my ($self) = @_; $self->{paste} = undef; delete $self->{overlay}; $self->disable ("key_press"); } sub key_press { my ($self, $event, $keysym, $string) = @_; my $paste = delete $self->{paste}; if ($keysym == 121) { # y my $paste = $$paste; $paste =~ s/[\x00-\x1f]+/ /g; $self->tt_paste ($paste); $self->leave; } elsif ($keysym == 112) { # p $self->tt_paste ($$paste); $self->leave; } elsif ($keysym == 110) { # n $self->leave; } $self->{paste} = $paste; 1 }