Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.96k stars 555 forks source link

perlbug should offer to execute a mailto link #13696

Closed p5pRT closed 6 years ago

p5pRT commented 10 years ago

Migrated from rt.perl.org#121553 (status was 'rejected')

Searchable as RT121553$

p5pRT commented 10 years ago

From @bulk88

Created by @bulk88

Perlbug should offer a mailto link with the subject and body in the mailto url and run it through the GUI shell/a browser. See attached pic of how it works on windows. That Outlook Express window isn't configured to send mail on that PC\, but on another PC I have a regular mail client that does send mail. Notice the double quotes didn't work\, and the &s had to be escaped with win32's cmd line escape character which is ^. But this would improve the experience of perlbug on win32 and maybe some other platforms. start command is windows specific\, google says "open" on OSX and |gnome-open on Linux are equivelents. I assume the interface will be an option parallel to "send"\, or underneath "send" as a yes or no\, or automatically if sendmail fails.

----------------------------------------- You have finished composing your message. At this point\, you have a few options. You can​:

  * [Se]nd the message to perlbug@​perl.org and sd\,   * [D]isplay the message on the screen\,   * [R]e-edit the message   * Display or change the message's [su]bject   * Save the message to a [f]ile to mail at another time   * [Q]uit without sending a message

Action (Send/Display/Edit/Subject/Save to File)​: send

Are you certain you want to send this message?

Please type "yes" if you are [no]​: yes It appears that there is no program which looks like "sendmail" on your system and that the Mail​::Send library from CPAN isn't available.

Because of this\, there's no easy way to automatically send your message.

A copy of your message has been saved in 'C​:\WINDOWS\TEMP\zzXuwo1cZJ' for you to send to 'perlbug@​perl.org' with your normal mail client.

C​:\perl519\bin\perlbug.bat has detected an error while trying to send your message​: .

Your message may not have been sent. You will now have a chance to save a copy to disk.

Name of file to save message in [perlbug.rep]​: --------------------------------------------- |

Perl Info ``` Flags: category=utilities severity=wishlist Site configuration information for perl 5.19.10: Configured by Owner at Sat Mar 15 22:30:42 2014. Summary of my perl5 (revision 5 version 19 subversion 10) configuration: Derived from: 2179658b5e799a6e3c4e736ec7c84b0f50bf3473 Ancestor: e9251c1a8f4944e6dceff5240d9e109ba075ff29 Platform: osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef useithreads=define, usemultiplicity=define use64bitint=undef, use64bitall=undef, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cl', ccflags ='-nologo -GF -W3 -O1 -MD -Zi -DNDEBUG -G7 -GL -DWIN32 -D_CONSOLE -DNO_STRICT -DPERL_TEXTMODE_SCRIPTS -DPERL_HASH_FUNC_ONE_AT_A_TIME -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -D_USE_32BIT_TIME_T', optimize='-O1 -MD -Zi -DNDEBUG -G7 -GL', cppflags='-DWIN32' ccversion='13.10.6030', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:\perl519\lib\CORE" -machine:x86' libpth="C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\lib" libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl519.lib gnulibc_version='' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:\perl519\lib\CORE" -machine:x86' Locally applied patches: uncommitted-changes 2179658b5e799a6e3c4e736ec7c84b0f50bf3473 @INC for perl 5.19.10: C:/perl519/site/lib C:/perl519/lib . Environment for perl 5.19.10: HOME (unset) LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=C:\perl519\bin;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\wbem; PERL_BADLANG (unset) SHELL (unset) ```
p5pRT commented 10 years ago

From @bulk88

[perlbug win32 mailto.PNG](https://rt-archive.perl.org/perl5/Ticket/Attachment/1286062/678598/perlbug win32 mailto.PNG)

p5pRT commented 10 years ago

From @tonycoz

On Mon Mar 31 19​:12​:11 2014\, bulk88 wrote​:

Perlbug should offer a mailto link with the subject and body in the mailto url and run it through the GUI shell/a browser. See attached pic of how it works on windows. That Outlook Express window isn't configured to send mail on that PC\, but on another PC I have a regular mail client that does send mail. Notice the double quotes didn't work\, and the &s had to be escaped with win32's cmd line escape character which is ^. But this would improve the experience of perlbug on win32 and maybe some other platforms. start command is windows specific\, google says "open" on OSX and |gnome-open on Linux are equivelents. I assume the interface will be an option parallel to "send"\, or underneath "send" as a yes or no\, or automatically if sendmail fails.

It's an interesting idea.

From some searching it appears that xdg-open is preferred over gnome-open now - since it works outside of gnome.

Testing locally\, xdg-open ran mutt twice (first in my current terminal\, then in a new terminal) while gnome-open only ran it once (in a new terminal) when I set mutt as my mail client. And didn't send the mail.

So I don't think it should be an automated fallback\, but an explicitly selected option.

Of course\, it won't help when their mail client isn't setup (like Evolution for me on Linux\, or Mail on OS X).

Tony

p5pRT commented 10 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 9 years ago

From @jkeenan

On Tue Apr 15 17​:25​:02 2014\, tonyc wrote​:

On Mon Mar 31 19​:12​:11 2014\, bulk88 wrote​:

Perlbug should offer a mailto link with the subject and body in the mailto url and run it through the GUI shell/a browser. See attached pic of how it works on windows. That Outlook Express window isn't configured to send mail on that PC\, but on another PC I have a regular mail client that does send mail. Notice the double quotes didn't work\, and the &s had to be escaped with win32's cmd line escape character which is ^. But this would improve the experience of perlbug on win32 and maybe some other platforms. start command is windows specific\, google says "open" on OSX and |gnome-open on Linux are equivelents. I assume the interface will be an option parallel to "send"\, or underneath "send" as a yes or no\, or automatically if sendmail fails.

It's an interesting idea.

From some searching it appears that xdg-open is preferred over gnome- open now - since it works outside of gnome.

Testing locally\, xdg-open ran mutt twice (first in my current terminal\, then in a new terminal) while gnome-open only ran it once (in a new terminal) when I set mutt as my mail client. And didn't send the mail.

So I don't think it should be an automated fallback\, but an explicitly selected option.

Of course\, it won't help when their mail client isn't setup (like Evolution for me on Linux\, or Mail on OS X).

Tony

bulk88\,

I reviewed this older ticket this evening. TonyC provided some feedback in April 2014\, but it doesn't appear there has been any further correspondence.

If you want to pursue this\, could you prepare a patch?

Thank you very much.

-- James E Keenan (jkeenan@​cpan.org)

p5pRT commented 7 years ago

From @bulk88

On Mon\, 05 Oct 2015 19​:23​:56 -0700\, jkeenan wrote​:

I reviewed this older ticket this evening. TonyC provided some feedback in April 2014\, but it doesn't appear there has been any further correspondence.

If you want to pursue this\, could you prepare a patch?

Thank you very much.

I wrote a crude patch that uses URI​::Escape (not core!!!!). There is 1 minor limit of mailto URL spec\, no HTML\, no MIME\, no attachment\, but perlbug doesnt generate attachments by default anyway (arbitrary user speced only). I did find another limit\, there is a truncation/buffer size bug somewhere. The URL generated works fine if I copy paste it into Seamonkey 2.46's URL bar. BUT if I do system('start mailto​://') or copy paste the "start mailto​://" into cmd.exe\, or paste the mailto​:// URL into Win7 explorer's URL bar\, the email body is truncated around 2015-2040 byte mark (the "byteorder" variable in the perlbug email). This 2KB limit is AFTER percent escaping\, so the email body in the Seamonkey composer is actually 1280 bytes long. A


perl -e" print \"\n\n\n\n\n\n\n\".$ARGV[0]" mailto​://perlbug@​perl.org?subject=kjjh%20kuh^&body=This%20is%20a%20bug%20report%20for%20perl%20from.......................


shows the full URL in STDOUT\, so its not a shell bug\, it is a Seamonkey or somewhere else in Windows bug. I am thinking possibly adding a "start %TEMP%/YsTDFrLJ.eml" or something\, or using Win32 MAPI and WSH (MAPI is COM based\, and because no Win32​::OLE in core\, use WSH VB/JS somehow to launch the compose window in a C-free solution).

Possibly related link https://blogs.msdn.microsoft.com/ieinternals/2014/08/13/url-length-limits/ "On Windows 8.1\, for instance\, if you directly pass a 4k Application Protocol URL to ShellExecute in native code\, the URL is silently truncated at the 2083 character mark."

https://support.microsoft.com/en-us/help/830473/command-prompt-cmd.-exe-command-line-string-limitation

-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 7 years ago

From @bulk88

On Sun\, 22 Jan 2017 13​:38​:50 -0800\, bulk88 wrote​:

I wrote a crude patch that uses URI​::Escape (not core!!!!).

POF Patch attached.

-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 7 years ago

From @bulk88

0001-WIP-RT-121553-perlbug-executes-mailto-link.patch ```diff From 62c809c1c2f2cbbef8b8facf277b7f4a8490d3bc Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Thu, 23 Feb 2017 20:54:26 -0500 Subject: [PATCH] WIP RT#121553 perlbug executes mailto link --- lib/URI/Escape.pm | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ utils/perlbug.PL | 21 ++++++ 2 files changed, 241 insertions(+) create mode 100644 lib/URI/Escape.pm diff --git a/lib/URI/Escape.pm b/lib/URI/Escape.pm new file mode 100644 index 0000000..547535e --- /dev/null +++ b/lib/URI/Escape.pm @@ -0,0 +1,220 @@ +package URI::Escape; + +use strict; +use warnings; + +=head1 NAME + +URI::Escape - Percent-encode and percent-decode unsafe characters + +=head1 SYNOPSIS + + use URI::Escape; + $safe = uri_escape("10% is enough\n"); + $verysafe = uri_escape("foo", "\0-\377"); + $str = uri_unescape($safe); + +=head1 DESCRIPTION + +This module provides functions to percent-encode and percent-decode URI strings as +defined by RFC 3986. Percent-encoding URI's is informally called "URI escaping". +This is the terminology used by this module, which predates the formalization of the +terms by the RFC by several years. + +A URI consists of a restricted set of characters. The restricted set +of characters consists of digits, letters, and a few graphic symbols +chosen from those common to most of the character encodings and input +facilities available to Internet users. They are made up of the +"unreserved" and "reserved" character sets as defined in RFC 3986. + + unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + reserved = ":" / "/" / "?" / "#" / "[" / "]" / "@" + "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" + +In addition, any byte (octet) can be represented in a URI by an escape +sequence: a triplet consisting of the character "%" followed by two +hexadecimal digits. A byte can also be represented directly by a +character, using the US-ASCII character for that octet. + +Some of the characters are I for use as delimiters or as +part of certain URI components. These must be escaped if they are to +be treated as ordinary data. Read RFC 3986 for further details. + +The functions provided (and exported by default) from this module are: + +=over 4 + +=item uri_escape( $string ) + +=item uri_escape( $string, $unsafe ) + +Replaces each unsafe character in the $string with the corresponding +escape sequence and returns the result. The $string argument should +be a string of bytes. The uri_escape() function will croak if given a +characters with code above 255. Use uri_escape_utf8() if you know you +have such chars or/and want chars in the 128 .. 255 range treated as +UTF-8. + +The uri_escape() function takes an optional second argument that +overrides the set of characters that are to be escaped. The set is +specified as a string that can be used in a regular expression +character class (between [ ]). E.g.: + + "\x00-\x1f\x7f-\xff" # all control and hi-bit characters + "a-z" # all lower case characters + "^A-Za-z" # everything not a letter + +The default set of characters to be escaped is all those which are +I part of the C character class shown above as well +as the reserved characters. I.e. the default is: + + "^A-Za-z0-9\-\._~" + +=item uri_escape_utf8( $string ) + +=item uri_escape_utf8( $string, $unsafe ) + +Works like uri_escape(), but will encode chars as UTF-8 before +escaping them. This makes this function able to deal with characters +with code above 255 in $string. Note that chars in the 128 .. 255 +range will be escaped differently by this function compared to what +uri_escape() would. For chars in the 0 .. 127 range there is no +difference. + +Equivalent to: + + utf8::encode($string); + my $uri = uri_escape($string); + +Note: JavaScript has a function called escape() that produces the +sequence "%uXXXX" for chars in the 256 .. 65535 range. This function +has really nothing to do with URI escaping but some folks got confused +since it "does the right thing" in the 0 .. 255 range. Because of +this you sometimes see "URIs" with these kind of escapes. The +JavaScript encodeURIComponent() function is similar to uri_escape_utf8(). + +=item uri_unescape($string,...) + +Returns a string with each %XX sequence replaced with the actual byte +(octet). + +This does the same as: + + $string =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; + +but does not modify the string in-place as this RE would. Using the +uri_unescape() function instead of the RE might make the code look +cleaner and is a few characters less to type. + +In a simple benchmark test I did, +calling the function (instead of the inline RE above) if a few chars +were unescaped was something like 40% slower, and something like 700% slower if none were. If +you are going to unescape a lot of times it might be a good idea to +inline the RE. + +If the uri_unescape() function is passed multiple strings, then each +one is returned unescaped. + +=back + +The module can also export the C<%escapes> hash, which contains the +mapping from all 256 bytes to the corresponding escape codes. Lookup +in this hash is faster than evaluating C +each time. + +=head1 SEE ALSO + +L + + +=head1 COPYRIGHT + +Copyright 1995-2004 Gisle Aas. + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +use Exporter 'import'; +our %escapes; +our @EXPORT = qw(uri_escape uri_unescape uri_escape_utf8); +our @EXPORT_OK = qw(%escapes); +our $VERSION = "3.31"; + +use Carp (); + +# Build a char->hex map +for (0..255) { + $escapes{chr($_)} = sprintf("%%%02X", $_); +} + +my %subst; # compiled patterns + +my %Unsafe = ( + RFC2732 => qr/[^A-Za-z0-9\-_.!~*'()]/, + RFC3986 => qr/[^A-Za-z0-9\-\._~]/, +); + +sub uri_escape { + my($text, $patn) = @_; + return undef unless defined $text; + if (defined $patn){ + unless (exists $subst{$patn}) { + # Because we can't compile the regex we fake it with a cached sub + (my $tmp = $patn) =~ s,/,\\/,g; + eval "\$subst{\$patn} = sub {\$_[0] =~ s/([$tmp])/\$escapes{\$1} || _fail_hi(\$1)/ge; }"; + Carp::croak("uri_escape: $@") if $@; + } + &{$subst{$patn}}($text); + } else { + $text =~ s/($Unsafe{RFC3986})/$escapes{$1} || _fail_hi($1)/ge; + } + $text; +} + +sub _fail_hi { + my $chr = shift; + Carp::croak(sprintf "Can't escape \\x{%04X}, try uri_escape_utf8() instead", ord($chr)); +} + +sub uri_escape_utf8 { + my $text = shift; + utf8::encode($text); + return uri_escape($text, @_); +} + +sub uri_unescape { + # Note from RFC1630: "Sequences which start with a percent sign + # but are not followed by two hexadecimal characters are reserved + # for future extension" + my $str = shift; + if (@_ && wantarray) { + # not executed for the common case of a single argument + my @str = ($str, @_); # need to copy + for (@str) { + s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; + } + return @str; + } + $str =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg if defined $str; + $str; +} + +# XXX FIXME escape_char is buggy as it assigns meaning to the string's storage format. +sub escape_char { + # Old versions of utf8::is_utf8() didn't properly handle magical vars (e.g. $1). + # The following forces a fetch to occur beforehand. + my $dummy = substr($_[0], 0, 0); + + if (utf8::is_utf8($_[0])) { + my $s = shift; + utf8::encode($s); + unshift(@_, $s); + } + + return join '', @URI::Escape::escapes{split //, $_[0]}; +} + +1; diff --git a/utils/perlbug.PL b/utils/perlbug.PL index 2a440cd..2ab2004 100644 --- a/utils/perlbug.PL +++ b/utils/perlbug.PL @@ -1050,6 +1050,23 @@ sub _message_headers { return \%headers; } +sub _mailto_uri { + die "MIME not supported in mailto url" if $have_attachment; + require URI::Escape; + URI::Escape->import('uri_escape'); + my $url_launch; + if ($Is_MSWin32) { + $url_launch = 'start' + } + elsif ($Is_Linux) { + $url_launch = ''; + } + my $uri = 'start mailto://'.$address.'?subject='.uri_escape($subject).'^&body='.uri_escape(_read_report($filename)); + $uri .= '^&cc='.uri_escape($cc) if ($cc); + system($uri); + return $uri; +} + sub _add_body_start { my $body_start = <<"BODY_START"; This is a multi-part message in MIME format. @@ -1184,6 +1201,10 @@ sub _probe_for_sendmail { sub _send_message_sendmail { my $sendmail = _probe_for_sendmail(); unless ($sendmail) { + if ($Is_MSWin32) { + _mailto_uri(); + return; + } my $message_start = !$Is_Linux && !$Is_OpenBSD ? <<'EOT' : <<'EOT'; It appears that there is no program which looks like "sendmail" on your system and that the Mail::Send library from CPAN isn't available. -- 1.9.5.msysgit.1 ```
p5pRT commented 6 years ago

From zefram@fysh.org

Although this is an interesting idea\, it sounds as though the length issue is prohibitive. To put a whole perlbug message body in a mailto URI is certainly stretching the concept of that URI scheme\, and I'm not surprised that such long URIs wouldn't work in practice. It was worth the experiment\, though.

Since no one has actually managed to make this work\, I think we can declare this unworkable\, and should close the ticket.

-zefram

p5pRT commented 6 years ago

@cpansprout - Status changed from 'open' to 'rejected'