File Coverage

blib/lib/Parse/PMFile.pm
Criterion Covered Total %
statement 330 494 66.8
branch 154 254 60.6
condition 54 143 37.7
subroutine 32 41 78.0
pod 2 2 100.0
total 572 934 61.2


line stmt bran cond sub pod time code
1             package Parse::PMFile;
2              
3 134     134   24306 sub __clean_eval { eval $_[0] } # needs to be here (RT#101273)
4              
5 67     67   8402002 use strict;
  67         154  
  67         2711  
6 67     67   664 use warnings;
  67         176  
  67         4174  
7 67     67   44653 use Safe;
  67         847433  
  67         2711  
8 67     67   52661 use JSON::PP ();
  67         1602482  
  67         2599  
9 67     67   40075 use Dumpvalue;
  67         427138  
  67         3467  
10 67     67   36974 use version ();
  67         152968  
  67         2444  
11 67     67   486 use File::Spec ();
  67         110  
  67         107914  
12              
13             our $VERSION = '0.48';
14             our $VERBOSE = 0;
15             our $ALLOW_DEV_VERSION = 0;
16             our $FORK = 0;
17             our $UNSAFE = $] < 5.010000 ? 1 : 0;
18              
19             sub new {
20 313     313 1 14425796 my ($class, $meta, $opts) = @_;
21 313 100       981 bless {%{ $opts || {} }, META_CONTENT => $meta}, $class;
  313         4583  
22             }
23              
24             # from PAUSE::pmfile::examine_fio
25             sub parse {
26 314     314 1 12010 my ($self, $pmfile) = @_;
27              
28 314         1186 $pmfile =~ s|\\|/|g;
29              
30 314         8495 my($filemtime) = (stat $pmfile)[9];
31 314         1700 $self->{MTIME} = $filemtime;
32 314         1010 $self->{PMFILE} = $pmfile;
33              
34 314 100       1325 unless ($self->_version_from_meta_ok) {
35 308         616 my $version;
36 308 50       714 unless (eval { $version = $self->_parse_version; 1 }) {
  308         1590  
  267         1234  
37 0         0 $self->_verbose(1, "error with version in $pmfile: $@");
38 0         0 return;
39             }
40              
41 267         1221 $self->{VERSION} = $version;
42 267 50 66     4140 if ($self->{VERSION} =~ /^\{.*\}$/) {
    100 100        
43             # JSON error message
44             } elsif ($self->{VERSION} =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){ # ignore developer releases and "You suck!"
45 5         51 return;
46             }
47             }
48              
49 268         2593 my($ppp) = $self->_packages_per_pmfile;
50 268         2285 my @keys_ppp = $self->_filter_ppps(sort keys %$ppp);
51 268         1615 $self->_verbose(1,"Will check keys_ppp[@keys_ppp]\n");
52              
53             #
54             # Immediately after each package (pmfile) examined contact
55             # the database
56             #
57              
58 268         898 my ($package, %errors);
59 268         0 my %checked_in;
60 268         769 DBPACK: foreach $package (@keys_ppp) {
61             # this part is taken from PAUSE::package::examine_pkg
62             # and PAUSE::package::_pkg_name_insane
63 268 50 33     8926 if ($package !~ /^\w[\w\:\']*\w?\z/
      33        
      33        
      33        
      33        
64             || $package !~ /\w\z/
65             || $package =~ /:/ && $package !~ /::/
66             || $package =~ /\w:\w/
67             || $package =~ /:::/
68             ){
69 0         0 $self->_verbose(1,"Package[$package] did not pass the ultimate sanity check");
70 0         0 delete $ppp->{$package};
71 0         0 next;
72             }
73              
74 268 0 33     1321 if ($self->{USERID} && $self->{PERMISSIONS} && !$self->_perm_check($package)) {
      0        
75 0         0 delete $ppp->{$package};
76 0         0 next;
77             }
78              
79             # Check that package name matches case of file name
80             {
81 268         444 my (undef, $module) = split m{/lib/}, $self->{PMFILE}, 2;
  268         1804  
82 268 100       905 if ($module) {
83 6         74 $module =~ s{\.pm\z}{};
84 6         24 $module =~ s{/}{::}g;
85              
86 6 50 33     49 if (lc $module eq lc $package && $module ne $package) {
87             # warn "/// $self->{PMFILE} vs. $module vs. $package\n";
88             $errors{$package} = {
89             indexing_warning => "Capitalization of package ($package) does not match filename!",
90             infile => $self->{PMFILE},
91 0         0 };
92             }
93             }
94             }
95              
96 268         647 my $pp = $ppp->{$package};
97 268 50 66     2626 if ($pp->{version} && $pp->{version} =~ /^\{.*\}$/) { # JSON parser error
98 0         0 my $err = JSON::PP::decode_json($pp->{version});
99 0 0       0 if ($err->{x_normalize}) {
    0          
100             $errors{$package} = {
101             normalize => $err->{version},
102             infile => $pp->{infile},
103 0         0 };
104 0         0 $pp->{version} = "undef";
105             } elsif ($err->{openerr}) {
106 0         0 $pp->{version} = "undef";
107 0         0 $self->_verbose(1,
108             qq{Parse::PMFile was not able to
109             read the file. It issued the following error: C< $err->{r} >},
110             );
111             $errors{$package} = {
112             open => $err->{r},
113             infile => $pp->{infile},
114 0         0 };
115             } else {
116 0         0 $pp->{version} = "undef";
117 0         0 $self->_verbose(1,
118             qq{Parse::PMFile was not able to
119             parse the following line in that file: C< $err->{line} >
120              
121             Note: the indexer is running in a Safe compartement and cannot
122             provide the full functionality of perl in the VERSION line. It
123             is trying hard, but sometime it fails. As a workaround, please
124             consider writing a META.yml that contains a 'provides'
125             attribute or contact the CPAN admins to investigate (yet
126             another) workaround against "Safe" limitations.)},
127              
128             );
129             $errors{$package} = {
130             parse_version => $err->{line},
131             infile => $err->{file},
132 0         0 };
133             }
134             }
135              
136             # Sanity checks
137              
138 268         858 for (
139             $package,
140             $pp->{version},
141             ) {
142 536 50 66     4954 if (!defined || /^\s*$/ || /\s/){ # for whatever reason I come here
      66        
143 4         10 delete $ppp->{$package};
144 4         14 next; # don't screw up 02packages
145             }
146             }
147 268 100       1576 unless ($self->_version_ok($pp)) {
148             $errors{$package} = {
149             long_version => qq{Version string exceeds maximum allowed length of 16b: "$pp->{version}"},
150             infile => $pp->{infile},
151 3         30 };
152 3         9 next;
153             }
154 265         6497 $checked_in{$package} = $ppp->{$package};
155             } # end foreach package
156              
157 268 100 66     2981 return (wantarray && %errors) ? (\%checked_in, \%errors) : \%checked_in;
158             }
159              
160             sub _version_ok {
161 268     268   766 my ($self, $pp) = @_;
162 268 100 100     1340 return if length($pp->{version} || 0) > 16;
163 265         969 return 1
164             }
165              
166             sub _perm_check {
167 0     0   0 my ($self, $package) = @_;
168 0         0 my $userid = $self->{USERID};
169 0         0 my $module = $self->{PERMISSIONS}->module_permissions($package);
170 0 0       0 return 1 if !$module; # not listed yet
171 0 0 0     0 return 1 if defined $module->m && $module->m eq $userid;
172 0 0 0     0 return 1 if defined $module->f && $module->f eq $userid;
173 0 0 0     0 return 1 if defined $module->c && grep {$_ eq $userid} @{$module->c};
  0         0  
  0         0  
174 0         0 return;
175             }
176              
177             # from PAUSE::pmfile;
178             sub _parse_version {
179 308     308   783 my $self = shift;
180              
181 67     67   806 use strict;
  67         152  
  67         26387  
182              
183 308         822 my $pmfile = $self->{PMFILE};
184 308         37239 my $tmpfile = File::Spec->catfile(File::Spec->tmpdir, "ParsePMFile$$" . rand(1000));
185              
186 308         1256 my $pmcp = $pmfile;
187 308         1155 for ($pmcp) {
188 308         1451 s/([^\\](\\\\)*)@/$1\\@/g; # thanks to Raphael Manfredi for the
189             # solution to escape @s and \
190             }
191 308         677 my($v);
192             {
193              
194 308         614 package main; # seems necessary
195              
196             # XXX: do we need to fork as PAUSE does?
197             # or, is alarm() just fine?
198 308         471 my $pid;
199 308 100 66     2563 if ($self->{FORK} || $FORK) {
200 153         359866 $pid = fork();
201 153 50       14386 die "Can't fork: $!" unless defined $pid;
202             }
203 308 100       4690 if ($pid) {
204 112         68055146 waitpid($pid, 0);
205 112 50       24255 if (open my $fh, '<', $tmpfile) {
206 112         14709 $v = <$fh>;
207             }
208             } else {
209             # XXX Limit Resources too
210              
211 196         4955 my $comp;
212 196         2078 my $eval = qq{
213             local(\$^W) = 0;
214             Parse::PMFile::_parse_version_safely("$pmcp");
215             };
216 196 50 33     4683 unless ($self->{UNSAFE} || $UNSAFE) {
217 196         10239 $comp = Safe->new;
218 196         452483 $comp->permit("entereval"); # for MBARBON/Module-Info-0.30.tar.gz
219 196         3494 $comp->share("*Parse::PMFile::_parse_version_safely");
220 196         28436 $comp->share("*version::new");
221 196         12315 $comp->share("*version::numify");
222 196         11662 $comp->share_from('main', ['*version::',
223             '*charstar::',
224             '*Exporter::',
225             '*DynaLoader::']);
226 196         283467 $comp->share_from('version', ['&qv']);
227 196         11270 $comp->permit(":base_math"); # atan2 (Acme-Pi)
228             # $comp->permit("require"); # no strict!
229 196         2440 $comp->deny(qw/enteriter iter unstack goto/); # minimum protection against Acme::BadExample
230             }
231              
232 196 50 33     9163 version->import('qv') if $self->{UNSAFE} || $UNSAFE;
233             {
234 67     67   537 no strict;
  67         155  
  67         35704  
  196         1344  
235 196 50       3096 $v = $comp ? $comp->reval($eval) : eval $eval;
236             }
237 196 100       245076 if ($@){ # still in the child process, out of Safe::reval
238 21         117 my $err = $@;
239             # warn ">>>>>>>err[$err]<<<<<<<<";
240 21 50       201 if (ref $err) {
241 21 50       597 if ($err->{line} =~ /([\$*])([\w\:\']*)\bVERSION\b.*?\=(.*)/) {
242 21         250 local($^W) = 0;
243 21         251 my ($sigil, $vstr) = ($1, $3);
244 21 50       519 $self->_restore_overloaded_stuff(1) if $err->{line} =~ /use\s+version\b|version\->|qv\(/;
245 21 50       129 $v = $comp ? $comp->reval($vstr) : eval $vstr;
246 21 50 33     25684 $v = $$v if $sigil eq '*' && ref $v;
247             }
248 21 50 33     485 if ($@ or !$v) {
249 0         0 $self->_verbose(1, sprintf("reval failed: err[%s] for eval[%s]",
250             JSON::PP::encode_json($err),
251             $eval,
252             ));
253 0         0 $v = JSON::PP::encode_json($err);
254             }
255             } else {
256 0         0 $v = JSON::PP::encode_json({ openerr => $err });
257             }
258             }
259 196 50       1345 if (defined $v) {
260 67     67   531 no warnings;
  67         177  
  67         22032  
261 196 100       1987 $v = $v->numify if ref($v) =~ /^version(::vpp)?$/;
262             } else {
263 0         0 $v = "";
264             }
265 196 100 66     3976 if ($self->{FORK} || $FORK) {
266 41         13532 open my $fh, '>:utf8', $tmpfile;
267 41         1371 print $fh $v;
268 41         3604 exit 0;
269             } else {
270 155         788 utf8::encode($v);
271             # undefine empty $v as if read from the tmpfile
272 155 50 33     1024 $v = undef if defined $v && !length $v;
273 155 50       1029 $comp->erase if ($comp);
274 155         206775 $self->_restore_overloaded_stuff;
275             }
276             }
277             }
278 267 100 66     67828 unlink $tmpfile if ($self->{FORK} || $FORK) && -e $tmpfile;
      66        
279              
280 267         19674 return $self->_normalize_version($v);
281             }
282              
283             sub _restore_overloaded_stuff {
284 176     176   746 my ($self, $used_version_in_safe) = @_;
285 176 50 33     1806 return if $self->{UNSAFE} || $UNSAFE;
286              
287 67     67   501 no strict 'refs';
  67         128  
  67         2318  
288 67     67   294 no warnings 'redefine';
  67         98  
  67         109816  
289              
290             # version XS in CPAN
291 176         386 my $restored;
292 176 50       655 if ($INC{'version/vxs.pm'}) {
293 0         0 *{'version::(""'} = \&version::vxs::stringify;
  0         0  
294 0         0 *{'version::(0+'} = \&version::vxs::numify;
  0         0  
295 0         0 *{'version::(cmp'} = \&version::vxs::VCMP;
  0         0  
296 0         0 *{'version::(<=>'} = \&version::vxs::VCMP;
  0         0  
297 0         0 *{'version::(bool'} = \&version::vxs::boolean;
  0         0  
298 0         0 $restored = 1;
299             }
300             # version PP in CPAN
301 176 50       690 if ($INC{'version/vpp.pm'}) {
302             {
303 0         0 package # hide from PAUSE
304             charstar;
305 0         0 overload->import;
306             }
307 0 0       0 if (!$used_version_in_safe) {
308             package # hide from PAUSE
309             version::vpp;
310 0         0 overload->import;
311             }
312 0 0       0 unless ($restored) {
313 0         0 *{'version::(""'} = \&version::vpp::stringify;
  0         0  
314 0         0 *{'version::(0+'} = \&version::vpp::numify;
  0         0  
315 0         0 *{'version::(cmp'} = \&version::vpp::vcmp;
  0         0  
316 0         0 *{'version::(<=>'} = \&version::vpp::vcmp;
  0         0  
317 0         0 *{'version::(bool'} = \&version::vpp::vbool;
  0         0  
318             }
319 0         0 *{'version::vpp::(""'} = \&version::vpp::stringify;
  0         0  
320 0         0 *{'version::vpp::(0+'} = \&version::vpp::numify;
  0         0  
321 0         0 *{'version::vpp::(cmp'} = \&version::vpp::vcmp;
  0         0  
322 0         0 *{'version::vpp::(<=>'} = \&version::vpp::vcmp;
  0         0  
323 0         0 *{'version::vpp::(bool'} = \&version::vpp::vbool;
  0         0  
324 0         0 *{'charstar::(""'} = \&charstar::thischar;
  0         0  
325 0         0 *{'charstar::(0+'} = \&charstar::thischar;
  0         0  
326 0         0 *{'charstar::(++'} = \&charstar::increment;
  0         0  
327 0         0 *{'charstar::(--'} = \&charstar::decrement;
  0         0  
328 0         0 *{'charstar::(+'} = \&charstar::plus;
  0         0  
329 0         0 *{'charstar::(-'} = \&charstar::minus;
  0         0  
330 0         0 *{'charstar::(*'} = \&charstar::multiply;
  0         0  
331 0         0 *{'charstar::(cmp'} = \&charstar::cmp;
  0         0  
332 0         0 *{'charstar::(<=>'} = \&charstar::spaceship;
  0         0  
333 0         0 *{'charstar::(bool'} = \&charstar::thischar;
  0         0  
334 0         0 *{'charstar::(='} = \&charstar::clone;
  0         0  
335 0         0 $restored = 1;
336             }
337             # version in core
338 176 50       519 if (!$restored) {
339 176         800 *{'version::(""'} = \&version::stringify;
  176         843  
340 176         413 *{'version::(0+'} = \&version::numify;
  176         454  
341 176         350 *{'version::(cmp'} = \&version::vcmp;
  176         498  
342 176         12723 *{'version::(<=>'} = \&version::vcmp;
  176         514  
343 176         366 *{'version::(bool'} = \&version::boolean;
  176         1446  
344             }
345             }
346              
347             # from PAUSE::pmfile;
348             sub _packages_per_pmfile {
349 268     268   747 my $self = shift;
350              
351 268         640 my $ppp = {};
352 268         1248 my $pmfile = $self->{PMFILE};
353 268         745 my $filemtime = $self->{MTIME};
354 268         886 my $version = $self->{VERSION};
355              
356 268 50       15707 open my $fh, "<", "$pmfile" or return $ppp;
357              
358 268         3110 local $/ = "\n";
359 268         592 my $inpod = 0;
360              
361 268         747 my $package_or_class = 'package';
362 268         678 my $checked_bom;
363 268         7332 PLINE: while (<$fh>) {
364 6228         7818 chomp;
365 6228         7969 my($pline) = $_;
366 6228 100       10329 $pline =~ s/\A(?:\x00\x00\xfe\xff|\xff\xfe\x00\x00|\xfe\xff|\xff\xfe|\xef\xbb\xbf)// unless $checked_bom;
367 6228         6897 $checked_bom = 1;
368 6228 100       11745 $inpod = $pline =~ /^=(?!cut)/ ? 1 :
    100          
369             $pline =~ /^=cut/ ? 0 : $inpod;
370 6228 100       11563 next if $inpod;
371 6168 100       10798 next if substr($pline,0,4) eq "=cut";
372              
373 6162         8678 $pline =~ s/\#.*//;
374 6162 100       15538 next if $pline =~ /^\s*$/;
375 4888 100 66     10029 if ($pline =~ /^__(?:END|DATA)__\b/
376             and $pmfile !~ /\.PL$/ # PL files may well have code after __DATA__
377             ){
378 9         33 last PLINE;
379             }
380              
381             =pod
382             # hide in the pod block until 'class' is added to a version bundle
383             if ($pline =~ /^[\s\{;]*use\s(+v?5\.[0-9]+)/) {
384             my $version = $1;
385             my $version_bundle_for_class = version->parse("v5.xx.xx");
386             if (eval { version->parse($version) >= $version_bundle_for_class) {
387             $package_or_class = 'package|class|role';
388             }
389             next PLINE;
390             }
391             =cut
392              
393             # use feature 'class'; enabels class (and role, though not implemented yet)
394 4879 100       9071 if ($pline =~ /^[\s\{;]*use\s+(?:feature|experimental)\s+[^;]+\b(?:class|all)[^;]*;/) {
395 120         431 $package_or_class = 'package|class';
396             }
397              
398             # some modules also enables class and role
399 4879 50       7946 if ($pline =~ /^[\s\{;]*use\s+(?:Feature::Compat::Class)[^;]*;/) {
400 0         0 $package_or_class = 'package|class';
401             }
402 4879 100       8082 if ($pline =~ /^[\s\{;]*use\s+(?:Object::Pad)[^;]*;/) {
403 48         155 $package_or_class = 'package|class|role';
404             }
405              
406 4879         5725 my $pkg;
407             my $strict_version;
408              
409 4879 100       50247 if (
410             # If you change *anything* here, it needs changing in '_parse_version_safely' too
411             $pline =~ m{
412             # (.*) # takes too much time if $pline is long
413             #(?
414             ^[\s\{;]*
415             \b(?:$package_or_class)\s+
416             ([\w\:\']+)
417             \s*
418             (?: $ | [\}\;\:] | \{ | \s+($version::STRICT) )
419             }x) {
420 277         1631 $pkg = $1;
421 277         688 $strict_version = $2;
422 277 50       849 if ($pkg eq "DB"){
423             # XXX if pumpkin and perl make him comaintainer! I
424             # think I always made the pumpkins comaint on DB
425             # without further ado (?)
426 0         0 next PLINE;
427             }
428             }
429              
430 4879 100       12063 if ($pkg) {
431             # Found something
432              
433             # from package
434 277         867 $pkg =~ s/\'/::/g;
435 277 50       1647 next PLINE unless $pkg =~ /^[A-Za-z]/;
436 277 50       1357 next PLINE unless $pkg =~ /\w$/;
437 277 100       908 next PLINE if $pkg eq "main";
438             # Perl::Critic::Policy::TestingAndDebugging::ProhibitShebangWarningsArg
439             # database for modid in mods, package in packages, package in perms
440             # alter table mods modify modid varchar(128) binary NOT NULL default '';
441             # alter table packages modify package varchar(128) binary NOT NULL default '';
442 271 50       970 next PLINE if length($pkg) > 128;
443             #restriction
444 271         1796 $ppp->{$pkg}{parsed}++;
445 271         1139 $ppp->{$pkg}{infile} = $pmfile;
446 271 100       1349 if ($self->_simile($pmfile,$pkg)) {
447 265         1097 $ppp->{$pkg}{simile} = $pmfile;
448 265 100       1361 if ($self->_version_from_meta_ok) {
449 6         23 my $provides = $self->{META_CONTENT}{provides};
450 6 50       20 if (exists $provides->{$pkg}) {
451 6 50       18 if (defined $provides->{$pkg}{version}) {
452 6         22 my $v = $provides->{$pkg}{version};
453 6 100 33     132 if ($v =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){ # ignore developer releases and "You suck!"
      66        
454 4         44 next PLINE;
455             }
456              
457 2 50       15 unless (eval { $version = $self->_normalize_version($v); 1 }) {
  2         13  
  2         17  
458 0         0 $self->_verbose(1, "error with version in $pmfile: $@");
459 0         0 next;
460              
461             }
462 2         13 $ppp->{$pkg}{version} = $version;
463             } else {
464 0         0 $ppp->{$pkg}{version} = "undef";
465             }
466             }
467             } else {
468 259 100       792 if (defined $strict_version){
469 19         70 $ppp->{$pkg}{version} = $strict_version ;
470             } else {
471 240 50       999 $ppp->{$pkg}{version} = defined $version ? $version : "";
472             }
473 67     67   572 no warnings;
  67         146  
  67         22212  
474 259 100       733 if ($version eq 'undef') {
475 75 50       250 $ppp->{$pkg}{version} = $version unless defined $ppp->{$pkg}{version};
476             } else {
477             $ppp->{$pkg}{version} =
478             $version
479             if $version
480             > $ppp->{$pkg}{version} ||
481             $version
482 184 50 33     1868 gt $ppp->{$pkg}{version};
483             }
484             }
485             } else { # not simile
486             #### it comes later, it would be nonsense
487             #### to set to "undef". MM_Unix gives us
488             #### the best we can reasonably consider
489             $ppp->{$pkg}{version} =
490             $version
491             unless defined $ppp->{$pkg}{version} &&
492 6 50 33     17 length($ppp->{$pkg}{version});
493             }
494 267         907 $ppp->{$pkg}{filemtime} = $filemtime;
495 267         2197 $ppp->{$pkg}{version} .= ""; # make sure to stringify version
496             } else {
497             # $self->_verbose(2,"no pkg found");
498             }
499             }
500              
501 268         3910 close $fh;
502 268         3502 $ppp;
503             }
504              
505             # from PAUSE::pmfile;
506             {
507 67     67   591 no strict;
  67         133  
  67         70847  
508             sub _parse_version_safely {
509 196     196   120354 my($parsefile) = @_;
510 196         821 my $result;
511 196         1479 local *FH;
512 196         3002 local $/ = "\n";
513 196 50       15959 open(FH,$parsefile) or die "Could not open '$parsefile': $!";
514 196         1658 my $inpod = 0;
515 196         1647 my $package_or_class = 'package';
516 196         9719 while () {
517 559 50       4150 $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod;
    50          
518 559 50 33     5483 next if $inpod || /^\s*#/;
519 559 100       2337 last if /^__(?:END|DATA)__\b/; # fails on quoted __END__ but this is rare -> __END__ in the middle of a line is rarer
520 556         1477 chop;
521              
522             # use feature 'class'; enabels class (and role, though not implemented yet)
523 556 100       2990 if (/^[\s\{;]*use\s+(?:feature|experimental)\s+[^;]+\b(?:class|all)[^;]*;/) {
524 75         397 $package_or_class = 'package|class';
525             }
526              
527             # some modules also enables class and role
528             # XXX: what to do with MooseX::Declare and a few minor experiments)
529 556 50       1782 if (/^[\s\{;]*use\s+(?:Feature::Compat::Class)[^;]*;/) {
530 0         0 $package_or_class = 'package|class';
531             }
532 556 100       2006 if (/^[\s\{;]*use\s+(?:Object::Pad)[^;]*;/) {
533 33         90 $package_or_class = 'package|class|role';
534             }
535              
536             # If you change *anything* here, it needs changing in '_packages_per_pmfile' too
537 556 100       16253 if (my ($ver) = /$package_or_class \s+ \S+ \s+ (\S+) \s* [:;{]/x) {
538             # XXX: should handle this better if version is bogus -- rjbs,
539             # 2014-03-16
540 39 100       2905 return $ver if version::is_lax($ver);
541             }
542              
543             # next unless /\$(([\w\:\']*)\bVERSION)\b.*\=/;
544 539 100       7219 next unless /(?<=])\=(?![=>])/;
545 134         429 my $current_parsed_line = $_;
546 134         2272 my $eval = qq{
547             package #
548             ExtUtils::MakeMaker::_version;
549              
550             local $1$2;
551             \$$2=undef; do {
552             $_
553             }; \$$2
554             };
555 134         1595 local $^W = 0;
556 134     0   2375 local $SIG{__WARN__} = sub {};
557 134         1815 $result = __clean_eval($eval);
558             # warn "current_parsed_line[$current_parsed_line]\$\@[$@]";
559 134 100 66     1514 if ($@ or !defined $result){
560 21         1489 die +{
561             eval => $eval,
562             line => $current_parsed_line,
563             file => $parsefile,
564             err => $@,
565             };
566             }
567 113         715 last;
568             } #;
569 158         3202 close FH;
570              
571 158 100       809 $result = "undef" unless defined $result;
572 158 100       1073 if ((ref $result) =~ /^version(?:::vpp)?\b/) {
573 67     67   870 no warnings;
  67         191  
  67         63764  
574 6         55 $result = $result->numify;
575             }
576 158         5782 return $result;
577             }
578             }
579              
580             # from PAUSE::pmfile;
581             sub _filter_ppps {
582 268     268   1066 my($self,@ppps) = @_;
583 268         525 my @res;
584              
585             # very similar code is in PAUSE::dist::filter_pms
586 268         806 MANI: for my $ppp ( @ppps ) {
587 271 100       1014 if ($self->{META_CONTENT}){
588             my $no_index = $self->{META_CONTENT}{no_index}
589 9   66     64 || $self->{META_CONTENT}{private}; # backward compat
590 9 100       33 if (ref($no_index) eq 'HASH') {
591 3         47 my %map = (
592             package => qr{\z},
593             namespace => qr{::},
594             );
595 3         7 for my $k (qw(package namespace)) {
596 3 50       15 next unless my $v = $no_index->{$k};
597 3         4 my $rest = $map{$k};
598 3 50       11 if (ref $v eq "ARRAY") {
599 3         6 for my $ve (@$v) {
600 3         7 $ve =~ s|::$||;
601 3 50       38 if ($ppp =~ /^$ve$rest/){
602 3         16 $self->_verbose(1,"Skipping ppp[$ppp] due to ve[$ve]");
603 3         15 next MANI;
604             } else {
605 0         0 $self->_verbose(1,"NOT skipping ppp[$ppp] due to ve[$ve]");
606             }
607             }
608             } else {
609 0         0 $v =~ s|::$||;
610 0 0       0 if ($ppp =~ /^$v$rest/){
611 0         0 $self->_verbose(1,"Skipping ppp[$ppp] due to v[$v]");
612 0         0 next MANI;
613             } else {
614 0         0 $self->_verbose(1,"NOT skipping ppp[$ppp] due to v[$v]");
615             }
616             }
617             }
618             } else {
619 6         24 $self->_verbose(1,"No keyword 'no_index' or 'private' in META_CONTENT");
620             }
621             } else {
622             # $self->_verbose(1,"no META_CONTENT"); # too noisy
623             }
624 268         897 push @res, $ppp;
625             }
626 268         1675 $self->_verbose(1,"Result of filter_ppps: res[@res]");
627 268         933 @res;
628             }
629              
630             # from PAUSE::pmfile;
631             sub _simile {
632 271     271   1167 my($self,$file,$package) = @_;
633             # MakeMaker gives them the chance to have the file Simple.pm in
634             # this directory but have the package HTML::Simple in it.
635             # Afaik, they wouldn't be able to do so with deeper nested packages
636 271         2779 $file =~ s|.*/||;
637 271         1741 $file =~ s|\.pm(?:\.PL)?||;
638 271         3385 my $ret = $package =~ m/\b\Q$file\E$/;
639 271   100     906 $ret ||= 0;
640 271 100       704 unless ($ret) {
641             # Apache::mod_perl_guide stuffs it into Version.pm
642 6 50       12 $ret = 1 if lc $file eq 'version';
643             }
644 271         1900 $self->_verbose(1,"Result of simile(): file[$file] package[$package] ret[$ret]\n");
645 271         1018 $ret;
646             }
647              
648             # from PAUSE::pmfile
649             sub _normalize_version {
650 269     269   1706 my($self,$v) = @_;
651 269 50       1378 $v = "undef" unless defined $v;
652 269         5651 my $dv = Dumpvalue->new;
653 269         20685 my $sdv = $dv->stringify($v,1); # second argument prevents ticks
654 269         24274 $self->_verbose(1,"Result of normalize_version: sdv[$sdv]\n");
655              
656 269 100       4237 return $v if $v eq "undef";
657 194 50       1969 return $v if $v =~ /^\{.*\}$/; # JSON object
658 194         1203 $v =~ s/^\s+//;
659 194         1127 $v =~ s/\s+\z//;
660 194 100       1500 if ($v =~ /_/) {
661             # XXX should pass something like EDEVELOPERRELEASE up e.g.
662             # SIXTEASE/XML-Entities-0.0306.tar.gz had nothing but one
663             # such modules and the mesage was not helpful that "nothing
664             # was found".
665 10         159 return $v ;
666             }
667 184 50       1975 if (!version::is_lax($v)) {
668 0         0 return JSON::PP::encode_json({ x_normalize => 'version::is_lax failed', version => $v });
669             }
670             # may warn "Integer overflow"
671 67     67   688 my $vv = eval { no warnings; version->new($v)->numify };
  67         519  
  67         11371  
  184         11881  
  184         4989  
672 184 50       1038 if ($@) {
673             # warn "$v: $@";
674 0         0 return JSON::PP::encode_json({ x_normalize => $@, version => $v });
675             # return "undef";
676             }
677 184 100       803 if ($vv eq $v) {
678             # the boring 3.14
679             } else {
680 157         761 my $forced = $self->_force_numeric($v);
681 157 50       995 if ($forced eq $vv) {
    50          
682             } elsif ($forced =~ /^v(.+)/) {
683             # rare case where a v1.0.23 slipped in (JANL/w3mir-1.0.10.tar.gz)
684 67     67   694 no warnings;
  67         734  
  67         133517  
685 0         0 $vv = version->new($1)->numify;
686             } else {
687             # warn "Unequal forced[$forced] and vv[$vv]";
688 157 50       1496 if ($forced == $vv) {
689             # the trailing zeroes would cause unnecessary havoc
690 157         395 $vv = $forced;
691             }
692             }
693             }
694 184         3277 return $vv;
695             }
696              
697             # from PAUSE::pmfile;
698             sub _force_numeric {
699 157     157   550 my($self,$v) = @_;
700 157         1446 $v = $self->_readable($v);
701              
702 157 50 33     3033 if (
      33        
703             $v =~
704             /^(\+?)(\d*)(\.(\d*))?/ &&
705             # "$2$4" ne ''
706             (
707             defined $2 && length $2
708             ||
709             defined $4 && length $4
710             )
711             ) {
712 157 50       680 my $two = defined $2 ? $2 : "";
713 157 50       1258 my $three = defined $3 ? $3 : "";
714 157         436 $v = "$two$three";
715             }
716             # no else branch! We simply say, everything else is a string.
717 157         465 $v;
718             }
719              
720             # from PAUSE::dist
721             sub _version_from_meta_ok {
722 579     579   1377 my($self) = @_;
723 579 100       7753 return $self->{VERSION_FROM_META_OK} if exists $self->{VERSION_FROM_META_OK};
724 313         704 my $c = $self->{META_CONTENT};
725              
726             # If there's no provides hash, we can't get our module versions from the
727             # provides hash! -- rjbs, 2012-03-31
728 313 100       2384 return($self->{VERSION_FROM_META_OK} = 0) unless $c->{provides};
729              
730             # Some versions of Module::Build geneated an empty provides hash. If we're
731             # *not* looking at a Module::Build-generated metafile, then it's okay.
732 6 50       33 my ($mb_v) = (defined $c->{generated_by} ? $c->{generated_by} : '') =~ /Module::Build version ([\d\.]+)/;
733 6 50       57 return($self->{VERSION_FROM_META_OK} = 1) unless $mb_v;
734              
735             # ??? I don't know why this is here.
736 0 0       0 return($self->{VERSION_FROM_META_OK} = 1) if $mb_v eq '0.250.0';
737              
738 0 0 0     0 if ($mb_v >= 0.19 && $mb_v < 0.26 && ! keys %{$c->{provides}}) {
  0   0     0  
739             # RSAVAGE/Javascript-SHA1-1.01.tgz had an empty provides hash. Ron
740             # did not find the reason why this happened, but let's not go
741             # overboard, 0.26 seems a good threshold from the statistics: there
742             # are not many empty provides hashes from 0.26 up.
743 0         0 return($self->{VERSION_FROM_META_OK} = 0);
744             }
745              
746             # We're not in the suspect range of M::B versions. It's good to go.
747 0         0 return($self->{VERSION_FROM_META_OK} = 1);
748             }
749              
750             sub _verbose {
751 1085     1085   2814 my($self,$level,@what) = @_;
752 1085 50 33     9405 warn @what if $level <= ((ref $self && $self->{VERBOSE}) || $VERBOSE);
753             }
754              
755             # all of the following methods are stripped from CPAN::Version
756             # (as of version 5.5001, bundled in CPAN 2.03), and slightly
757             # modified (ie. made private, as well as CPAN->debug(...) are
758             # replaced with $self->_verbose(9, ...).)
759              
760             # CPAN::Version::vcmp courtesy Jost Krieger
761             sub _vcmp {
762 0     0   0 my($self,$l,$r) = @_;
763 0         0 local($^W) = 0;
764 0         0 $self->_verbose(9, "l[$l] r[$r]");
765              
766 0 0       0 return 0 if $l eq $r; # short circuit for quicker success
767              
768 0         0 for ($l,$r) {
769 0         0 s/_//g;
770             }
771 0         0 $self->_verbose(9, "l[$l] r[$r]");
772 0         0 for ($l,$r) {
773 0 0 0     0 next unless tr/.// > 1 || /^v/;
774 0         0 s/^v?/v/;
775 0         0 1 while s/\.0+(\d)/.$1/; # remove leading zeroes per group
776             }
777 0         0 $self->_verbose(9, "l[$l] r[$r]");
778 0 0       0 if ($l=~/^v/ <=> $r=~/^v/) {
779 0         0 for ($l,$r) {
780 0 0       0 next if /^v/;
781 0         0 $_ = $self->_float2vv($_);
782             }
783             }
784 0         0 $self->_verbose(9, "l[$l] r[$r]");
785 0         0 my $lvstring = "v0";
786 0         0 my $rvstring = "v0";
787 0 0 0     0 if ($] >= 5.006
      0        
788             && $l =~ /^v/
789             && $r =~ /^v/) {
790 0         0 $lvstring = $self->_vstring($l);
791 0         0 $rvstring = $self->_vstring($r);
792 0         0 $self->_verbose(9, sprintf "lv[%vd] rv[%vd]", $lvstring, $rvstring);
793             }
794              
795             return (
796 0   0     0 ($l ne "undef") <=> ($r ne "undef")
797             ||
798             $lvstring cmp $rvstring
799             ||
800             $l <=> $r
801             ||
802             $l cmp $r
803             );
804             }
805              
806             sub _vgt {
807 0     0   0 my($self,$l,$r) = @_;
808 0         0 $self->_vcmp($l,$r) > 0;
809             }
810              
811             sub _vlt {
812 0     0   0 my($self,$l,$r) = @_;
813 0         0 $self->_vcmp($l,$r) < 0;
814             }
815              
816             sub _vge {
817 0     0   0 my($self,$l,$r) = @_;
818 0         0 $self->_vcmp($l,$r) >= 0;
819             }
820              
821             sub _vle {
822 0     0   0 my($self,$l,$r) = @_;
823 0         0 $self->_vcmp($l,$r) <= 0;
824             }
825              
826             sub _vstring {
827 0     0   0 my($self,$n) = @_;
828 0 0       0 $n =~ s/^v// or die "Parse::PMFile::_vstring() called with invalid arg [$n]";
829 0         0 pack "U*", split /\./, $n;
830             }
831              
832             # vv => visible vstring
833             sub _float2vv {
834 0     0   0 my($self,$n) = @_;
835 0         0 my($rev) = int($n);
836 0   0     0 $rev ||= 0;
837 0         0 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit
838             # architecture influence
839 0   0     0 $mantissa ||= 0;
840 0         0 $mantissa .= "0" while length($mantissa)%3;
841 0         0 my $ret = "v" . $rev;
842 0         0 while ($mantissa) {
843 0 0       0 $mantissa =~ s/(\d{1,3})// or
844             die "Panic: length>0 but not a digit? mantissa[$mantissa]";
845 0         0 $ret .= ".".int($1);
846             }
847             # warn "n[$n]ret[$ret]";
848 0         0 $ret =~ s/(\.0)+/.0/; # v1.0.0 => v1.0
849 0         0 $ret;
850             }
851              
852             sub _readable {
853 157     157   468 my($self,$n) = @_;
854 157         1076 $n =~ /^([\w\-\+\.]+)/;
855              
856 157 50 33     2452 return $1 if defined $1 && length($1)>0;
857             # if the first user reaches version v43, he will be treated as "+".
858             # We'll have to decide about a new rule here then, depending on what
859             # will be the prevailing versioning behavior then.
860              
861 0 0         if ($] < 5.006) { # or whenever v-strings were introduced
862             # we get them wrong anyway, whatever we do, because 5.005 will
863             # have already interpreted 0.2.4 to be "0.24". So even if he
864             # indexer sends us something like "v0.2.4" we compare wrongly.
865              
866             # And if they say v1.2, then the old perl takes it as "v12"
867              
868 0           $self->_verbose(9, "Suspicious version string seen [$n]\n");
869 0           return $n;
870             }
871 0           my $better = sprintf "v%vd", $n;
872 0           $self->_verbose(9, "n[$n] better[$better]");
873 0           return $better;
874             }
875              
876             1;
877              
878             __END__