Email-Valid-1.202000755000767000024 012772077134 13042 5ustar00rjbsstaff000000000000README100644000767000024 57412772077134 13771 0ustar00rjbsstaff000000000000Email-Valid-1.202 This archive contains the distribution Email-Valid, version 1.202: Check validity of Internet email addresses This software is copyright (c) 1998 by Maurice Aubrey. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. This README file was generated by Dist::Zilla::Plugin::Readme v6.007. Changes100644000767000024 1770612772077134 14451 0ustar00rjbsstaff000000000000Email-Valid-1.202Revision history for Perl extension Email::Valid. 1.202 2016-09-25 21:48:09-04:00 America/New_York - avoid using a new Net::DNS feature, which should restore function with old versions of Net::DNS 1.201 2016-09-22 19:21:01-04:00 America/New_York - mx check once again allows for A records; a future check may allow mx-only checks on purpose 1.200 2016-03-27 17:36:57-04:00 America/New_York - skip more tests when Net::Domain::TLD not available, as required 1.199 2016-03-27 09:58:03-04:00 America/New_York - More "no MX found" fixes (thanks, Troy Morehouse) - treat restricted/reserved TLDs (invalid, test, example, localhost) as invalid (thanks, Steve Bertrand!) - Made first mention of various external modules be L<> linked. - Added link to RFC822 to SEE ALSO - Various typo and formatting fixes 1.198 2015-10-25 22:36:37-04:00 America/New_York - fix a typo that caused the MX check to die 1.197 2015-10-16 22:57:05-04:00 America/New_York - improve detection of "no MXes" (thanks, Troy Morehouse) - avoid some avoidable warnings (thanks, Svetlana) 1.196 2015-02-05 22:31:29-05:00 America/New_York - AOL "local rules" no longer enforced 1.195 2014-09-01 08:38:58-04:00 America/New_York - handle domain part with MX but no A record (thanks, Karel Miko) 1.194 2014-05-28 17:21:53-04:00 America/New_York - yhaoo.com grew an MX record; use something that won't 1.193 2014-03-26 22:29:28-04:00 America/New_York - improve behavior on CNAME MX records 1.192 2013-09-07 21:00:55 America/New_York if Net::DNS is not available, do not test null mx validity 1.191 2013-09-04 21:52:50 America/New_York update bugtracker, repo, etc. mxcheck fails when remote MX record is "." drop use of bytes.pm; any bug fixed by that should be fixed again properly 0.190 2012-03-26 fix skip test count 0.189 2012-03-26 addresses in the form rjbs@[1.2.3.4], when allowed by allow_ip, are not failed for the tld check (reported by Marcel Grünauer) 0.188 2012-03-15 fix [rt.cpan.org #75736], in which 0@domain.com was considered invalid (thanks for the fix from Steve Bertrand) 0.187 2012-01-27 addresses in the form rjbs@[1.2.3.4] are now (correctly) considered valid; this can be disabled with the -allow_ip option (this resolves RT #48398) check email address length and localpart length (thanks, Steve Bertrand!) 0.186 2012-01-22 use blessed($x) instead of wrapping an ->isa called in eval{}; this patch (thanks, Felipe Bergo!) was submitted to avoid problems with people who have global __DIE__ handlers, but was applied to just avoid the dumb eval{}; people with __DIE__ are otherwise on their own, here 0.185 2011-08-11 do not die in t/valid.t when testing for working DNS (address RT #70157, thanks, Alexey Tourbin) avoid a pointless warning (mentioned in RT #68312) check TLD validity before MX records (address RT #32237, thanks, meyerdigital) reject addresses with non-ASCII characters (address RT #50230, thanks, ferreira) 0.184 2010-06-10 initialize Net::DNS resolver earlier (address RT #56828, thanks mschout @ github) 0.183_001 2009-10-05 reject addresses with any octets that are &128 (address RT #50230, thanks Adriano Ferreira and Graham Barr) 0.182 2009-08-03 skip DNS tests on machines with lying DNS 0.181 2009-03-23 explicitly require perl5 version 6 update some module metadata (Alexandr Ciornii) remove hateful indirect method notation (Alexandr Ciornii) 0.180 2009-01-16 add repo location to metadata 0.179 Mon Nov 27 2006 bug 23657: fix domain label regex: thanks, Nobuaki ITO! 0.178 Sat Nov 25 2006 reduce cases in which IO::CaptureOutput is needed on Win32 (bug 22062, thanks Alexandr Ciornii) 0.177 Sat Nov 25 2006 resolve bug 22710: make fqdn rule more strict: domains must be multiple valid domain labels, and domain labels must be [a-z0-9][-a-z0-9]* replace UNIVERSAL:: with eval{}-wrapping 0.176 Thu Jul 27 2006 further improve DNS stuff: try to make Net::DNS a prereq if we think we'll need it later 0.175 Sat Jun 24 2006 attempt to improve nslookup-location on Cygwin 0.174 Fri Jun 17 2006 added module required on Win32 (IO::CaptureOutput) to Makefile.PL 0.173 Fri Jun 17 2006 update test to require same min. version of TLD.pm as code 0.172 Sat Jun 10 2006 add pod tests 0.171 Sat Jun 10 2006 fixed a problem with the test plan 0.170 Thu Jun 8 2006 fix details on failures for mxcheck and tldcheck don't screw up addresses beginning with a dash try to work on win32 where forking open is busted (thanks Smylers) improve tests 0.16 Fri Jun 2 2006 maintainership assumed by RJBS work with current, broken Net::Domain::TLD improve tests 0.15 Sun Sep 7 21:39:12 PDT 2003 Support for top level domain validity check added by Elizabeth Mattijsen (liz@dijkmat.nl). Updated documentation and added tests. Patch to improve portability when looking for nslookup executable. Thanks to Chromatic Update AOL rules in local_rules check thanks to Paul Fierro 0.14 Wed Jul 3 12:58:50 CEST 2002 Applied patch from Michael G Schwern to remove 'use UNIVERSAL'. 0.13 Tue Jan 16 13:25:57 PST 2001 Only load Net::DNS module if required 0.12 Thu Jul 8 22:26:41 PDT 1999 Added details() method to determine why an address check fails. Thanks to Otis Gospodnetic for the suggestion. Global Net::DNS::Resolver object is now used for DNS queries when Net::DNS is available. Can be accessed directly to tweak the resolver behavior. The address() method now returns an additional value (an instance of the Mail::Address class) when called in a list context. Updated documentation. 0.11 Wed Jul 7 04:33:58 PDT 1999 Changed name to Mail::Address RELEASE WITHDRAWN PENDING DISCUSSION OF THIS NAME CHANGE 0.09 Thu Apr 8 17:21:15 PDT 1999 Added Mail::Address to PREREQ_PM to list dependency, as suggested by Achim. Moved test.pl to t/valid.t as suggested by Achim. DNS lookups now use Net::DNS if available, falling back to nslookup if not. Suggested by Lupe Christoph. Modified documentation Renamed Email::Valid::NSLookup to Email::Valid::DNS, which is now responsible for all DNS queries. 0.08 Removed a couple of warnings when running under -w Bug handling AOL local rules fixed local_rules() now defaults to off 0.07 Tue Jan 12 02:04:57 PST 1999 Mail::Address module is now required Added Email::Valid::NSLookup module to encapsulate DNS lookups -- now we can add additional classes to use other utilities. Fixed problem with spaces thanks to David Birnbaum. Renamed a couple of the parameters -- old names should still work. 0.06 Tue May 26 14:27:34 1998 Modified named parameter parsing 0.05 Mon May 11 00:56:00 1998 fudge() now defaults to false Modified documentation Changed behavior of fully_qualified 0.04 Thu May 7 16:42:00 1998 Added support for Mail::Address objects Added positional/named parameter calling style Updated documentation 0.01 Fri Mar 6 22:19:54 1998 original version; created by h2xs 1.18 LICENSE100644000767000024 4366312772077134 14164 0ustar00rjbsstaff000000000000Email-Valid-1.202This software is copyright (c) 1998 by Maurice Aubrey. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 1998 by Maurice Aubrey. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 1998 by Maurice Aubrey. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End dist.ini100644000767000024 32412772077134 14546 0ustar00rjbsstaff000000000000Email-Valid-1.202name = Email-Valid author = Maurice Aubrey license = Perl_5 copyright_holder = Maurice Aubrey copyright_year = 1998 [@Filter] -bundle = @RJBS -remove = MakeMaker [MakeMaker::Runner] META.yml100644000767000024 2676412772077134 14433 0ustar00rjbsstaff000000000000Email-Valid-1.202--- abstract: 'Check validity of Internet email addresses' author: - 'Maurice Aubrey ' build_requires: ExtUtils::MakeMaker: '0' File::Spec: '0' Test::More: '0.96' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.007, CPAN::Meta::Converter version 2.150005' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Email-Valid requires: Carp: '0' File::Spec: '0' IO::CaptureOutput: '0' IO::File: '0' Mail::Address: '0' Net::DNS: '0' Net::Domain::TLD: '1.65' Scalar::Util: '0' perl: '5.006' strict: '0' warnings: '0' resources: bugtracker: https://github.com/Perl-Email-Project/Email-Valid/issues homepage: https://github.com/Perl-Email-Project/Email-Valid repository: https://github.com/Perl-Email-Project/Email-Valid.git version: '1.202' x_Dist_Zilla: perl: version: '5.024000' plugins: - class: Dist::Zilla::Plugin::Git::GatherDir config: Dist::Zilla::Plugin::GatherDir: exclude_filename: [] exclude_match: [] follow_symlinks: 0 include_dotfiles: 0 prefix: '' prune_directory: [] root: . Dist::Zilla::Plugin::Git::GatherDir: include_untracked: 0 name: '@Filter/Git::GatherDir' version: '2.039' - class: Dist::Zilla::Plugin::CheckPrereqsIndexed name: '@Filter/CheckPrereqsIndexed' version: '0.020' - class: Dist::Zilla::Plugin::CheckExtraTests name: '@Filter/CheckExtraTests' version: '0.029' - class: Dist::Zilla::Plugin::PromptIfStale config: Dist::Zilla::Plugin::PromptIfStale: check_all_plugins: 0 check_all_prereqs: 0 modules: - Dist::Zilla::PluginBundle::RJBS phase: build run_under_travis: 0 skip: [] name: '@Filter/RJBS-Outdated' version: '0.051' - class: Dist::Zilla::Plugin::PromptIfStale config: Dist::Zilla::Plugin::PromptIfStale: check_all_plugins: 1 check_all_prereqs: 0 modules: [] phase: release run_under_travis: 0 skip: [] name: '@Filter/CPAN-Outdated' version: '0.051' - class: Dist::Zilla::Plugin::PruneCruft name: '@Filter/@Filter/PruneCruft' version: '6.007' - class: Dist::Zilla::Plugin::ManifestSkip name: '@Filter/@Filter/ManifestSkip' version: '6.007' - class: Dist::Zilla::Plugin::MetaYAML name: '@Filter/@Filter/MetaYAML' version: '6.007' - class: Dist::Zilla::Plugin::License name: '@Filter/@Filter/License' version: '6.007' - class: Dist::Zilla::Plugin::Readme name: '@Filter/@Filter/Readme' version: '6.007' - class: Dist::Zilla::Plugin::ExecDir name: '@Filter/@Filter/ExecDir' version: '6.007' - class: Dist::Zilla::Plugin::ShareDir name: '@Filter/@Filter/ShareDir' version: '6.007' - class: Dist::Zilla::Plugin::Manifest name: '@Filter/@Filter/Manifest' version: '6.007' - class: Dist::Zilla::Plugin::TestRelease name: '@Filter/@Filter/TestRelease' version: '6.007' - class: Dist::Zilla::Plugin::ConfirmRelease name: '@Filter/@Filter/ConfirmRelease' version: '6.007' - class: Dist::Zilla::Plugin::UploadToCPAN name: '@Filter/@Filter/UploadToCPAN' version: '6.007' - class: Dist::Zilla::Plugin::AutoPrereqs name: '@Filter/AutoPrereqs' version: '6.007' - class: Dist::Zilla::Plugin::Git::NextVersion config: Dist::Zilla::Plugin::Git::NextVersion: first_version: '0.001' version_by_branch: 1 version_regexp: (?^:^([0-9]+\.[0-9]+)$) Dist::Zilla::Role::Git::Repo: repo_root: . name: '@Filter/Git::NextVersion' version: '2.039' - class: Dist::Zilla::Plugin::PkgVersion name: '@Filter/PkgVersion' version: '6.007' - class: Dist::Zilla::Plugin::MetaConfig name: '@Filter/MetaConfig' version: '6.007' - class: Dist::Zilla::Plugin::MetaJSON name: '@Filter/MetaJSON' version: '6.007' - class: Dist::Zilla::Plugin::NextRelease name: '@Filter/NextRelease' version: '6.007' - class: Dist::Zilla::Plugin::Test::ChangesHasContent name: '@Filter/Test::ChangesHasContent' version: '0.010' - class: Dist::Zilla::Plugin::PodSyntaxTests name: '@Filter/PodSyntaxTests' version: '6.007' - class: Dist::Zilla::Plugin::Test::ReportPrereqs name: '@Filter/Test::ReportPrereqs' version: '0.025' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: requires name: '@Filter/TestMoreWithSubtests' version: '6.007' - class: Dist::Zilla::Plugin::PodWeaver config: Dist::Zilla::Plugin::PodWeaver: config_plugins: - '@RJBS' finder: - ':InstallModules' - ':ExecFiles' plugins: - class: Pod::Weaver::Plugin::EnsurePod5 name: '@CorePrep/EnsurePod5' version: '4.013' - class: Pod::Weaver::Plugin::H1Nester name: '@CorePrep/H1Nester' version: '4.013' - class: Pod::Weaver::Plugin::SingleEncoding name: '@RJBS/SingleEncoding' version: '4.013' - class: Pod::Weaver::Section::Name name: '@RJBS/Name' version: '4.013' - class: Pod::Weaver::Section::Version name: '@RJBS/Version' version: '4.013' - class: Pod::Weaver::Section::Region name: '@RJBS/Prelude' version: '4.013' - class: Pod::Weaver::Section::Generic name: '@RJBS/Synopsis' version: '4.013' - class: Pod::Weaver::Section::Generic name: '@RJBS/Description' version: '4.013' - class: Pod::Weaver::Section::Generic name: '@RJBS/Overview' version: '4.013' - class: Pod::Weaver::Section::Generic name: '@RJBS/Stability' version: '4.013' - class: Pod::Weaver::Section::Collect name: Attributes version: '4.013' - class: Pod::Weaver::Section::Collect name: Methods version: '4.013' - class: Pod::Weaver::Section::Collect name: Functions version: '4.013' - class: Pod::Weaver::Section::Leftovers name: '@RJBS/Leftovers' version: '4.013' - class: Pod::Weaver::Section::Region name: '@RJBS/postlude' version: '4.013' - class: Pod::Weaver::Section::Authors name: '@RJBS/Authors' version: '4.013' - class: Pod::Weaver::Section::Contributors name: '@RJBS/Contributors' version: '0.009' - class: Pod::Weaver::Section::Legal name: '@RJBS/Legal' version: '4.013' - class: Pod::Weaver::Plugin::Transformer name: '@RJBS/List' version: '4.013' name: '@Filter/PodWeaver' version: '4.008' - class: Dist::Zilla::Plugin::GithubMeta name: '@Filter/GithubMeta' version: '0.54' - class: Dist::Zilla::Plugin::Git::Check config: Dist::Zilla::Plugin::Git::Check: untracked_files: die Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - dist.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: repo_root: . name: '@Filter/@Git/Check' version: '2.039' - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: [] commit_msg: v%v%n%n%c Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - dist.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@Filter/@Git/Commit' version: '2.039' - class: Dist::Zilla::Plugin::Git::Tag config: Dist::Zilla::Plugin::Git::Tag: branch: ~ changelog: Changes signed: 0 tag: '1.202' tag_format: '%v' tag_message: v%v Dist::Zilla::Role::Git::Repo: repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@Filter/@Git/Tag' version: '2.039' - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - 'origin :' - 'github :' remotes_must_exist: 0 Dist::Zilla::Role::Git::Repo: repo_root: . name: '@Filter/@Git/Push' version: '2.039' - class: Dist::Zilla::Plugin::Git::Contributors config: Dist::Zilla::Plugin::Git::Contributors: 'git --version': 2.9.3 include_authors: 0 include_releaser: 1 order_by: name paths: - . name: '@Filter/Git::Contributors' version: '0.027' - class: Dist::Zilla::Plugin::MakeMaker::Runner config: Dist::Zilla::Role::TestRunner: default_jobs: 1 name: MakeMaker::Runner version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':InstallModules' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':IncModules' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':TestFiles' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':ExtraTestFiles' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':ExecFiles' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':PerlExecFiles' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':ShareFiles' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':MainModule' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':AllFiles' version: '6.007' - class: Dist::Zilla::Plugin::FinderCode name: ':NoFiles' version: '6.007' zilla: class: Dist::Zilla::Dist::Builder config: is_trial: '0' version: '6.007' x_contributors: - 'Alexandr Ciornii ' - 'Karel Miko ' - 'McA ' - 'Michael Schout ' - 'Mohammad S Anwar ' - 'Neil Bowers ' - 'Ricardo SIGNES ' - 'Steve Bertrand ' - 'Svetlana ' - 'Troy Morehouse ' x_serialization_backend: 'YAML::Tiny version 1.69' MANIFEST100644000767000024 50512772077134 14234 0ustar00rjbsstaff000000000000Email-Valid-1.202# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.007. Changes LICENSE MANIFEST META.json META.yml Makefile.PL README dist.ini lib/Email/Valid.pm t/00-report-prereqs.dd t/00-report-prereqs.t t/resolver.t t/utf-8.t t/valid.t xt/author/pod-syntax.t xt/release/changes_has_content.t xt/sayers-corpus.t t000755000767000024 012772077134 13226 5ustar00rjbsstaff000000000000Email-Valid-1.202utf-8.t100644000767000024 43012772077134 14473 0ustar00rjbsstaff000000000000Email-Valid-1.202/tuse strict; use warnings; use Test::More tests => 2; use Email::Valid (); ok( ! Email::Valid->address("adriano-f\xE9res\@blah.com"), 'do not accept addr with \xE9', ); ok( ! Email::Valid->address("adriano-u\x{11F}ur\@blah.com"), 'do not accept addr with \x{11F}', ); valid.t100644000767000024 1306212772077134 14674 0ustar00rjbsstaff000000000000Email-Valid-1.202/t#!perl use strict; use Test::More tests => 39; BEGIN { use_ok('Email::Valid'); } my $v = Email::Valid->new; for my $sub ( sub { $_[0] }, sub { Mail::Address->new(undef, $_[0]) }, ) { ok( ! $v->address( $sub->('Alfred Neuman ') ), 'Alfred Neuman ', ); ok( $v->address( $sub->('123@example.com') ), '123@example.com', ); } ok( $v->address( -address => 'Alfred Neuman ', -fqdn => 0), 'Alfred Neuman { -fqdn => 0 }', ); is( $v->address( -address => 'first last@aol.com', -fudge => 1), 'firstlast@aol.com', "spaces fudged out of an address local-part", ); ok( ! $v->address( -address => 'first last@aol.com', -fudge => 0), "spaces in localpart is not valid when not fudging", ); is($v->details, 'rfc822', "details are rfc822"); is( $v->address('foo @ foo.com'), 'foo@foo.com', "spaced out address is squished" ); is( $v->address(q{fred&barney@stonehenge(yup, the rock place).(that's dot)com}), 'fred&barney@stonehenge.com', "comments nicely dropped from an address", ); is ($v->address(-address => 'user@example.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'), undef, "address with > 254 chars fails", ); is($v->details, 'address_too_long', "details say address is too long"); is( $v->address(-address => 'somebody@example.com', -localpart => 1), 'somebody@example.com', "localpart with 64 chars or less is valid", ); is( $v->address(-address => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com', -localpart => 1), undef, "localpart with 64 chars or more fails", ); is($v->details, 'localpart', "details are localpart"); ok( $v->address('somebody@ example.com'), "space between @ and domain is valid", ); is( $v->address(-address => '1@example.com', -localpart => 1), '1@example.com', "localpart in true context succeeds", ); is( $v->address(-address => '0@example.com', -localpart => 1), '0@example.com', "localpart in false context is defined (bug 75736)", ); ok( $v->address('-dashy@example.net'), 'an email can start with a dash', ); ok( $v->address(-address => '-dashy@example.net'), 'an email can start with a dash (alternate calling method)', ); ok( ! $v->address(-address => 'dashy@-example.net', -fqdn => 1), 'but a domain cannot', ); ok( ! $v->address(-address => 'dashy@example.net-', -fqdn => 1), 'a domain cannot end with a dash either', ); ok( $v->address(-address => 'dashy@a--o.example.net', -fqdn => 1), 'but a domain may contain two dashes in a row in the middle', ); ok( $v->address(-address => 'dashy@ao.example.net', -fqdn => 1), 'and of course two-character labels are valid!', ); ok( $v->address(-address => 'dashy@a.a.example.net', -fqdn => 1), 'onesies, too', ); SKIP: { skip "your dns appears missing or failing to resolve", 3 unless eval { $v->address(-address=> 'devnull@pobox.com', -mxcheck => 1) }; if ( $v->address(-address => 'blort@will-never-exist.pobox.com', -mxcheck => 1) ) { skip "your dns is lying to you; you must not use mxcheck", 3; } ok( $v->address(-address => 'blort@aol.com', -mxcheck => 1), 'blort@aol.com, with mxcheck, is ok', ); ok( !$v->address(-address => 'blort@will-never-exist.pobox.com', -mxcheck => 1), 'blort@will-never-exist.pobox.com, with mxcheck, is invalid', ) or diag "was using $Email::Valid::DNS_Method for dns resolution"; skip "can't deal with null mx without Net::DNS", 1 unless $Email::Valid::DNS_Method eq 'Net::DNS'; ok( !$v->address(-address => 'blort@no-mx-exists.manxome.org', -mxcheck => 1), 'no-mx-exists.manxome.org has a null mx record', ) or diag "was using $Email::Valid::DNS_Method for dns resolution"; } ok( $v->address(-address => 'rjbs@[127.0.0.1]'), 'a domain literal address is okay', ); ok( ! $v->address(-address => 'rjbs@[127.0.0.1]', -allow_ip => 0), 'a domain literal address is not okay if we say -allow_ip=>0', ); SKIP: { skip "tests require Net::Domain::TLD 1.65", 8 unless (eval {require Net::Domain::TLD;Net::Domain::TLD->VERSION(1.65);1}); { my $v = Email::Valid->new; ok( $v->address( -address => 'blort@notarealdomainfoo.com', -mxcheck => 0, -tldcheck => 1, ), 'blort@notarealdomainfoo.com is ok with tldcheck', ); ok( ! $v->address( -address => 'blort@notarealdomainfoo.bla', -mxcheck => 0, -tldcheck => 1, ), 'blort@notarealdomainfoo.bla is not ok with tldcheck', ); is($v->details, 'tldcheck', "it was the tldcheck that broke this email"); } ok( Email::Valid->address( -tldcheck => 1, -allow_ip => 1, -address => q!foo@[1.2.3.4]!, ), "allow_ip + domain literal = no tldcheck", ); ok( ! $v->address( -address => '123@example.invalid', -tldcheck => 1), '123@example.invalid is wrong as per IETF spec (invalid TLD)', ); ok( ! $v->address( -address => '123@example.test', -tldcheck => 1), '123@example.test is wrong as per IETF spec (invalid TLD)', ); ok( ! $v->address( -address => '123@example.example', -tldcheck => 1), '123@example.example is wrong as per IETF spec (invalid TLD)', ); ok( ! $v->address( -address => '123@example.localhost', -tldcheck => 1), '123@example.localhost is wrong as per IETF spec (invalid TLD)', ); } META.json100644000767000024 4366312772077134 14600 0ustar00rjbsstaff000000000000Email-Valid-1.202{ "abstract" : "Check validity of Internet email addresses", "author" : [ "Maurice Aubrey " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.007, CPAN::Meta::Converter version 2.150005", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Email-Valid", "prereqs" : { "develop" : { "requires" : { "Test::More" : "0", "Test::Pod" : "1.41", "XML::LibXML" : "0", "utf8" : "0" } }, "runtime" : { "requires" : { "Carp" : "0", "File::Spec" : "0", "IO::CaptureOutput" : "0", "IO::File" : "0", "Mail::Address" : "0", "Net::DNS" : "0", "Net::Domain::TLD" : "1.65", "Scalar::Util" : "0", "perl" : "5.006", "strict" : "0", "warnings" : "0" } }, "test" : { "recommends" : { "CPAN::Meta" : "2.120900" }, "requires" : { "ExtUtils::MakeMaker" : "0", "File::Spec" : "0", "Test::More" : "0.96" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/Perl-Email-Project/Email-Valid/issues" }, "homepage" : "https://github.com/Perl-Email-Project/Email-Valid", "repository" : { "type" : "git", "url" : "https://github.com/Perl-Email-Project/Email-Valid.git", "web" : "https://github.com/Perl-Email-Project/Email-Valid" } }, "version" : "1.202", "x_Dist_Zilla" : { "perl" : { "version" : "5.024000" }, "plugins" : [ { "class" : "Dist::Zilla::Plugin::Git::GatherDir", "config" : { "Dist::Zilla::Plugin::GatherDir" : { "exclude_filename" : [], "exclude_match" : [], "follow_symlinks" : 0, "include_dotfiles" : 0, "prefix" : "", "prune_directory" : [], "root" : "." }, "Dist::Zilla::Plugin::Git::GatherDir" : { "include_untracked" : 0 } }, "name" : "@Filter/Git::GatherDir", "version" : "2.039" }, { "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", "name" : "@Filter/CheckPrereqsIndexed", "version" : "0.020" }, { "class" : "Dist::Zilla::Plugin::CheckExtraTests", "name" : "@Filter/CheckExtraTests", "version" : "0.029" }, { "class" : "Dist::Zilla::Plugin::PromptIfStale", "config" : { "Dist::Zilla::Plugin::PromptIfStale" : { "check_all_plugins" : 0, "check_all_prereqs" : 0, "modules" : [ "Dist::Zilla::PluginBundle::RJBS" ], "phase" : "build", "run_under_travis" : 0, "skip" : [] } }, "name" : "@Filter/RJBS-Outdated", "version" : "0.051" }, { "class" : "Dist::Zilla::Plugin::PromptIfStale", "config" : { "Dist::Zilla::Plugin::PromptIfStale" : { "check_all_plugins" : 1, "check_all_prereqs" : 0, "modules" : [], "phase" : "release", "run_under_travis" : 0, "skip" : [] } }, "name" : "@Filter/CPAN-Outdated", "version" : "0.051" }, { "class" : "Dist::Zilla::Plugin::PruneCruft", "name" : "@Filter/@Filter/PruneCruft", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::ManifestSkip", "name" : "@Filter/@Filter/ManifestSkip", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::MetaYAML", "name" : "@Filter/@Filter/MetaYAML", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::License", "name" : "@Filter/@Filter/License", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::Readme", "name" : "@Filter/@Filter/Readme", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::ExecDir", "name" : "@Filter/@Filter/ExecDir", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::ShareDir", "name" : "@Filter/@Filter/ShareDir", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::Manifest", "name" : "@Filter/@Filter/Manifest", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::TestRelease", "name" : "@Filter/@Filter/TestRelease", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::ConfirmRelease", "name" : "@Filter/@Filter/ConfirmRelease", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::UploadToCPAN", "name" : "@Filter/@Filter/UploadToCPAN", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::AutoPrereqs", "name" : "@Filter/AutoPrereqs", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::Git::NextVersion", "config" : { "Dist::Zilla::Plugin::Git::NextVersion" : { "first_version" : "0.001", "version_by_branch" : 1, "version_regexp" : "(?^:^([0-9]+\\.[0-9]+)$)" }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." } }, "name" : "@Filter/Git::NextVersion", "version" : "2.039" }, { "class" : "Dist::Zilla::Plugin::PkgVersion", "name" : "@Filter/PkgVersion", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::MetaConfig", "name" : "@Filter/MetaConfig", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::MetaJSON", "name" : "@Filter/MetaJSON", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::NextRelease", "name" : "@Filter/NextRelease", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::Test::ChangesHasContent", "name" : "@Filter/Test::ChangesHasContent", "version" : "0.010" }, { "class" : "Dist::Zilla::Plugin::PodSyntaxTests", "name" : "@Filter/PodSyntaxTests", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", "name" : "@Filter/Test::ReportPrereqs", "version" : "0.025" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "test", "type" : "requires" } }, "name" : "@Filter/TestMoreWithSubtests", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::PodWeaver", "config" : { "Dist::Zilla::Plugin::PodWeaver" : { "config_plugins" : [ "@RJBS" ], "finder" : [ ":InstallModules", ":ExecFiles" ], "plugins" : [ { "class" : "Pod::Weaver::Plugin::EnsurePod5", "name" : "@CorePrep/EnsurePod5", "version" : "4.013" }, { "class" : "Pod::Weaver::Plugin::H1Nester", "name" : "@CorePrep/H1Nester", "version" : "4.013" }, { "class" : "Pod::Weaver::Plugin::SingleEncoding", "name" : "@RJBS/SingleEncoding", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Name", "name" : "@RJBS/Name", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Version", "name" : "@RJBS/Version", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@RJBS/Prelude", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "@RJBS/Synopsis", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "@RJBS/Description", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "@RJBS/Overview", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "@RJBS/Stability", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "Attributes", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "Methods", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "Functions", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Leftovers", "name" : "@RJBS/Leftovers", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@RJBS/postlude", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Authors", "name" : "@RJBS/Authors", "version" : "4.013" }, { "class" : "Pod::Weaver::Section::Contributors", "name" : "@RJBS/Contributors", "version" : "0.009" }, { "class" : "Pod::Weaver::Section::Legal", "name" : "@RJBS/Legal", "version" : "4.013" }, { "class" : "Pod::Weaver::Plugin::Transformer", "name" : "@RJBS/List", "version" : "4.013" } ] } }, "name" : "@Filter/PodWeaver", "version" : "4.008" }, { "class" : "Dist::Zilla::Plugin::GithubMeta", "name" : "@Filter/GithubMeta", "version" : "0.54" }, { "class" : "Dist::Zilla::Plugin::Git::Check", "config" : { "Dist::Zilla::Plugin::Git::Check" : { "untracked_files" : "die" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "dist.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." } }, "name" : "@Filter/@Git/Check", "version" : "2.039" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [], "commit_msg" : "v%v%n%n%c" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "dist.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@Filter/@Git/Commit", "version" : "2.039" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", "config" : { "Dist::Zilla::Plugin::Git::Tag" : { "branch" : null, "changelog" : "Changes", "signed" : 0, "tag" : "1.202", "tag_format" : "%v", "tag_message" : "v%v" }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@Filter/@Git/Tag", "version" : "2.039" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "origin :", "github :" ], "remotes_must_exist" : 0 }, "Dist::Zilla::Role::Git::Repo" : { "repo_root" : "." } }, "name" : "@Filter/@Git/Push", "version" : "2.039" }, { "class" : "Dist::Zilla::Plugin::Git::Contributors", "config" : { "Dist::Zilla::Plugin::Git::Contributors" : { "git --version" : "2.9.3", "include_authors" : 0, "include_releaser" : 1, "order_by" : "name", "paths" : [ "." ] } }, "name" : "@Filter/Git::Contributors", "version" : "0.027" }, { "class" : "Dist::Zilla::Plugin::MakeMaker::Runner", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "MakeMaker::Runner", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":TestFiles", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExtraTestFiles", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":PerlExecFiles", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", "version" : "6.007" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", "version" : "6.007" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { "is_trial" : "0" }, "version" : "6.007" } }, "x_contributors" : [ "Alexandr Ciornii ", "Karel Miko ", "McA ", "Michael Schout ", "Mohammad S Anwar ", "Neil Bowers ", "Ricardo SIGNES ", "Steve Bertrand ", "Svetlana ", "Troy Morehouse " ], "x_serialization_backend" : "Cpanel::JSON::XS version 3.0213" } Makefile.PL100644000767000024 166012772077134 15100 0ustar00rjbsstaff000000000000Email-Valid-1.202require 5.006; use strict; use warnings; use ExtUtils::MakeMaker; use File::Spec; # We want it if we already have it. That way we skip the block below. my $need_net_dns = 1 if eval "require Net::DNS; 1;"; unless ($need_net_dns) { my $found_it; my $ns = 'nslookup'; foreach my $path (File::Spec->path) { my $file = File::Spec->catfile($path, $ns); $found_it = "$file.exe" if ($^O eq 'MSWin32') and -x "$file.exe" and !-d _; $found_it = $file if -x $file and !-d _; } $need_net_dns = ! $found_it; } WriteMakefile( 'NAME' => 'Email::Valid', 'VERSION_FROM' => 'lib/Email/Valid.pm', MIN_PERL_VERSION => '5.006', 'PREREQ_PM' => { 'Test::More' => 0, 'Mail::Address' => 0, 'Scalar::Util' => 0, # for blessed() ($need_net_dns ? ('Net::DNS' => 0) : ()), ((!$need_net_dns and $^O =~ /\AMSWin32|Cygwin\z/) ? ('IO::CaptureOutput' => 0) : () ), }, ); resolver.t100644000767000024 75712772077134 15405 0ustar00rjbsstaff000000000000Email-Valid-1.202/t#!perl use strict; use Test::More; if (!eval { require Net::DNS; 1 }) { plan skip_all => 'only relevant if Net::DNS is installed'; } else { plan tests => 4; } # not yet loaded, so resolver should be undef ok !defined $Email::Valid::Resolver, 'resolver is undef'; # load module, which calls import(), initializing resolver use_ok('Email::Valid'); # check resolver object ok defined $Email::Valid::Resolver, 'resover initialized'; isa_ok $Email::Valid::Resolver, 'Net::DNS::Resolver'; Email000755000767000024 012772077134 14560 5ustar00rjbsstaff000000000000Email-Valid-1.202/libValid.pm100644000767000024 7746312772077134 16356 0ustar00rjbsstaff000000000000Email-Valid-1.202/lib/Emailrequire 5.006; use strict; use warnings; package Email::Valid; $Email::Valid::VERSION = '1.202'; # ABSTRACT: Check validity of Internet email addresses our ( $RFC822PAT, $Details, $Resolver, $Nslookup_Path, $Debug, ); use Carp; use IO::File; use Mail::Address; use File::Spec; use Scalar::Util 'blessed'; our %AUTOLOAD = ( allow_ip => 1, fqdn => 1, fudge => 1, mxcheck => 1, tldcheck => 1, local_rules => 1, localpart => 1, ); our $NSLOOKUP_PAT = 'preference|serial|expire|mail\s+exchanger'; our @NSLOOKUP_PATHS = File::Spec->path(); # initialize if already loaded, better in prefork mod_perl environment our $DNS_Method = defined $Net::DNS::VERSION ? 'Net::DNS' : ''; unless ($DNS_Method) { __PACKAGE__->_select_dns_method; } # initialize $Resolver if necessary if ($DNS_Method eq 'Net::DNS') { unless (defined $Resolver) { $Resolver = Net::DNS::Resolver->new; } } sub new { my $class = shift; $class = ref $class || $class; bless my $self = {}, $class; $self->_initialize; %$self = $self->_rearrange([ keys %AUTOLOAD ], \@_); return $self; } sub _initialize { my $self = shift; $self->{mxcheck} = 0; $self->{tldcheck} = 0; $self->{fudge} = 0; $self->{fqdn} = 1; $self->{allow_ip} = 1; $self->{local_rules} = 0; $self->{localpart} = 1; $self->{details} = $Details = undef; } # Pupose: handles named parameter calling style sub _rearrange { my $self = shift; my(@names) = @{ shift() }; my(@params) = @{ shift() }; my(%args); ref $self ? %args = %$self : _initialize( \%args ); return %args unless @params; unless (@params > 1 and $params[0] =~ /^-/) { while(@params) { croak 'unexpected number of parameters' unless @names; $args{ lc shift @names } = shift @params; } return %args; } while(@params) { my $param = lc substr(shift @params, 1); $args{ $param } = shift @params; } %args; } # Purpose: determine why an address failed a check sub details { my $self = shift; return (ref $self ? $self->{details} : $Details) unless @_; $Details = shift; $self->{details} = $Details if ref $self; return undef; } # Purpose: Check whether address conforms to RFC 822 syntax. sub rfc822 { my $self = shift; my %args = $self->_rearrange([qw( address )], \@_); my $addr = $args{address} or return $self->details('rfc822'); $addr = $addr->address if (blessed($addr) && $addr->isa('Mail::Address')); return $self->details('rfc822') if $addr =~ /\P{ASCII}/ or $addr !~ m/^$RFC822PAT$/o; return 1; } # Purpose: attempt to locate the nslookup utility sub _find_nslookup { my $self = shift; my $ns = 'nslookup'; foreach my $path (@NSLOOKUP_PATHS) { my $file = File::Spec->catfile($path, $ns); return "$file.exe" if ($^O eq 'MSWin32') and -x "$file.exe" and !-d _; return $file if -x $file and !-d _; } return undef; } sub _select_dns_method { # Configure a global resolver object for DNS queries # if Net::DNS is available eval { require Net::DNS }; return $DNS_Method = 'Net::DNS' unless $@; $DNS_Method = 'nslookup'; } # Purpose: perform DNS query using the Net::DNS module sub _net_dns_query { my $self = shift; my $host = shift; $Resolver = Net::DNS::Resolver->new unless defined $Resolver; my @mx_entries = Net::DNS::mx($Resolver, $host); # Check for valid MX records for $host if (@mx_entries) { foreach my $mx (@mx_entries) { my $mxhost = $mx->exchange; my $query = $Resolver->search($mxhost); next unless ($query); foreach my $a_rr ($query->answer) { return 1 unless $a_rr->type ne 'A'; } } } # Check for A record for $host my $ans = $Resolver->query($host, 'A'); my @a_rrs = $ans ? $ans->answer : (); if (@a_rrs) { foreach my $a_rr (@a_rrs) { return 1 unless $a_rr->type ne 'A'; } } # MX Check failed return $self->details('mx'); } # Purpose: perform DNS query using the nslookup utility sub _nslookup_query { my $self = shift; my $host = shift; local($/, *OLDERR); unless ($Nslookup_Path) { $Nslookup_Path = $self->_find_nslookup or croak 'unable to locate nslookup'; } # Check for an A record return 1 if gethostbyname $host; # Check for an MX record if ($^O eq 'MSWin32' or $^O eq 'Cygwin') { # Oh no, we're on Windows! require IO::CaptureOutput; my $response = IO::CaptureOutput::capture_exec( $Nslookup_Path, '-query=mx', $host ); croak "unable to execute nslookup '$Nslookup_Path': exit $?" if $?; print STDERR $response if $Debug; $response =~ /$NSLOOKUP_PAT/io or return $self->details('mx'); return 1; } else { # phew, we're not on Windows! if (my $fh = IO::File->new('-|')) { my $response = <$fh>; print STDERR $response if $Debug; close $fh; $response =~ /$NSLOOKUP_PAT/io or return $self->details('mx'); return 1; } else { open OLDERR, '>&STDERR' or croak "cannot dup stderr: $!"; open STDERR, '>&STDOUT' or croak "cannot redirect stderr to stdout: $!"; { exec $Nslookup_Path, '-query=mx', $host; } open STDERR, ">&OLDERR"; croak "unable to execute nslookup '$Nslookup_Path': $!"; } } } # Purpose: Check whether a top level domain is valid for a domain. sub tld { my $self = shift; my %args = $self->_rearrange([qw( address )], \@_); unless (eval {require Net::Domain::TLD; Net::Domain::TLD->VERSION(1.65); 1}) { die "Net::Domain::TLD not available"; } my $host = $self->_host( $args{address} or return $self->details('tld') ); my ($tld) = $host =~ m#\.(\w+)$#; my %invalid_tlds = map { $_ => 1 } qw(invalid test example localhost); return defined $invalid_tlds{$tld} ? 0 : Net::Domain::TLD::tld_exists($tld); } # Purpose: Check whether a DNS record (A or MX) exists for a domain. sub mx { my $self = shift; my %args = $self->_rearrange([qw( address )], \@_); my $host = $self->_host($args{address}) or return $self->details('mx'); $self->_select_dns_method unless $DNS_Method; if ($DNS_Method eq 'Net::DNS') { print STDERR "using Net::DNS for dns query\n" if $Debug; return $self->_net_dns_query( $host ); } elsif ($DNS_Method eq 'nslookup') { print STDERR "using nslookup for dns query\n" if $Debug; return $self->_nslookup_query( $host ); } else { croak "unknown DNS method '$DNS_Method'"; } } # Purpose: convert address to host # Returns: host sub _host { my $self = shift; my $addr = shift; $addr = $addr->address if (blessed($addr) && $addr->isa('Mail::Address')); my $host = ($addr =~ /^.*@(.*)$/ ? $1 : $addr); $host =~ s/\s+//g; # REMOVE BRACKETS IF IT'S A DOMAIN-LITERAL # RFC822 3.4.6 # Square brackets ("[" and "]") are used to indicate the # presence of a domain-literal, which the appropriate # name-domain is to use directly, bypassing normal # name-resolution mechanisms. $host =~ s/(^\[)|(\]$)//g; $host; } # Purpose: Fix common addressing errors # Returns: Possibly modified address sub _fudge { my $self = shift; my $addr = shift; $addr =~ s/\s+//g if $addr =~ /aol\.com$/i; $addr =~ s/,/./g if $addr =~ /compuserve\.com$/i; $addr; } # Purpose: Special address restrictions on a per-domain basis. # Caveats: These organizations may change their rules at any time. sub _local_rules { my $self = shift; my($user, $host) = @_; 1; } sub _valid_local_part { my ($self, $localpart) = @_; return 0 unless defined $localpart and length $localpart <= 64; return 1; } sub _valid_domain_parts { my ($self, $string) = @_; return unless $string and length $string <= 255; return if $string =~ /\.\./; my @labels = split /\./, $string; for my $label (@labels) { return 0 unless $self->_is_domain_label($label); } return scalar @labels; } sub _is_domain_label { my ($self, $string) = @_; return unless $string =~ /\A [A-Z0-9] # must start with an alnum (?: [-A-Z0-9]* # then maybe a dash or alnum [A-Z0-9] # finally ending with an alnum )? # lather, rinse, repeat \z/ix; return 1; } # Purpose: Put an address through a series of checks to determine # whether it should be considered valid. sub address { my $self = shift; my %args = $self->_rearrange([qw( address fudge mxcheck tldcheck fqdn local_rules )], \@_); my $addr = $args{address} or return $self->details('rfc822'); $addr = $addr->address if (blessed($addr) && $addr->isa('Mail::Address')); $addr = $self->_fudge( $addr ) if $args{fudge}; $self->rfc822( -address => $addr ) or return undef; ($addr) = Mail::Address->parse( $addr ); $addr or return $self->details('rfc822'); # This should never happen if (length($addr->address) > 254) { return $self->details('address_too_long'); } if ($args{local_rules}) { $self->_local_rules( $addr->user, $addr->host ) or return $self->details('local_rules'); } if ($args{localpart}) { $self->_valid_local_part($addr->user) > 0 or return $self->details('localpart'); } my $ip_ok = $args{allow_ip} && $addr->host =~ /\A\[ (?:[0-9]{1,3}\.){3}[0-9]{1,3} /x; if (! $ip_ok && $args{fqdn}) { my $domain_parts = $self->_valid_domain_parts($addr->host); return $self->details('fqdn') unless $ip_ok || ($domain_parts && $domain_parts > 1); } if (! $ip_ok && $args{tldcheck}) { $self->tld( $addr->host ) or return $self->details('tldcheck'); } if ($args{mxcheck}) { # I'm not sure this ->details call is needed, but I'll test for it later. # The whole ->details thing is... weird. -- rjbs, 2006-06-08 $self->mx( $addr->host ) or return $self->details('mxcheck'); } return (wantarray ? ($addr->address, $addr) : $addr->address); } sub AUTOLOAD { my $self = shift; my $type = ref($self) || die "$self is not an object"; my $name = our $AUTOLOAD; $name =~ s/.*://; return if $name eq 'DESTROY'; die "unknown autoload name '$name'" unless $AUTOLOAD{$name}; return (@_ ? $self->{$name} = shift : $self->{$name}); } # Regular expression built using Jeffrey Friedl's example in # _Mastering Regular Expressions_ (http://www.ora.com/catalog/regexp/). $RFC822PAT = <<'EOF'; [\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\ xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xf f\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\x ff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015 "]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\ xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80 -\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]* )*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\ \\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\ x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x8 0-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n \015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x 80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^ \x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040 \t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([ ^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\ \\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\ x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80- \xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015() ]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\ x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04 0\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\ n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\ 015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?! [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\ ]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\ x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\01 5()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>@,;:". \\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff] )|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^ ()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\0 15()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][ ^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\ n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\ x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(? :(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80- \xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]* (?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015 ()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015() ]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\0 40)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\ [^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\ xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]* )*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80 -\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x 80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t ]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\ \[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff]) *\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x 80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80 -\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015( )]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\ \x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t ]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\0 15()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015 ()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^( \040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]| \\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80 -\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015() ]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x 80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^ \x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040 \t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:". \\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff ])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\ \x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x 80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015 ()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\ \\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^ (\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000- \037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\ n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]| \([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\)) [^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff \n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\x ff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*( ?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\ 000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\ xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\x ff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*) *\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\x ff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80- \xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*) *(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\ ]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\] )[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80- \xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\x ff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*( ?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80 -\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)< >@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x8 0-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?: \([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()] *(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*) *\)[\040\t]*)*)*>) EOF $RFC822PAT =~ s/\n//g; 1; #pod =head1 SYNOPSIS #pod #pod use Email::Valid; #pod my $address = Email::Valid->address('maurice@hevanet.com'); #pod print ($address ? 'yes' : 'no'); #pod #pod =head1 DESCRIPTION #pod #pod This module determines whether an email address is well-formed, and #pod optionally, whether a mail host exists for the domain. #pod #pod Please note that there is no way to determine whether an #pod address is deliverable without attempting delivery #pod (for details, see L). #pod #pod =head1 PREREQUISITES #pod #pod This module requires perl 5.004 or later and the L module. #pod Either the L module or the nslookup utility is required #pod for DNS checks. The L module is required to check the #pod validity of top level domains. #pod #pod =head1 METHODS #pod #pod Every method which accepts an C<<
>> parameter may #pod be passed either a string or an instance of the Mail::Address #pod class. All errors raise an exception. #pod #pod =over 4 #pod #pod =item new ( [PARAMS] ) #pod #pod This method is used to construct an Email::Valid object. #pod It accepts an optional list of named parameters to #pod control the behavior of the object at instantiation. #pod #pod The following named parameters are allowed. See the #pod individual methods below for details. #pod #pod -mxcheck #pod -tldcheck #pod -fudge #pod -fqdn #pod -allow_ip #pod -local_rules #pod #pod =item mx (
| ) #pod #pod This method accepts an email address or domain name and determines #pod whether a DNS record (A or MX) exists for it. #pod #pod The method returns true if a record is found and undef if not. #pod #pod Either the Net::DNS module or the nslookup utility is required for #pod DNS checks. Using Net::DNS is the preferred method since error #pod handling is improved. If Net::DNS is available, you can modify #pod the behavior of the resolver (e.g. change the default tcp_timeout #pod value) by manipulating the global L instance stored in #pod C<$Email::Valid::Resolver>. #pod #pod =item rfc822 (
) #pod #pod This method determines whether an address conforms to the RFC822 #pod specification (except for nested comments). It returns true if it #pod conforms and undef if not. #pod #pod =item fudge ( | ) #pod #pod Specifies whether calls to address() should attempt to correct #pod common addressing errors. Currently, this results in the removal of #pod spaces in AOL addresses, and the conversion of commas to periods in #pod Compuserve addresses. The default is false. #pod #pod =item allow_ip ( | ) #pod #pod Specifies whether a "domain literal" is acceptable as the domain part. That #pod means addresses like: C #pod #pod The checking for the domain literal is stricter than the RFC and looser than #pod checking for a valid IP address, I. #pod #pod The default is true. #pod #pod =item fqdn ( | ) #pod #pod Specifies whether addresses passed to address() must contain a fully #pod qualified domain name (FQDN). The default is true. #pod #pod B FQDN checks only occur for non-domain-literals. In other #pod words, if you have set C and the address ends in a bracketed IP #pod address, the FQDN check will not occur. #pod #pod =item tld (
) #pod #pod This method determines whether the domain part of an address is in a #pod recognized top-level domain. #pod #pod B TLD checks only occur for non-domain-literals. In other #pod words, if you have set C and the address ends in a bracketed IP #pod address, the TLD check will not occur. #pod #pod =item local_rules ( | ) #pod #pod Specifies whether addresses passed to address() should be tested #pod for domain specific restrictions. Currently, this is limited to #pod certain AOL restrictions that I'm aware of. The default is false. #pod #pod =item mxcheck ( | ) #pod #pod Specifies whether addresses passed to address() should be checked #pod for a valid DNS entry. The default is false. #pod #pod =item tldcheck ( | ) #pod #pod Specifies whether addresses passed to address() should be checked #pod for a valid top level domains. The default is false. #pod #pod =item address (
) #pod #pod This is the primary method which determines whether an email #pod address is valid. Its behavior is modified by the values of #pod mxcheck(), tldcheck(), local_rules(), fqdn(), and fudge(). If the address #pod passes all checks, the (possibly modified) address is returned as #pod a string. Otherwise, undef is returned. #pod In a list context, the method also returns an instance of the #pod Mail::Address class representing the email address. #pod #pod =item details () #pod #pod If the last call to address() returned undef, you can call this #pod method to determine why it failed. Possible values are: #pod #pod rfc822 #pod localpart #pod local_rules #pod fqdn #pod mxcheck #pod tldcheck #pod #pod If the class is not instantiated, you can get the same information #pod from the global C<$Email::Valid::Details>. #pod #pod =back #pod #pod =head1 EXAMPLES #pod #pod Let's see if the address 'maurice@hevanet.com' conforms to the #pod RFC822 specification: #pod #pod print (Email::Valid->address('maurice@hevanet.com') ? 'yes' : 'no'); #pod #pod Additionally, let's make sure there's a mail host for it: #pod #pod print (Email::Valid->address( -address => 'maurice@hevanet.com', #pod -mxcheck => 1 ) ? 'yes' : 'no'); #pod #pod Let's see an example of how the address may be modified: #pod #pod $addr = Email::Valid->address('Alfred Neuman '); #pod print "$addr\n"; # prints Neuman@foo.bar #pod #pod Now let's add the check for top level domains: #pod #pod $addr = Email::Valid->address( -address => 'Neuman@foo.bar', #pod -tldcheck => 1 ); #pod print "$addr\n"; # doesn't print anything #pod #pod Need to determine why an address failed? #pod #pod unless(Email::Valid->address('maurice@hevanet')) { #pod print "address failed $Email::Valid::Details check.\n"; #pod } #pod #pod If an error is encountered, an exception is raised. This is really #pod only possible when performing DNS queries. Trap any exceptions by #pod wrapping the call in an eval block: #pod #pod eval { #pod $addr = Email::Valid->address( -address => 'maurice@hevanet.com', #pod -mxcheck => 1 ); #pod }; #pod warn "an error was encountered: $@" if $@; #pod #pod =head1 CREDITS #pod #pod Significant portions of this module are based on the ckaddr program #pod written by Tom Christiansen and the RFC822 address pattern developed #pod by Jeffrey Friedl. Neither were involved in the construction of this #pod module; all errors are mine. #pod #pod Thanks very much to the following people for their suggestions and #pod bug fixes: #pod #pod Otis Gospodnetic #pod Kim Ryan #pod Pete Ehlke #pod Lupe Christoph #pod David Birnbaum #pod Achim #pod Elizabeth Mattijsen (liz@dijkmat.nl) #pod #pod =head1 SEE ALSO #pod #pod L, L, L, L #pod #pod L - #pod standard for the format of ARPA internet text messages. #pod Superseded by L. #pod #pod =cut __END__ =pod =encoding UTF-8 =head1 NAME Email::Valid - Check validity of Internet email addresses =head1 VERSION version 1.202 =head1 SYNOPSIS use Email::Valid; my $address = Email::Valid->address('maurice@hevanet.com'); print ($address ? 'yes' : 'no'); =head1 DESCRIPTION This module determines whether an email address is well-formed, and optionally, whether a mail host exists for the domain. Please note that there is no way to determine whether an address is deliverable without attempting delivery (for details, see L). =head1 PREREQUISITES This module requires perl 5.004 or later and the L module. Either the L module or the nslookup utility is required for DNS checks. The L module is required to check the validity of top level domains. =head1 METHODS Every method which accepts an C<<
>> parameter may be passed either a string or an instance of the Mail::Address class. All errors raise an exception. =over 4 =item new ( [PARAMS] ) This method is used to construct an Email::Valid object. It accepts an optional list of named parameters to control the behavior of the object at instantiation. The following named parameters are allowed. See the individual methods below for details. -mxcheck -tldcheck -fudge -fqdn -allow_ip -local_rules =item mx (
| ) This method accepts an email address or domain name and determines whether a DNS record (A or MX) exists for it. The method returns true if a record is found and undef if not. Either the Net::DNS module or the nslookup utility is required for DNS checks. Using Net::DNS is the preferred method since error handling is improved. If Net::DNS is available, you can modify the behavior of the resolver (e.g. change the default tcp_timeout value) by manipulating the global L instance stored in C<$Email::Valid::Resolver>. =item rfc822 (
) This method determines whether an address conforms to the RFC822 specification (except for nested comments). It returns true if it conforms and undef if not. =item fudge ( | ) Specifies whether calls to address() should attempt to correct common addressing errors. Currently, this results in the removal of spaces in AOL addresses, and the conversion of commas to periods in Compuserve addresses. The default is false. =item allow_ip ( | ) Specifies whether a "domain literal" is acceptable as the domain part. That means addresses like: C The checking for the domain literal is stricter than the RFC and looser than checking for a valid IP address, I. The default is true. =item fqdn ( | ) Specifies whether addresses passed to address() must contain a fully qualified domain name (FQDN). The default is true. B FQDN checks only occur for non-domain-literals. In other words, if you have set C and the address ends in a bracketed IP address, the FQDN check will not occur. =item tld (
) This method determines whether the domain part of an address is in a recognized top-level domain. B TLD checks only occur for non-domain-literals. In other words, if you have set C and the address ends in a bracketed IP address, the TLD check will not occur. =item local_rules ( | ) Specifies whether addresses passed to address() should be tested for domain specific restrictions. Currently, this is limited to certain AOL restrictions that I'm aware of. The default is false. =item mxcheck ( | ) Specifies whether addresses passed to address() should be checked for a valid DNS entry. The default is false. =item tldcheck ( | ) Specifies whether addresses passed to address() should be checked for a valid top level domains. The default is false. =item address (
) This is the primary method which determines whether an email address is valid. Its behavior is modified by the values of mxcheck(), tldcheck(), local_rules(), fqdn(), and fudge(). If the address passes all checks, the (possibly modified) address is returned as a string. Otherwise, undef is returned. In a list context, the method also returns an instance of the Mail::Address class representing the email address. =item details () If the last call to address() returned undef, you can call this method to determine why it failed. Possible values are: rfc822 localpart local_rules fqdn mxcheck tldcheck If the class is not instantiated, you can get the same information from the global C<$Email::Valid::Details>. =back =head1 EXAMPLES Let's see if the address 'maurice@hevanet.com' conforms to the RFC822 specification: print (Email::Valid->address('maurice@hevanet.com') ? 'yes' : 'no'); Additionally, let's make sure there's a mail host for it: print (Email::Valid->address( -address => 'maurice@hevanet.com', -mxcheck => 1 ) ? 'yes' : 'no'); Let's see an example of how the address may be modified: $addr = Email::Valid->address('Alfred Neuman '); print "$addr\n"; # prints Neuman@foo.bar Now let's add the check for top level domains: $addr = Email::Valid->address( -address => 'Neuman@foo.bar', -tldcheck => 1 ); print "$addr\n"; # doesn't print anything Need to determine why an address failed? unless(Email::Valid->address('maurice@hevanet')) { print "address failed $Email::Valid::Details check.\n"; } If an error is encountered, an exception is raised. This is really only possible when performing DNS queries. Trap any exceptions by wrapping the call in an eval block: eval { $addr = Email::Valid->address( -address => 'maurice@hevanet.com', -mxcheck => 1 ); }; warn "an error was encountered: $@" if $@; =head1 CREDITS Significant portions of this module are based on the ckaddr program written by Tom Christiansen and the RFC822 address pattern developed by Jeffrey Friedl. Neither were involved in the construction of this module; all errors are mine. Thanks very much to the following people for their suggestions and bug fixes: Otis Gospodnetic Kim Ryan Pete Ehlke Lupe Christoph David Birnbaum Achim Elizabeth Mattijsen (liz@dijkmat.nl) =head1 SEE ALSO L, L, L, L L - standard for the format of ARPA internet text messages. Superseded by L. =head1 AUTHOR Maurice Aubrey =head1 CONTRIBUTORS =for stopwords Alexandr Ciornii Karel Miko McA Michael Schout Mohammad S Anwar Neil Bowers Ricardo SIGNES Steve Bertrand Svetlana Troy Morehouse =over 4 =item * Alexandr Ciornii =item * Karel Miko =item * McA =item * Michael Schout =item * Mohammad S Anwar =item * Neil Bowers =item * Ricardo SIGNES =item * Steve Bertrand =item * Svetlana =item * Troy Morehouse =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 1998 by Maurice Aubrey. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut xt000755000767000024 012772077134 13416 5ustar00rjbsstaff000000000000Email-Valid-1.202sayers-corpus.t100644000767000024 27125012772077134 16631 0ustar00rjbsstaff000000000000Email-Valid-1.202/xt#!perl -T use utf8; use strict; use warnings FATAL => 'all'; use Test::More; # why can't the bloody thing do this by default? binmode Test::More->builder->$_, ':encoding(UTF-8)' for qw(output failure_output todo_output); BEGIN { plan skip_all => "set EXTENDED_TESTING env var to run these" unless $ENV{EXTENDED_TESTING}; } use Email::Valid qw(); use XML::LibXML qw(); sub encode_tap { # suitable for printing into a TAP stream, i.e. change linebreaks my ($string) = @_; # unfortunately, the tr operator is too dumb to do this $string =~ s[\x{a}][␊]g; $string =~ s[\x{d}][␍]g; return $string; } my $dom = XML::LibXML->load_xml(string => do { local $/; }); my $valid = Email::Valid->new; for my $test_element ($dom->findnodes('//test')) { my %record; for my $key (qw(address valid warning comment source sourcelink id)) { my @key_node = $test_element->getChildrenByTagName($key); $record{$key} = $key_node[0]->textContent if @key_node; } my $comment = encode_tap($record{address}) . ' is ' . ('true' eq $record{valid} ? q() : 'in') . 'valid' . (exists $record{comment} ? " - $record{comment}" : q()) ; if ('true' eq $record{valid}) { ok $valid->address($record{address}), $comment; } elsif ('false' eq $record{valid}) { my $details = $valid->details || 'no details'; ok !$valid->address($record{address}), "[$details] $comment"; } else { die 'cannot happen'; } } done_testing; # http://code.iamcal.com/php/rfc822/tests.php # http://www.dominicsayers.com/isemail/ # http://www.dominicsayers.com/isemail/isemail/extras/RFC5322BNF.html # http://code.google.com/p/isemail/source/browse/trunk/tests/tests.xml __DATA__
first.last@example.com
true false Dominic Sayers http://www.dominicsayers.com/isemail 1
1234567890123456789012345678901234567890123456789012345678901234@example.com
true false Dominic Sayers http://www.dominicsayers.com/isemail 2
first.last@sub.do,com
false false Mistyped comma instead of dot (replaces old #3 which was the same as #57) Rob <bob@bob.com> 3
"first\"last"@example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 4
first\@last@example.com
false false Escaping can only happen within a quoted string Dominic Sayers http://www.dominicsayers.com/isemail 5
"first@last"@example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 6
"first\\last"@example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 7
x@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x2
true false Total length reduced to 254 characters so it's still valid Dominic Sayers http://www.dominicsayers.com/isemail 8
1234567890123456789012345678901234567890123456789012345678@12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.123456789012345678901234567890123456789012345678901234567890123.example.com
true false Total length reduced to 254 characters so it's still valid RFC 3696 erratum 1690 http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690 9
first.last@[12.34.56.78]
true true RFC 3696 erratum 1690 http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690 10
first.last@[IPv6:::12.34.56.78]
true true Dominic Sayers http://www.dominicsayers.com/isemail 11
first.last@[IPv6:1111:2222:3333::4444:12.34.56.78]
true true Dominic Sayers http://www.dominicsayers.com/isemail 12
first.last@[IPv6:1111:2222:3333:4444:5555:6666:12.34.56.78]
true true Dominic Sayers http://www.dominicsayers.com/isemail 13
first.last@[IPv6:::1111:2222:3333:4444:5555:6666]
true true Dominic Sayers http://www.dominicsayers.com/isemail 14
first.last@[IPv6:1111:2222:3333::4444:5555:6666]
true true Dominic Sayers http://www.dominicsayers.com/isemail 15
first.last@[IPv6:1111:2222:3333:4444:5555:6666::]
true true Dominic Sayers http://www.dominicsayers.com/isemail 16
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]
true true Dominic Sayers http://www.dominicsayers.com/isemail 17
first.last@x23456789012345678901234567890123456789012345678901234567890123.example.com
true false Dominic Sayers http://www.dominicsayers.com/isemail 18
first.last@1xample.com
true false Dominic Sayers http://www.dominicsayers.com/isemail 19
first.last@123.example.com
true false Dominic Sayers http://www.dominicsayers.com/isemail 20
123456789012345678901234567890123456789012345678901234567890@12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12.example.com
false false Entire address is longer than 254 characters RFC 3696 erratum 1690 http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=1690 21
first.last
false false No @ Dominic Sayers http://www.dominicsayers.com/isemail 22
12345678901234567890123456789012345678901234567890123456789012345@example.com
false false Local part more than 64 characters Dominic Sayers http://www.dominicsayers.com/isemail 23
.first.last@example.com
false false Local part starts with a dot Dominic Sayers http://www.dominicsayers.com/isemail 24
first.last.@example.com
false false Local part ends with a dot Dominic Sayers http://www.dominicsayers.com/isemail 25
first..last@example.com
false false Local part has consecutive dots Dominic Sayers http://www.dominicsayers.com/isemail 26
"first"last"@example.com
false false Local part contains unescaped excluded characters Dominic Sayers http://www.dominicsayers.com/isemail 27
"first\last"@example.com
true true Any character can be escaped in a quoted string Dominic Sayers http://www.dominicsayers.com/isemail 28
"""@example.com
false false Local part contains unescaped excluded characters Dominic Sayers http://www.dominicsayers.com/isemail 29
"\"@example.com
false false Local part cannot end with a backslash Dominic Sayers http://www.dominicsayers.com/isemail 30
""@example.com
false false Local part is effectively empty Dominic Sayers http://www.dominicsayers.com/isemail 31
first\\@last@example.com
false false Local part contains unescaped excluded characters Dominic Sayers http://www.dominicsayers.com/isemail 32
first.last@
false false No domain Dominic Sayers http://www.dominicsayers.com/isemail 33
x@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456
false false Domain exceeds 255 chars Dominic Sayers http://www.dominicsayers.com/isemail 34
first.last@[.12.34.56.78]
false false Only char that can precede IPv4 address is ':' Dominic Sayers http://www.dominicsayers.com/isemail 35
first.last@[12.34.56.789]
false false Can't be interpreted as IPv4 so IPv6 tag is missing Dominic Sayers http://www.dominicsayers.com/isemail 36
first.last@[::12.34.56.78]
false false IPv6 tag is missing Dominic Sayers http://www.dominicsayers.com/isemail 37
first.last@[IPv5:::12.34.56.78]
false false IPv6 tag is wrong Dominic Sayers http://www.dominicsayers.com/isemail 38
first.last@[IPv6:1111:2222:3333::4444:5555:12.34.56.78]
true true RFC 4291 disagrees with RFC 5321 but is cited by it Dominic Sayers http://www.dominicsayers.com/isemail 39
first.last@[IPv6:1111:2222:3333:4444:5555:12.34.56.78]
false false Not enough IPv6 groups Dominic Sayers http://www.dominicsayers.com/isemail 40
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:12.34.56.78]
false false Too many IPv6 groups (6 max) Dominic Sayers http://www.dominicsayers.com/isemail 41
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777]
false false Not enough IPv6 groups Dominic Sayers http://www.dominicsayers.com/isemail 42
first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]
false false Too many IPv6 groups (8 max) Dominic Sayers http://www.dominicsayers.com/isemail 43
first.last@[IPv6:1111:2222::3333::4444:5555:6666]
false false Too many '::' (can be none or one) Dominic Sayers http://www.dominicsayers.com/isemail 44
first.last@[IPv6:1111:2222:3333::4444:5555:6666:7777]
true true RFC 4291 disagrees with RFC 5321 but is cited by it Dominic Sayers http://www.dominicsayers.com/isemail 45
first.last@[IPv6:1111:2222:333x::4444:5555]
false false x is not valid in an IPv6 address Dominic Sayers http://www.dominicsayers.com/isemail 46
first.last@[IPv6:1111:2222:33333::4444:5555]
false false 33333 is not a valid group in an IPv6 address Dominic Sayers http://www.dominicsayers.com/isemail 47
first.last@example.123
true true TLD can't be all digits Dominic Sayers http://www.dominicsayers.com/isemail 48
first.last@com
true true Mail host must be second- or lower level Dominic Sayers http://www.dominicsayers.com/isemail 49
first.last@-xample.com
false false Label can't begin with a hyphen Dominic Sayers http://www.dominicsayers.com/isemail 50
first.last@exampl-.com
false false Label can't end with a hyphen Dominic Sayers http://www.dominicsayers.com/isemail 51
first.last@x234567890123456789012345678901234567890123456789012345678901234.example.com
false false Label can't be longer than 63 octets Dominic Sayers http://www.dominicsayers.com/isemail 52
"Abc\@def"@example.com
true true RFC 3696 (February 2004) http://tools.ietf.org/html/rfc3696#section-3 53
"Fred\ Bloggs"@example.com
true true RFC 3696 (as amended by erratum 2005-07-09) http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=246 54
"Joe.\\Blow"@example.com
true true RFC 3696 (as amended by erratum 2005-07-09) http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=246 55
"Abc@def"@example.com
true true RFC 3696 (as amended by erratum 2005-07-09) http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=246 56
"Fred Bloggs"@example.com
true true RFC 3696 (February 2004) http://tools.ietf.org/html/rfc3696#section-3 57
user+mailbox@example.com
true false RFC 3696 (February 2004) http://tools.ietf.org/html/rfc3696#section-3 58
customer/department=shipping@example.com
true false RFC 3696 (February 2004) http://tools.ietf.org/html/rfc3696#section-3 59
$A12345@example.com
true true RFC 3696 (February 2004) http://tools.ietf.org/html/rfc3696#section-3 60
!def!xyz%abc@example.com
true true RFC 3696 (February 2004) http://tools.ietf.org/html/rfc3696#section-3 61
_somename@example.com
true false RFC 3696 (February 2004) http://tools.ietf.org/html/rfc3696#section-3 62
dclo@us.ibm.com
true false Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 63
abc\@def@example.com
false false This example from RFC 3696 was corrected in an erratum Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 64
abc\\@example.com
false false This example from RFC 3696 was corrected in an erratum Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 65
peter.piper@example.com
true false Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 66
Doug\ \"Ace\"\ Lovell@example.com
false false Escaping can only happen in a quoted string Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 67
"Doug \"Ace\" L."@example.com
true true Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 68
abc@def@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 69
abc\\@def@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 70
abc\@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 71
@example.com
false false No local part Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 72
doug@
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 73
"qu@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 74
ote"@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 75
.dot@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 76
dot.@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 77
two..dot@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 78
"Doug "Ace" L."@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 79
Doug\ \"Ace\"\ L\.@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 80
hello world@example.com
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 81
gatsby@f.sc.ot.t.f.i.tzg.era.l.d.
false false Doug Lovell says this should fail Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 82
true false
test@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 83
true false
TEST@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 84
true false
1234567890@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 85
true false
test+test@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 86
true false
test-test@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 87
true false
t*est@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 88
true true
+1~1+@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 89
true true
{_test_}@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 90
true true
"[[ test ]]"@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 91
true false
test.test@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 92
true true
"test.test"@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 93
true true
test."test"@example.com
Obsolete form, but documented in RFC 5322 Dave Child http://code.google.com/p/php-email-address-validation/ 94
true true
"test@test"@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 95
true false
test@123.123.123.x123
Dave Child http://code.google.com/p/php-email-address-validation/ 96
true true
test@123.123.123.123
Top Level Domain won't be all-numeric (see RFC 3696 Section 2). I disagree with Dave Child on this one. Dave Child http://code.google.com/p/php-email-address-validation/ 97
true true
test@[123.123.123.123]
Dave Child http://code.google.com/p/php-email-address-validation/ 98
true false
test@example.example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 99
true false
test@example.example.example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 100
false false
test.example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 101
false false
test.@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 102
false false
test..test@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 103
false false
.test@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 104
false false
test@test@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 105
false false
test@@example.com
Dave Child http://code.google.com/p/php-email-address-validation/ 106
false false
-- test --@example.com
No spaces allowed in local part Dave Child http://code.google.com/p/php-email-address-validation/ 107
false false
[test]@example.com
Square brackets only allowed within quotes Dave Child http://code.google.com/p/php-email-address-validation/ 108
true true
"test\test"@example.com
Any character can be escaped in a quoted string Dave Child http://code.google.com/p/php-email-address-validation/ 109
false false
"test"test"@example.com
Quotes cannot be nested Dave Child http://code.google.com/p/php-email-address-validation/ 110
false false
()[]\;:,><@example.com
Disallowed Characters Dave Child http://code.google.com/p/php-email-address-validation/ 111
false false Dave Child says so
test@.
Dave Child http://code.google.com/p/php-email-address-validation/ 112
false false Dave Child says so
test@example.
Dave Child http://code.google.com/p/php-email-address-validation/ 113
false false Dave Child says so
test@.org
Dave Child http://code.google.com/p/php-email-address-validation/ 114
false false
test@123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012.com
255 characters is maximum length for domain. This is 256. Dave Child http://code.google.com/p/php-email-address-validation/ 115
true true Dave Child says so
test@example
Dave Child http://code.google.com/p/php-email-address-validation/ 116
false false Dave Child says so
test@[123.123.123.123
Dave Child http://code.google.com/p/php-email-address-validation/ 117
false false Dave Child says so
test@123.123.123.123]
Dave Child http://code.google.com/p/php-email-address-validation/ 118
NotAnEmail
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 119
@NotAnEmail
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 120
"test\\blah"@example.com
true true Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 121
"test\blah"@example.com
true true Any character can be escaped in a quoted string Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 122
"test\ blah"@example.com
true true Quoted string specifically excludes carriage returns unless escaped Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 123
"test blah"@example.com
false false Quoted string specifically excludes carriage returns Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 124
"test\"blah"@example.com
true true Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 125
"test"blah"@example.com
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 126
customer/department@example.com
true false Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 127
_Yosemite.Sam@example.com
true false Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 128
~@example.com
true true Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 129
.wooly@example.com
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 130
wo..oly@example.com
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 131
pootietang.@example.com
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 132
.@example.com
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 133
"Austin@Powers"@example.com
true true Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 134
Ima.Fool@example.com
true false Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 135
"Ima.Fool"@example.com
true true Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 136
"Ima Fool"@example.com
true true Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 137
Ima Fool@example.com
false false Phil Haack says so Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 138
phil.h\@\@ck@haacked.com
false false Escaping can only happen in a quoted string Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 139
"first"."last"@example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 140
"first".middle."last"@example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 141
"first\\"last"@example.com
false false Contains an unescaped quote Dominic Sayers http://www.dominicsayers.com/isemail 142
"first".last@example.com
true true obs-local-part form as described in RFC 5322 Dominic Sayers http://www.dominicsayers.com/isemail 143
first."last"@example.com
true true obs-local-part form as described in RFC 5322 Dominic Sayers http://www.dominicsayers.com/isemail 144
"first"."middle"."last"@example.com
true true obs-local-part form as described in RFC 5322 Dominic Sayers http://www.dominicsayers.com/isemail 145
"first.middle"."last"@example.com
true true obs-local-part form as described in RFC 5322 Dominic Sayers http://www.dominicsayers.com/isemail 146
"first.middle.last"@example.com
true true obs-local-part form as described in RFC 5322 Dominic Sayers http://www.dominicsayers.com/isemail 147
"first..last"@example.com
true true obs-local-part form as described in RFC 5322 Dominic Sayers http://www.dominicsayers.com/isemail 148
foo@[\1.2.3.4]
false false RFC 5321 specifies the syntax for address-literal and does not allow escaping Cal Henderson http://code.iamcal.com/php/rfc822/ 149
"first\\\"last"@example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 150
first."mid\dle"."last"@example.com
true true Backslash can escape anything but must escape something Dominic Sayers http://www.dominicsayers.com/isemail 151
Test. Folding. Whitespace@example.com
true false Dominic Sayers http://www.dominicsayers.com/isemail 152
first."".last@example.com
false false Contains a zero-length element Dominic Sayers http://www.dominicsayers.com/isemail 153
first\last@example.com
false false Unquoted string must be an atom Dominic Sayers http://www.dominicsayers.com/isemail 154
Abc\@def@example.com
false false Was incorrectly given as a valid address in the original RFC 3696 RFC 3696 erratum 246 http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=246 155
Fred\ Bloggs@example.com
false false Was incorrectly given as a valid address in the original RFC 3696 RFC 3696 erratum 246 http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=246 156
Joe.\\Blow@example.com
false false Was incorrectly given as a valid address in the original RFC 3696 RFC 3696 erratum 246 http://www.rfc-editor.org/errata_search.php?rfc=3696&eid=246 157
first.last@[IPv6:1111:2222:3333:4444:5555:6666:12.34.567.89]
false false IPv4 part contains an invalid octet Cal Henderson http://code.iamcal.com/php/rfc822/ 158
"test\ blah"@example.com
false false Folding white space can't appear within a quoted pair Cal Henderson http://code.iamcal.com/php/rfc822/ 159
"test blah"@example.com
true true This is a valid quoted string with folding white space Phil Haack http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx 160
{^c\@**Dog^}@cartoon.com
false false This is a throwaway example from Doug Lovell's article. Actually it's not a valid address. Doug Lovell (LinuxJournal, June 2007) http://www.linuxjournal.com/article/9585 161
(foo)cal(bar)@(baz)iamcal.com(quux)
true true A valid address containing comments Cal Henderson http://code.iamcal.com/php/rfc822/ 162
cal@iamcal(woo).(yay)com
true true A valid address containing comments Cal Henderson http://code.iamcal.com/php/rfc822/ 163
"foo"(yay)@(hoopla)[1.2.3.4]
false false Address literal can't be commented (RFC 5321) Cal Henderson http://code.iamcal.com/php/rfc822/ 164
cal(woo(yay)hoopla)@iamcal.com
true true A valid address containing comments Cal Henderson http://code.iamcal.com/php/rfc822/ 165
cal(foo\@bar)@iamcal.com
true true A valid address containing comments Cal Henderson http://code.iamcal.com/php/rfc822/ 166
cal(foo\)bar)@iamcal.com
true true A valid address containing comments and an escaped parenthesis Cal Henderson http://code.iamcal.com/php/rfc822/ 167
cal(foo(bar)@iamcal.com
false false Unclosed parenthesis in comment Cal Henderson http://code.iamcal.com/php/rfc822/ 168
cal(foo)bar)@iamcal.com
false false Too many closing parentheses Cal Henderson http://code.iamcal.com/php/rfc822/ 169
cal(foo\)@iamcal.com
false false Backslash at end of comment has nothing to escape Cal Henderson http://code.iamcal.com/php/rfc822/ 170
first().last@example.com
true true A valid address containing an empty comment Dominic Sayers http://www.dominicsayers.com/isemail 171
first.( middle )last@example.com
true true Comment with folding white space Dominic Sayers http://www.dominicsayers.com/isemail 172
first(12345678901234567890123456789012345678901234567890)last@(1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890)example.com
false false Too long with comments, not too long without Dominic Sayers http://www.dominicsayers.com/isemail 173
first(Welcome to the ("wonderful" (!)) world of email)@example.com
true true Silly example from my blog post Dominic Sayers http://www.dominicsayers.com/isemail 174
pete(his account)@silly.test(his host)
true true Canonical example from RFC 5322 RFC 5322 http://tools.ietf.org/html/rfc5322 175
c@(Chris's host.)public.example
true true Canonical example from RFC 5322 RFC 5322 http://tools.ietf.org/html/rfc5322 176
jdoe@machine(comment). example
true true Canonical example from RFC 5322 RFC 5322 http://tools.ietf.org/html/rfc5322 177
1234 @ local(blah) .machine .example
true true Canonical example from RFC 5322 RFC 5322 http://tools.ietf.org/html/rfc5322 178
first(middle)last@example.com
false false Can't have a comment or white space except at an element boundary Dominic Sayers http://www.dominicsayers.com/isemail 179
first(abc.def).last@example.com
true true Comment can contain a dot Dominic Sayers http://www.dominicsayers.com/isemail 180
first(a"bc.def).last@example.com
true true Comment can contain double quote Dominic Sayers http://www.dominicsayers.com/isemail 181
first.(")middle.last(")@example.com
true true Comment can contain a quote Dominic Sayers http://www.dominicsayers.com/isemail 182
first(abc("def".ghi).mno)middle(abc("def".ghi).mno).last@(abc("def".ghi).mno)example(abc("def".ghi).mno).(abc("def".ghi).mno)com(abc("def".ghi).mno)
false false Can't have comments or white space except at an element boundary Dominic Sayers http://www.dominicsayers.com/isemail 183
first(abc\(def)@example.com
true true Comment can contain quoted-pair Dominic Sayers http://www.dominicsayers.com/isemail 184
first.last@x(1234567890123456789012345678901234567890123456789012345678901234567890).com
true true Label is longer than 63 octets, but not with comment removed Cal Henderson http://code.iamcal.com/php/rfc822/ 185
a(a(b(c)d(e(f))g)h(i)j)@example.com
true true Cal Henderson http://code.iamcal.com/php/rfc822/ 186
a(a(b(c)d(e(f))g)(h(i)j)@example.com
false false Braces are not properly matched Cal Henderson http://code.iamcal.com/php/rfc822/ 187
name.lastname@domain.com
true false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 188
.@
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 189
a@b
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 190
@bar.com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 191
@@bar.com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 192
a@bar.com
true false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 193
aaa.com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 194
aaa@.com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 195
aaa@.123
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 196
aaa@[123.123.123.123]
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 197
aaa@[123.123.123.123]a
false false extra data outside ip Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 198
aaa@[123.123.123.333]
false false not a valid IP Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 199
a@bar.com.
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 200
a@bar
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 201
a-b@bar.com
true false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 202
+@b.c
true true TLDs can be any length Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 203
+@b.com
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 204
a@-b.com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 205
a@b-.com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 206
-@..com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 207
-@a..com
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 208
a@b.co-foo.uk
true false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 209
"hello my name is"@stutter.com
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 210
"Test \"Fail\" Ing"@example.com
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 211
valid@special.museum
true false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 212
invalid@special.museum-
false false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 213
shaitan@my-domain.thisisminekthx
true false Disagree with Paul Gregg here Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 214
test@...........com
false false ...... Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 215
foobar@192.168.0.1
true true ip need to be [] Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 216
"Joe\\Blow"@example.com
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 217
Invalid \ Folding \ Whitespace@example.com
false false Paul Gregg This isn't FWS so Dominic Sayers says it's invalid http://pgregg.com/projects/php/code/showvalidemail.php 218
HM2Kinsists@(that comments are allowed)this.is.ok
true true Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 219
user%uucp!path@somehost.edu
true false Paul Gregg http://pgregg.com/projects/php/code/showvalidemail.php 220
"first(last)"@example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 221
( x ) first ( x ) . ( x) last ( x ) @example.com
true true Dominic Sayers http://www.dominicsayers.com/isemail 222
test. obs@syntax.com
true true obs-fws allows multiple lines George Pollard http://porg.es/blog/properly-validating-e-mail-addresses 223
test. obs@syntax.com
true true obs-fws allows multiple lines (test 2: space before break) George Pollard http://porg.es/blog/properly-validating-e-mail-addresses 224
test. obs@syntax.com
false false obs-fws must have at least one WSP per line George Pollard http://porg.es/blog/properly-validating-e-mail-addresses 225
"null \\0"@char.com
true true can have escaped null character George Pollard http://porg.es/blog/properly-validating-e-mail-addresses 226
"null \0"@char.com
false false cannot have unescaped null character George Pollard http://porg.es/blog/properly-validating-e-mail-addresses 227
null\\0@char.com
false false escaped null must be in quoted string George Pollard http://porg.es/blog/properly-validating-e-mail-addresses 228
cdburgess+!#$%&'*-/=?+_{}|~test@gmail.com
true false Example given in comments cdburgess http://www.dominicsayers.com/isemail/#comment-30024957 229
first.last@[IPv6:::a2:a3:a4:b1:b2:b3:b4]
true true :: only elides one zero group (IPv6 authority is RFC 4291) Dominic Sayers http://www.dominicsayers.com/isemail 230
first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3::]
true true :: only elides one zero group (IPv6 authority is RFC 4291) Dominic Sayers http://www.dominicsayers.com/isemail 231
first.last@[IPv6::]
false false IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 232
first.last@[IPv6:::]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 233
first.last@[IPv6::::]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 234
first.last@[IPv6::b4]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 235
first.last@[IPv6:::b4]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 236
first.last@[IPv6::::b4]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 237
first.last@[IPv6::b3:b4]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 238
first.last@[IPv6:::b3:b4]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 239
first.last@[IPv6::::b3:b4]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 240
first.last@[IPv6:a1::b4]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 241
first.last@[IPv6:a1:::b4]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 242
first.last@[IPv6:a1:]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 243
first.last@[IPv6:a1::]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 244
first.last@[IPv6:a1:::]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 245
first.last@[IPv6:a1:a2:]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 246
first.last@[IPv6:a1:a2::]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 247
first.last@[IPv6:a1:a2:::]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 248
first.last@[IPv6:0123:4567:89ab:cdef::]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 249
first.last@[IPv6:0123:4567:89ab:CDEF::]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 250
first.last@[IPv6:::a3:a4:b1:ffff:11.22.33.44]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 251
first.last@[IPv6:::a2:a3:a4:b1:ffff:11.22.33.44]
true true :: only elides one zero group (IPv6 authority is RFC 4291) Dominic Sayers http://www.dominicsayers.com/isemail 252
first.last@[IPv6:a1:a2:a3:a4::11.22.33.44]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 253
first.last@[IPv6:a1:a2:a3:a4:b1::11.22.33.44]
true true :: only elides one zero group (IPv6 authority is RFC 4291) Dominic Sayers http://www.dominicsayers.com/isemail 254
first.last@[IPv6::11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 255
first.last@[IPv6::::11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 256
first.last@[IPv6:a1:11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 257
first.last@[IPv6:a1::11.22.33.44]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 258
first.last@[IPv6:a1:::11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 259
first.last@[IPv6:a1:a2::11.22.33.44]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 260
first.last@[IPv6:a1:a2:::11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 261
first.last@[IPv6:0123:4567:89ab:cdef::11.22.33.44]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 262
first.last@[IPv6:0123:4567:89ab:cdef::11.22.33.xx]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 263
first.last@[IPv6:0123:4567:89ab:CDEF::11.22.33.44]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 264
first.last@[IPv6:0123:4567:89ab:CDEFF::11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 265
first.last@[IPv6:a1::a4:b1::b4:11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 266
first.last@[IPv6:a1::11.22.33]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 267
first.last@[IPv6:a1::11.22.33.44.55]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 268
first.last@[IPv6:a1::b211.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 269
first.last@[IPv6:a1::b2:11.22.33.44]
true true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 270
first.last@[IPv6:a1::b2::11.22.33.44]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 271
first.last@[IPv6:a1::b3:]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 272
first.last@[IPv6::a2::b4]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 273
first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3:]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 274
first.last@[IPv6::a2:a3:a4:b1:b2:b3:b4]
false true IPv6 authority is RFC 4291 Dominic Sayers http://www.dominicsayers.com/isemail 275
00-report-prereqs.t100644000767000024 1271412772077134 17007 0ustar00rjbsstaff000000000000Email-Valid-1.202/t#!perl use strict; use warnings; # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.025 use Test::More tests => 1; use ExtUtils::MakeMaker; use File::Spec; # from $version::LAX my $lax_version_re = qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | (?:\.[0-9]+) (?:_[0-9]+)? ) | (?: v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? ) )/x; # hide optional CPAN::Meta modules from prereq scanner # and check if they are available my $cpan_meta = "CPAN::Meta"; my $cpan_meta_pre = "CPAN::Meta::Prereqs"; my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic # Verify requirements? my $DO_VERIFY_PREREQS = 1; sub _max { my $max = shift; $max = ( $_ > $max ) ? $_ : $max for @_; return $max; } sub _merge_prereqs { my ($collector, $prereqs) = @_; # CPAN::Meta::Prereqs object if (ref $collector eq $cpan_meta_pre) { return $collector->with_merged_prereqs( CPAN::Meta::Prereqs->new( $prereqs ) ); } # Raw hashrefs for my $phase ( keys %$prereqs ) { for my $type ( keys %{ $prereqs->{$phase} } ) { for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; } } } return $collector; } my @include = qw( ); my @exclude = qw( ); # Add static prereqs to the included modules list my $static_prereqs = do 't/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), $static_prereqs ); # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; if ( $source && $HAS_CPAN_META && (my $meta = eval { CPAN::Meta->load_file($source) } ) ) { $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } else { $source = 'static metadata'; } my @full_reports; my @dep_errors; my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; # Add static includes into a fake section for my $mod (@include) { $req_hash->{other}{modules}{$mod} = 0; } for my $phase ( qw(configure build test runtime develop other) ) { next unless $req_hash->{$phase}; next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); for my $type ( qw(requires recommends suggests conflicts modules) ) { next unless $req_hash->{$phase}{$type}; my $title = ucfirst($phase).' '.ucfirst($type); my @reports = [qw/Module Want Have/]; for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { next if $mod eq 'perl'; next if grep { $_ eq $mod } @exclude; my $file = $mod; $file =~ s{::}{/}g; $file .= ".pm"; my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; my $want = $req_hash->{$phase}{$type}{$mod}; $want = "undef" unless defined $want; $want = "any" if !$want && $want == 0; my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; if ($prefix) { my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); $have = "undef" unless defined $have; push @reports, [$mod, $want, $have]; if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { if ( $have !~ /\A$lax_version_re\z/ ) { push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; } elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { push @dep_errors, "$mod version '$have' is not in required range '$want'"; } } } else { push @reports, [$mod, $want, "missing"]; if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { push @dep_errors, "$mod is not installed ($req_string)"; } } } if ( @reports ) { push @full_reports, "=== $title ===\n\n"; my $ml = _max( map { length $_->[0] } @reports ); my $wl = _max( map { length $_->[1] } @reports ); my $hl = _max( map { length $_->[2] } @reports ); if ($type eq 'modules') { splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; } else { splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; } push @full_reports, "\n"; } } } if ( @full_reports ) { diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } if ( @dep_errors ) { diag join("\n", "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n", "The following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); } pass; # vim: ts=4 sts=4 sw=4 et: author000755000767000024 012772077134 14720 5ustar00rjbsstaff000000000000Email-Valid-1.202/xtpod-syntax.t100644000767000024 25212772077134 17332 0ustar00rjbsstaff000000000000Email-Valid-1.202/xt/author#!perl # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); 00-report-prereqs.dd100644000767000024 305612772077134 17112 0ustar00rjbsstaff000000000000Email-Valid-1.202/tdo { my $x = { 'develop' => { 'requires' => { 'Test::More' => '0', 'Test::Pod' => '1.41', 'XML::LibXML' => '0', 'utf8' => '0' } }, 'runtime' => { 'requires' => { 'Carp' => '0', 'File::Spec' => '0', 'IO::CaptureOutput' => '0', 'IO::File' => '0', 'Mail::Address' => '0', 'Net::DNS' => '0', 'Net::Domain::TLD' => '1.65', 'Scalar::Util' => '0', 'perl' => '5.006', 'strict' => '0', 'warnings' => '0' } }, 'test' => { 'recommends' => { 'CPAN::Meta' => '2.120900' }, 'requires' => { 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '0', 'Test::More' => '0.96' } } }; $x; }release000755000767000024 012772077134 15036 5ustar00rjbsstaff000000000000Email-Valid-1.202/xtchanges_has_content.t100644000767000024 201112772077134 21352 0ustar00rjbsstaff000000000000Email-Valid-1.202/xt/release#!perl use Test::More tests => 2; note 'Checking Changes'; my $changes_file = 'Changes'; my $newver = '1.202'; my $trial_token = '-TRIAL'; SKIP: { ok(-e $changes_file, "$changes_file file exists") or skip 'Changes is missing', 1; ok(_get_changes($newver), "$changes_file has content for $newver"); } done_testing; # _get_changes copied and adapted from Dist::Zilla::Plugin::Git::Commit # by Jerome Quelin sub _get_changes { my $newver = shift; # parse changelog to find commit message open(my $fh, '<', $changes_file) or die "cannot open $changes_file: $!"; my $changelog = join('', <$fh>); close $fh; my @content = grep { /^$newver(?:$trial_token)?(?:\s+|$)/ ... /^\S/ } # from newver to un-indented split /\n/, $changelog; shift @content; # drop the version line # drop unindented last line and trailing blank lines pop @content while ( @content && $content[-1] =~ /^(?:\S|\s*$)/ ); # return number of non-blank lines return scalar @content; }