]> Sergey Matveev's repositories - public-inbox.git/commitdiff
remove Email::Address dependency
authorEric Wong <e@80x24.org>
Wed, 25 May 2016 01:44:46 +0000 (01:44 +0000)
committerEric Wong <e@80x24.org>
Wed, 25 May 2016 01:49:54 +0000 (01:49 +0000)
git has stricter requirements for ident names (no '<>')
which Email::Address allows.

Even in 1.908, Email::Address also has an incomplete fix for
CVE-2015-7686 with a DoS-able regexp for comments.  Since we
don't care for or need all the RFC compliance of Email::Address,
avoiding it entirely may be preferable.

Email::Address will still be installed as a requirement for
Email::MIME, but it is only used by the
Email::MIME::header_str_set which we do not use

12 files changed:
INSTALL
Makefile.PL
lib/PublicInbox/Address.pm [new file with mode: 0644]
lib/PublicInbox/Feed.pm
lib/PublicInbox/Import.pm
lib/PublicInbox/MDA.pm
lib/PublicInbox/SearchMsg.pm
lib/PublicInbox/SearchView.pm
lib/PublicInbox/View.pm
script/public-inbox-learn
script/public-inbox-mda
t/mda.t

diff --git a/INSTALL b/INSTALL
index e75c4e271842de487289e15d3f4974fa562a3c2f..40cd6cae638b95f90f0e5296b70d2d3bf9b2837c 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -28,7 +28,6 @@ Requirements (server MDA)
 * lynx (for converting HTML messages to text)
 * Perl and several modules:    (Debian package name)
   - Date::Parse                libtimedate-perl
-  - Email::Address             libemail-address-perl
   - Email::Filter              libemail-filter-perl
   - Email::MIME                libemail-mime-perl
   - Email::MIME::ContentType   libemail-mime-contenttype-perl
index 9e0c6e8fb5d53d31f8785283dfcc7e73fc50bc59..3cffe13356de55505b0c9afbf55c2977417c2739 100644 (file)
@@ -18,7 +18,6 @@ WriteMakefile(
                # We also depend on git.
                # Keep this sorted and synced to the INSTALL document
                'Date::Parse' => 0,
-               'Email::Address' => 0,
                'Email::Filter' => 0,
                'Email::MIME' => 0,
                'Email::MIME::ContentType' => 0,
diff --git a/lib/PublicInbox/Address.pm b/lib/PublicInbox/Address.pm
new file mode 100644 (file)
index 0000000..ef4cbdc
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright (C) 2016 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+package PublicInbox::Address;
+use strict;
+use warnings;
+
+# very loose regexes, here.  We don't need RFC-compliance,
+# just enough to make thing sanely displayable and pass to git
+
+sub emails { ($_[0] =~ /([^<\s]+\@[^>\s]+)/g) }
+
+sub from_name {
+       my ($val) = @_;
+       my $name = $val;
+       $name =~ s/\s*\S+\@\S+\s*\z//;
+       if ($name !~ /\S/ || $name =~ /[<>]/) { # git does not like [<>]
+               ($name) = emails($val);
+               $name =~ s/\@.*//;
+       }
+       $name =~ tr/\r\n\t/ /;
+       $name =~ s/\A\s*//;
+       $name;
+}
+
+1;
index 6ed0085630825fd985564d4c0cf0d202ddcf556d..81895dbf1d67289644007844cdf3853b47b15f3a 100644 (file)
@@ -5,13 +5,13 @@
 package PublicInbox::Feed;
 use strict;
 use warnings;
-use Email::Address;
 use Email::MIME;
 use Date::Parse qw(strptime);
 use PublicInbox::Hval qw/ascii_html/;
 use PublicInbox::Git;
 use PublicInbox::View;
 use PublicInbox::MID qw/mid_clean mid2path/;
+use PublicInbox::Address;
 use POSIX qw/strftime/;
 use constant {
        DATEFMT => '%Y-%m-%dT%H:%M:%SZ', # Atom standard
@@ -86,7 +86,6 @@ sub _no_thread {
 
 sub end_feed {
        my ($fh) = @_;
-       Email::Address->purge_cache;
        $fh->write('</feed>');
        $fh->close;
 }
@@ -171,7 +170,6 @@ sub emit_index_nosrch {
                PublicInbox::View::index_entry($mime, 0, $state);
                1;
        });
-       Email::Address->purge_cache;
        $last;
 }
 
@@ -330,9 +328,9 @@ sub add_to_feed {
        $title = title_tag($title);
 
        my $from = $header_obj->header('From') or return 0;
-       my @from = Email::Address->parse($from) or return 0;
-       my $name = ascii_html($from[0]->name);
-       my $email = $from[0]->address;
+       my ($email) = PublicInbox::Address::emails($from);
+       my $name = PublicInbox::Address::from_name($from);
+       $name = ascii_html($name);
        $email = ascii_html($email);
 
        if (delete $feed_opts->{emit_header}) {
index 1afcf5d252407adc8d9189a9a4bb9f06bc24978b..e3d65f4aa73b8eb28fa3e9024361c057e2284b9c 100644 (file)
@@ -8,7 +8,6 @@ package PublicInbox::Import;
 use strict;
 use warnings;
 use Fcntl qw(:flock :DEFAULT);
-use Email::Address;
 use PublicInbox::Spawn qw(spawn);
 use PublicInbox::MID qw(mid_mime mid2path);
 
@@ -141,21 +140,21 @@ sub add {
        my ($self, $mime) = @_; # mime = Email::MIME
 
        my $from = $mime->header('From');
-       my @from = Email::Address->parse($from);
-       my $name = $from[0]->name;
-       my $email = $from[0]->address;
-       my $date = $mime->header('Date');
-       my $subject = $mime->header('Subject');
-       $subject = '(no subject)' unless defined $subject;
-       my $mid = mid_mime($mime);
-       my $path = mid2path($mid);
-
+       my ($email) = ($from =~ /([^<\s]+\@[^>\s]+)/g);
+       my $name = $from;
+       $name =~ s/\s*\S+\@\S+\s*\z//;
        # git gets confused with:
        #  "'A U Thor <u@example.com>' via foo" <foo@example.com>
        # ref:
        # <CAD0k6qSUYANxbjjbE4jTW4EeVwOYgBD=bXkSu=akiYC_CB7Ffw@mail.gmail.com>
        $name =~ tr/<>// and $name = $email;
 
+       my $date = $mime->header('Date');
+       my $subject = $mime->header('Subject');
+       $subject = '(no subject)' unless defined $subject;
+       my $mid = mid_mime($mime);
+       my $path = mid2path($mid);
+
        my ($r, $w) = $self->gfi_start;
        my $tip = $self->{tip};
        if ($tip ne '') {
index e1207b56e3aad365f9989c73bd72fd38bc7e3d12..2e6e9ec5a1e55c509f7690d5eea5edd8d5ce1bfe 100644 (file)
@@ -6,7 +6,6 @@ package PublicInbox::MDA;
 use strict;
 use warnings;
 use Email::Simple;
-use Email::Address;
 use Date::Parse qw(strptime);
 use constant MAX_SIZE => 1024 * 500; # same as spamc default, should be tunable
 use constant MAX_MID_SIZE => 244; # max term size - 1 in Xapian
@@ -62,13 +61,13 @@ sub alias_specified {
 
        my @address = ref($address) eq 'ARRAY' ? @$address : ($address);
        my %ok = map {
-               my @recip = Email::Address->parse($_);
-               lc(__drop_plus($recip[0]->address)) => 1;
+               lc(__drop_plus($_)) => 1;
        } @address;
 
        foreach my $line ($filter->cc, $filter->to) {
-               foreach my $addr (Email::Address->parse($line)) {
-                       if ($ok{lc(__drop_plus($addr->address))}) {
+               my @addrs = ($line =~ /([^<\s]+\@[^>\s]+)/g);
+               foreach my $addr (@addrs) {
+                       if ($ok{lc(__drop_plus($addr))}) {
                                return 1;
                        }
                }
index 1244aeea770941800cb7908b162f156f702ae3d1..0fb2a07e43f5818f30acfe4ba4cfc8fdec60ce65 100644 (file)
@@ -7,10 +7,10 @@ package PublicInbox::SearchMsg;
 use strict;
 use warnings;
 use Search::Xapian;
-use Email::Address qw//;
 use POSIX qw//;
 use Date::Parse qw/str2time/;
 use PublicInbox::MID qw/mid_clean/;
+use PublicInbox::Address;
 use Encode qw/find_encoding/;
 my $enc_utf8 = find_encoding('UTF-8');
 our $PFX2TERM_RE = undef;
@@ -87,9 +87,7 @@ sub from ($) {
        my ($self) = @_;
        my $from = __hdr($self, 'from');
        if (defined $from && !defined $self->{from_name}) {
-               $from =~ tr/\t\r\n/ /;
-               my @from = Email::Address->parse($from);
-               $self->{from_name} = $from[0]->name;
+               $self->{from_name} = PublicInbox::Address::from_name($from);
        }
        $from;
 }
index e3dc22f7a60da083587528349837f59536d38219..0ae050529ca0601da056463b11ab5acece6ccf25 100644 (file)
@@ -176,7 +176,6 @@ sub tdump {
        $ctx->{searchview} = 1;
        tdump_ent($git, $state, $_, 0) for @rootset;
        PublicInbox::View::thread_adj_level($state, 0);
-       Email::Address->purge_cache;
 
        $fh->write(search_nav_bot($mset, $q). "\n\n" .
                        foot($ctx). '</pre></body></html>');
index 43609914c26a35ee9756c0245547565c367f09d2..a78ce31d291ea0859edc5cf75a7e2d253579c3a2 100644 (file)
@@ -14,6 +14,7 @@ use PublicInbox::Hval qw/ascii_html/;
 use PublicInbox::Linkify;
 use PublicInbox::MID qw/mid_clean id_compress mid2path mid_mime/;
 use PublicInbox::MsgIter;
+use PublicInbox::Address;
 require POSIX;
 
 use constant INDENT => '  ';
@@ -99,9 +100,7 @@ sub index_entry {
        $seen->{$id} = "#$id"; # save the anchor for children, later
 
        my $mid = PublicInbox::Hval->new_msgid($mid_raw);
-       my $from = $hdr->header('From');
-       my @from = Email::Address->parse($from);
-       $from = $from[0]->name;
+       my $from = PublicInbox::Address::from_name($hdr->header('From'));
 
        my $root_anchor = $state->{root_anchor} || '';
        my $path = $root_anchor ? '../../' : '';
@@ -191,7 +190,6 @@ sub emit_thread_html {
                                ('</ul></li>' x ($max - 1)) . '</ul>');
                }
        }
-       Email::Address->purge_cache;
 
        # there could be a race due to a message being deleted in git
        # but still being in the Xapian index:
@@ -339,8 +337,7 @@ sub headers_to_html_header {
                $v = PublicInbox::Hval->new($v);
 
                if ($h eq 'From') {
-                       my @from = Email::Address->parse($v->raw);
-                       $title[1] = ascii_html($from[0]->name);
+                       $title[1] = PublicInbox::Address::from_name($v->raw);
                } elsif ($h eq 'Subject') {
                        $title[0] = $v->as_html;
                        if ($srch) {
@@ -449,15 +446,13 @@ sub mailto_arg_link {
        foreach my $h (qw(From To Cc)) {
                my $v = $hdr->header($h);
                defined($v) && ($v ne '') or next;
-               my @addrs = Email::Address->parse($v);
-               foreach my $recip (@addrs) {
-                       my $address = $recip->address;
+               my @addrs = PublicInbox::Address::emails($v);
+               foreach my $address (@addrs) {
                        my $dst = lc($address);
                        $cc{$dst} ||= $address;
                        $to ||= $dst;
                }
        }
-       Email::Address->purge_cache;
        my @arg;
 
        my $subj = $hdr->header('Subject') || '';
index 1c051ec1e274a0a9ff166d7ec4a7c779a1d2c8c4..c79f24790e32870478a31d6c5202fada392ca738 100755 (executable)
@@ -11,7 +11,7 @@ use PublicInbox::Config;
 use PublicInbox::Git;
 use PublicInbox::Import;
 use Email::MIME;
-use Email::Address;
+use PublicInbox::Address;
 use IPC::Run qw/run/;
 my $train = shift or die "usage: $usage\n";
 if ($train !~ /\A(?:ham|spam)\z/) {
@@ -29,8 +29,9 @@ my $mime = Email::MIME->new(eval {
 # get all recipients
 my %dests;
 foreach my $h (qw(Cc To)) {
-       foreach my $recipient (Email::Address->parse($mime->header($h))) {
-               $dests{lc($recipient->address)} = 1;
+       my $val = $mime->header($h) or next;
+       foreach my $email (PublicInbox::Address::emails($val)) {
+               $dests{lc($email)} = 1;
        }
 }
 
index b606c59a8e33d19645a5abe5ef2cfd1730e3a458..6ac0e8c48d82befb762d813661c8bdb01332970a 100755 (executable)
@@ -9,7 +9,6 @@ my $usage = 'public-inbox-mda < rfc2822_message';
 
 use Email::Filter;
 use Email::MIME;
-use Email::Address;
 use File::Path::Expand qw/expand_filename/;
 use IPC::Run qw(run);
 use PublicInbox::MDA;
diff --git a/t/mda.t b/t/mda.t
index ad6a09139c6f74503411a513f0b405736d99bbba..fdba967204c310b333e406aa3f687776e5963be7 100644 (file)
--- a/t/mda.t
+++ b/t/mda.t
@@ -48,6 +48,7 @@ my $mime;
 
 local $ENV{GIT_COMMITTER_NAME} = eval {
        use PublicInbox::MDA;
+       use PublicInbox::Address;
        use Encode qw/encode/;
        my $mbox = 't/utf8.mbox';
        open(my $fh, '<', $mbox) or die "failed to open mbox: $mbox\n";
@@ -57,10 +58,9 @@ local $ENV{GIT_COMMITTER_NAME} = eval {
        $msg = Email::MIME->new($msg->simple->as_string);
 
        my $from = $msg->header('From');
-       my @from = Email::Address->parse($from);
-       my $author = $from[0]->name;
-       my $email = $from[0]->address;
-       my $date = $msg ->header('Date');
+       my $author = PublicInbox::Address::from_name($from);
+       my ($email) = PublicInbox::Address::emails($from);
+       my $date = $msg->header('Date');
 
        is('El&#233;anor',
                encode('us-ascii', my $tmp = $author, Encode::HTMLCREF),