Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perlbug should offer to execute a mailto link #13696

Closed
p5pRT opened this issue Apr 1, 2014 · 10 comments
Closed

perlbug should offer to execute a mailto link #13696

p5pRT opened this issue Apr 1, 2014 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 1, 2014

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

Searchable as RT121553$

@p5pRT
Copy link
Author

p5pRT commented Apr 1, 2014

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
Copy link
Author

p5pRT commented Apr 1, 2014

From @bulk88

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

@p5pRT
Copy link
Author

p5pRT commented Apr 16, 2014

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
Copy link
Author

p5pRT commented Apr 16, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2015

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
Copy link
Author

p5pRT commented Jan 22, 2017

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
Copy link
Author

p5pRT commented Feb 24, 2017

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
Copy link
Author

p5pRT commented Feb 24, 2017

From @bulk88

0001-WIP-RT-121553-perlbug-executes-mailto-link.patch
From 62c809c1c2f2cbbef8b8facf277b7f4a8490d3bc Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
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<reserved> 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<not> part of the C<unreserved> 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<sprintf("%%%02X", ord($byte))>
+each time.
+
+=head1 SEE ALSO
+
+L<URI>
+
+
+=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
Copy link
Author

p5pRT commented Nov 14, 2017

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
Copy link
Author

p5pRT commented Nov 14, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant