File Coverage

lib/Cwd/Ext.pm
Criterion Covered Total %
statement 51 55 92.7
branch 24 42 57.1
condition 0 8 0.0
subroutine 9 9 100.0
pod 5 5 100.0
total 89 119 74.7


line stmt bran cond sub pod time code
1             package Cwd::Ext;
2 2     2   36995 use strict;
  2         4  
  2         57  
3 2     2   10 use Exporter;
  2         2  
  2         80  
4 2     2   9 use Carp;
  2         8  
  2         193  
5 2     2   11 use vars qw(@ISA @EXPORT_OK $VERSION @EXPORT $VERSION $DEBUG %EXPORT_TAGS);
  2         2  
  2         1449  
6             @ISA = qw/Exporter/;
7             @EXPORT_OK = qw(abs_path_is_in abs_path_is_in_nd abs_path_nd abs_path_matches_into symlinks_supported);
8             %EXPORT_TAGS = ( all => \@EXPORT_OK );
9             $VERSION = sprintf "%d.%02d", q$Revision: 1.6 $ =~ /(\d+)/g;
10              
11              
12             # abs path no dereference
13             sub abs_path_nd {
14 9     9 1 31904 my $abs_path = shift;
15 9 50       96 return $abs_path if $abs_path=~m{^/$};
16            
17 9 100       85 unless( $abs_path=~/^\// ){
18 3         67 require Cwd;
19 3         16826 $abs_path = Cwd::cwd()."/$abs_path";
20             }
21            
22 9         177 my @elems = split m{/}, $abs_path;
23 9         38 my $ptr = 1;
24 9         95 while($ptr <= $#elems){
25 60 50       319 if($elems[$ptr] eq '' ){
    100          
    100          
26 0         0 splice @elems, $ptr, 1;
27             }
28              
29             elsif($elems[$ptr] eq '.' ){
30 3         30 splice @elems, $ptr, 1;
31             }
32              
33             elsif($elems[$ptr] eq '..' ){
34 2 50       41 if($ptr < 2){
35 0         0 splice @elems, $ptr, 1;
36             }
37             else {
38 2         5 $ptr--;
39 2         22 splice @elems, $ptr, 2;
40             }
41             }
42             else {
43 55         149 $ptr++;
44             }
45             }
46              
47 9 50       8601 $#elems ? join q{/}, @elems : q{/};
48             }
49              
50              
51             sub abs_path_matches_into {
52 13     13 1 32 my($child,$parent)=@_;
53 13 50       42 defined $child or die('missing child');
54 13 50       37 defined $parent or die('missing parent');
55            
56 13 50       49 if($child eq $parent){
57 0 0       0 warn(" - args are the same, returning true") if $DEBUG;
58 0         0 return $child;
59             }
60              
61             # WE DON'T WANT /home/hi to match on /home/hithere
62 13 100       423 unless( $child=~/^$parent\// ){
63 4 50       14 warn (" -[$child] is not a child of [$parent]") if $DEBUG;
64 4         27 return 0;
65             }
66 9         116 $child;
67             }
68              
69             # is path a inside filesystem hierarchy b
70             sub abs_path_is_in {
71 10     10 1 19219 my($child,$parent) = @_;
72 10 50       52 defined $child or confess('missing child path argument');
73 10 50       46 defined $parent or confess('missing parent path argument');
74            
75 10         102 require Cwd;
76 10 50 0     1431 my $_child = Cwd::abs_path($child) or warn("cant normalize child [$child]") and return;
77 10 50 0     910 my $_parent = Cwd::abs_path($parent) or warn("cant normalize parent [$parent]") and return;
78              
79 10         41 abs_path_matches_into($_child,$_parent);
80             }
81              
82             # is path a in filesystem hierarchy b, no symlink dereferece
83             sub abs_path_is_in_nd {
84 2     2 1 8 my($child,$parent) = @_;
85 2 50       17 defined $child or confess('missing child path argument');
86 2 50       8 defined $parent or confess('missing parent path argument');
87              
88 2 50 0     7 my $_child = Cwd::Ext::abs_path_nd($child) or warn("cant normalize child [$child]") and return;
89 2 50 0     8 my $_parent = Cwd::Ext::abs_path_nd($parent) or warn("cant normalize parent [$parent]") and return;
90              
91 2         20 abs_path_matches_into($_child,$_parent);
92             }
93              
94              
95 2     2 1 11 sub symlinks_supported { eval { symlink("",""); 1 } }
  2         27  
  2         6  
96              
97              
98             1;
99             # lib/Cwd/Ext.pod