什么解释Perl文件名检查?

时间:2012-10-19 11:59:15

标签: perl filenames sanitization

代码'if(-e“filename”)'测试在包含该代码的脚本的目录中是否存在名称为filename的文件。

做什么名字检查? Perl的?操作系统? Bash on POSIX-os?

'if(-e“cat string”)'会在Linux上执行cat命令吗?


我想知道,为了能够避免不希望的文件访问,如“../file”将访问父目录中的文件。


分享我的支票代码:

if($folder =~ m/$([\\]?\.[\\]?\.|[\\]?\\|[\\]?\/|[\\]?\?|[\\]?*|[\\]?:|[\\]?\||[\\]?\"|[\\]?\<|[\\]?\>)^|$([\\]?\.[\\]?\.|[\\]?\\|[\\]?\/|[\\]?\?|[\\]?*|[\\]?:|[\\]?\||[\\]?\"|[\\]?\<|[\\]?\>)\/|\/([\\]?\.[\\]?\.|[\\]?\\|[\\]?\/|[\\]?\?|[\\]?*|[\\]?:|[\\]?\||[\\]?\"|[\\]?\<|[\\]?\>)\/|\/([\\]?\.[\\]?\.|[\\]?\\|[\\]?\/|[\\]?\?|[\\]?*|[\\]?:|[\\]?\||[\\]?\"|[\\]?\<|[\\]?\>)^|\$'[^']*'/)
{
    #error
}


更新了正则表达式:

if($folder =~ m/(\/|\\)|$([\\]?\.[\\]?\.^|$[\\]?(\*|\?)^|\$'[^']*'/)
{
    #error
}

说明:$ folder必须是纯文件名。如果它包含Windows或POSIX路径分隔符或是(任何转义的)父目录返回链接或是(任何转义)通配符(因为它匹配第一个匹配的文件并至少在Mac OS X上返回true)或包含C ANSI转义任何地方的序列,信号错误其他任何东西,即使不合法或阴暗,也只需返回“文件不存在”,因此可以提供给'if(-e $ folder)'。

3 个答案:

答案 0 :(得分:7)

操作系统可以。 Perl对-e(以及-s之类的其他人)的调用是通过调用C库函数stat来实现的。

没有shell调用,因此"cat some_file"将不会被执行。相反,操作系统会查找名为“cat some_file”的文件。

当然,

stat可以使用相对路径名称进行调用。如果你不想那样,那么除去文件名+扩展名之外的所有内容。这种事情有Perl modules

我不想调试/查看你提出的正则表达式,因为它确实是完全不可读且不可维护的。

答案 1 :(得分:1)

  1. 谁进行名称检查?最后,除非您是设备驱动程序,否则所有文件I / O都由操作系统完成。 Perl向操作系统发出请求以执行该检查,尽管它可能通过C运行时库来执行此操作。你为什么要问?

  2. 将'if(-e“cat string”)'在Linux上执行cat命令?否。语法错误。打开文件,然后自己阅读。好的,如果必须使用cat,请使用systemxq,具体取决于您要对输出执行的操作。

  3. 您是否想知道为了能够避免不需要的文件访问,例如“../ file”?为什么这不受欢迎?它是..还是前导目录名称?

    use File::Basename;
    my $name = basename($filename);
    
  4. 将删除主要目录名称。

答案 2 :(得分:0)

Perl不使用shell来检查文件是否存在。尽管外观奇特,但您可以将-e视为内部Perl函数。它不能用作执行shell命令的偷偷摸摸的方式。

我认为你不需要这么复杂的正则表达式。如果您不希望用户能够输入父目录,只需确保文件名以单词字符开头(无论如何在Linux上):

if($folder =~ m/^\W/)
{
    print "path doesn't start with an alphanumeric character!";
}

当然,如果您担心的话,以这种方式强制执行路径是一种糟糕的安全方法。相反,您应该正确设置权限。