将catfile用于以目录结尾的路径时会有危险吗?

时间:2017-04-29 16:42:25

标签: perl directory-structure

File::Spec模块提供了一种创建跨OS有效路径的方法。它按照人们的预期运作:

use strict;
use warnings;

use File::Spec;

my $file = 'ghi.xml';
my $path = File::Spec->catfile(('abc', 'def'), $file);
print $path;
# Windows: abc/def/ghi.xml

方法catdir也可用,这将导致目录 - 而不是文件的路径。

我的问题是我事先并不知道$file是文件名还是目录名。据我测试,使用dirname时结果仍然正确,例如:

use strict;
use warnings;

use File::Spec;

my $file = 'ghi';
my $path = File::Spec->catfile(('abc', 'def'), $file);
print $path;
# Windows: abc/def/ghi

但我想知道这是否会引起问题。我假设因为我不明白为什么模块的创建者会为相同的功能构建两个接口。但是,我在文档中找不到任何进一步的解释。

使用catfile创建文件路径和目录是否安全?如果没有,有什么警告?

1 个答案:

答案 0 :(得分:4)

catdircatfile的差异通常非常小(取决于使用的操作系统)。在UNIX上,catfile无论如何都为目录元素做了catdir(例如减去最后一个(文件)部分),然后附加文件部分。 catdir执行一些路径清理逻辑。在Windows平台上,差异甚至更小。

您可以自己查看source of the module(s) for the different OS-es

主要的是:这些例程不进行任何文件系统访问,只是进行一些逻辑路径清理。

<强>替代:

如果您不关心其他类似UNIX的操作系统(例如Linux,FreeBSD,Mac OS X等)。 Windows,我个人建议使用Path::Tiny模块。来自它的医生:

  

此模块提供了一个用于处理文件的小型快速实用程序   路径。使用比File :: Spec更友好,并提供简单   从其他几个核心文件处理模块访问函数。它   旨在比CPAN上的许多替代品更小更快   帮助人们以一致而少的方式做许多常见的事情   容易出错的方式。

     

Path :: Tiny不会尝试除了像Unix一样的东西   Win32平台。

恕我直言 - 这是CPAN上最好的模块之一 - 真正的宝藏。例如,对于路径创建,您应该使用child方法 - 再次来自docs:

$file = path("/tmp")->child("foo.txt"); # "/tmp/foo.txt"
$file = path("/tmp")->child(@parts);
     

返回相对于原始对象的新Path :: Tiny对象。像   来自File :: Spec的catfilecatdir,但没有关心文件   或目录。

除了上述内容之外,Path::Tiny模块可以轻松访问文件内容(也可以使用unicode处理)和每个常用的&#34;路径&#34;操作。缺点:不幸的是,它不是CORE模块,例如:你需要从CPAN安装它。

修改

对目录使用catfile是否安全?由我:(但也许一些专家会知道别的或更多)。在unix上,

  • catdir调用canonpath(执行逻辑路径清理)。
  • catfile调用canonpath两次,一次调用文件部分,一次调用目录(如果已提供),以及连接两个结果。串联可能导致一些奇怪的路径,但它们通常是无害的。

在Windows上,差异更小,两者都会调用路径清理程序。

演示 - 以下脚本将生成不同部分的多种组合,并将使用catdircatfile(甚至是Path::Tiny的两种变体)

use strict;
use warnings;

use File::Spec::Functions;
use Path::Tiny;

my @parts = qw(x / /x /x/ /x// // //x //x/ //x// /./ /./x /x/./ );
my $cwidth=16;
print pr(qw(first second catdir catfile path-child path-list)), "\n";
print '-' x ($cwidth*6),"\n";
for my $first (map { s/x/first/r } @parts) {
    for my $second ( map { s/x/second/r } @parts) {
        print pr(
            $first,
            $second,
            catdir($first,$second),
            catfile($first,$second),
            path($first)->child($second),
            path($first,$second),
        ), "\n";
    }
}
sub pr {
    my $str;
    $str .= sprintf "%-${cwidth}s",$_ for @_;
    return $str;
}

打印出很长的结果。正如您所看到的,所有路径都可以安全地用于目录和文件,只有catfile的某些路径不是&#34;很好&#34;。

两者&#34; Path :: Tiny&#34;结果清晰一致。相反,catfilecatdir将允许使用未定义的部分(未在演示中显示) - 即使在这样的错误参数中,也会产生一些结果,路径: :如果你将undef或null-string传递给它的child方法,那么将会死

first           second          catdir          catfile         path-child      path-list       
------------------------------------------------------------------------------------------------
first           second          first/second    first/second    first/second    first/second    
first           /               first           first//         first           first           
first           /second         first/second    first//second   first/second    first/second    
first           /second/        first/second    first//second   first/second    first/second    
first           /second//       first/second    first//second   first/second    first/second    
first           //              first           first//         first           first           
first           //second        first/second    first//second   first/second    first/second    
first           //second/       first/second    first//second   first/second    first/second    
first           //second//      first/second    first//second   first/second    first/second    
first           /./             first           first//         first           first           
first           /./second       first/second    first//second   first/second    first/second    
first           /second/./      first/second    first//second   first/second    first/second    
/               second          /second         /second         /second         /second         
/               /               /               //              /               /               
/               /second         /second         //second        /second         /second         
/               /second/        /second         //second        /second         /second         
/               /second//       /second         //second        /second         /second         
/               //              /               //              /               /               
/               //second        /second         //second        /second         /second         
/               //second/       /second         //second        /second         /second         
/               //second//      /second         //second        /second         /second         
/               /./             /               //              /               /               
/               /./second       /second         //second        /second         /second         
/               /second/./      /second         //second        /second         /second         
/first          second          /first/second   /first/second   /first/second   /first/second   
/first          /               /first          /first//        /first          /first          
/first          /second         /first/second   /first//second  /first/second   /first/second   
/first          /second/        /first/second   /first//second  /first/second   /first/second   
/first          /second//       /first/second   /first//second  /first/second   /first/second   
/first          //              /first          /first//        /first          /first          
/first          //second        /first/second   /first//second  /first/second   /first/second   
/first          //second/       /first/second   /first//second  /first/second   /first/second   
/first          //second//      /first/second   /first//second  /first/second   /first/second   
/first          /./             /first          /first//        /first          /first          
/first          /./second       /first/second   /first//second  /first/second   /first/second   
/first          /second/./      /first/second   /first//second  /first/second   /first/second   
/first/         second          /first/second   /first/second   /first/second   /first/second   
/first/         /               /first          /first//        /first          /first          
/first/         /second         /first/second   /first//second  /first/second   /first/second   
/first/         /second/        /first/second   /first//second  /first/second   /first/second   
/first/         /second//       /first/second   /first//second  /first/second   /first/second   
/first/         //              /first          /first//        /first          /first          
/first/         //second        /first/second   /first//second  /first/second   /first/second   
/first/         //second/       /first/second   /first//second  /first/second   /first/second   
/first/         //second//      /first/second   /first//second  /first/second   /first/second   
/first/         /./             /first          /first//        /first          /first          
/first/         /./second       /first/second   /first//second  /first/second   /first/second   
/first/         /second/./      /first/second   /first//second  /first/second   /first/second   
/first//        second          /first/second   /first/second   /first/second   /first/second   
/first//        /               /first          /first//        /first          /first          
/first//        /second         /first/second   /first//second  /first/second   /first/second   
/first//        /second/        /first/second   /first//second  /first/second   /first/second   
/first//        /second//       /first/second   /first//second  /first/second   /first/second   
/first//        //              /first          /first//        /first          /first          
/first//        //second        /first/second   /first//second  /first/second   /first/second   
/first//        //second/       /first/second   /first//second  /first/second   /first/second   
/first//        //second//      /first/second   /first//second  /first/second   /first/second   
/first//        /./             /first          /first//        /first          /first          
/first//        /./second       /first/second   /first//second  /first/second   /first/second   
/first//        /second/./      /first/second   /first//second  /first/second   /first/second   
//              second          /second         /second         /second         /second         
//              /               /               //              /               /               
//              /second         /second         //second        /second         /second         
//              /second/        /second         //second        /second         /second         
//              /second//       /second         //second        /second         /second         
//              //              /               //              /               /               
//              //second        /second         //second        /second         /second         
//              //second/       /second         //second        /second         /second         
//              //second//      /second         //second        /second         /second         
//              /./             /               //              /               /               
//              /./second       /second         //second        /second         /second         
//              /second/./      /second         //second        /second         /second         
//first         second          /first/second   /first/second   /first/second   /first/second   
//first         /               /first          /first//        /first          /first          
//first         /second         /first/second   /first//second  /first/second   /first/second   
//first         /second/        /first/second   /first//second  /first/second   /first/second   
//first         /second//       /first/second   /first//second  /first/second   /first/second   
//first         //              /first          /first//        /first          /first          
//first         //second        /first/second   /first//second  /first/second   /first/second   
//first         //second/       /first/second   /first//second  /first/second   /first/second   
//first         //second//      /first/second   /first//second  /first/second   /first/second   
//first         /./             /first          /first//        /first          /first          
//first         /./second       /first/second   /first//second  /first/second   /first/second   
//first         /second/./      /first/second   /first//second  /first/second   /first/second   
//first/        second          /first/second   /first/second   /first/second   /first/second   
//first/        /               /first          /first//        /first          /first          
//first/        /second         /first/second   /first//second  /first/second   /first/second   
//first/        /second/        /first/second   /first//second  /first/second   /first/second   
//first/        /second//       /first/second   /first//second  /first/second   /first/second   
//first/        //              /first          /first//        /first          /first          
//first/        //second        /first/second   /first//second  /first/second   /first/second   
//first/        //second/       /first/second   /first//second  /first/second   /first/second   
//first/        //second//      /first/second   /first//second  /first/second   /first/second   
//first/        /./             /first          /first//        /first          /first          
//first/        /./second       /first/second   /first//second  /first/second   /first/second   
//first/        /second/./      /first/second   /first//second  /first/second   /first/second   
//first//       second          /first/second   /first/second   /first/second   /first/second   
//first//       /               /first          /first//        /first          /first          
//first//       /second         /first/second   /first//second  /first/second   /first/second   
//first//       /second/        /first/second   /first//second  /first/second   /first/second   
//first//       /second//       /first/second   /first//second  /first/second   /first/second   
//first//       //              /first          /first//        /first          /first          
//first//       //second        /first/second   /first//second  /first/second   /first/second   
//first//       //second/       /first/second   /first//second  /first/second   /first/second   
//first//       //second//      /first/second   /first//second  /first/second   /first/second   
//first//       /./             /first          /first//        /first          /first          
//first//       /./second       /first/second   /first//second  /first/second   /first/second   
//first//       /second/./      /first/second   /first//second  /first/second   /first/second   
/./             second          /second         /second         /second         /second         
/./             /               /               //              /               /               
/./             /second         /second         //second        /second         /second         
/./             /second/        /second         //second        /second         /second         
/./             /second//       /second         //second        /second         /second         
/./             //              /               //              /               /               
/./             //second        /second         //second        /second         /second         
/./             //second/       /second         //second        /second         /second         
/./             //second//      /second         //second        /second         /second         
/./             /./             /               //              /               /               
/./             /./second       /second         //second        /second         /second         
/./             /second/./      /second         //second        /second         /second         
/./first        second          /first/second   /first/second   /first/second   /first/second   
/./first        /               /first          /first//        /first          /first          
/./first        /second         /first/second   /first//second  /first/second   /first/second   
/./first        /second/        /first/second   /first//second  /first/second   /first/second   
/./first        /second//       /first/second   /first//second  /first/second   /first/second   
/./first        //              /first          /first//        /first          /first          
/./first        //second        /first/second   /first//second  /first/second   /first/second   
/./first        //second/       /first/second   /first//second  /first/second   /first/second   
/./first        //second//      /first/second   /first//second  /first/second   /first/second   
/./first        /./             /first          /first//        /first          /first          
/./first        /./second       /first/second   /first//second  /first/second   /first/second   
/./first        /second/./      /first/second   /first//second  /first/second   /first/second   
/first/./       second          /first/second   /first/second   /first/second   /first/second   
/first/./       /               /first          /first//        /first          /first          
/first/./       /second         /first/second   /first//second  /first/second   /first/second   
/first/./       /second/        /first/second   /first//second  /first/second   /first/second   
/first/./       /second//       /first/second   /first//second  /first/second   /first/second   
/first/./       //              /first          /first//        /first          /first          
/first/./       //second        /first/second   /first//second  /first/second   /first/second   
/first/./       //second/       /first/second   /first//second  /first/second   /first/second   
/first/./       //second//      /first/second   /first//second  /first/second   /first/second   
/first/./       /./             /first          /first//        /first          /first          
/first/./       /./second       /first/second   /first//second  /first/second   /first/second   
/first/./       /second/./      /first/second   /first//second  /first/second   /first/second