0

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

什么是做名字检查?珀尔?操作系统?POSIX 操作系统上的重击?

'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)”。

4

3 回答 3

7

The operating system does. Perl's call to -e (as well as others like -s) are implemented by calling the C library function stat.

There is no shell involed, and therefore "cat some_file" will not be executed. Instead the OS looks for a file called "cat some_file".

stat can, of course, be called with relative path names. If you don't want that then strip away everything but the file name + extension. There are Perl modules for this kind of thing.

I don't want to debug/look into your proposed regular expression because it is, quite honestly, completey unreadable and unmaintainable.

于 2012-10-19T12:15:52.087 回答
1
  1. Who does the name check? In the end, all file I/O is done by the operating system, unless you are a device driver. Perl makes the request to the operating system to do that check, although it might go through the C runtime-library to do so. Why are you asking?

  2. Would 'if(-e "cat string")' execute the cat command on Linux? No. Wrong syntax. Open the file then read it yourself. OK, if you must use cat, use system, or xq, depending on what you want to do with the output.

  3. Do you want to know in order to be able to avert undesired file access like "../file"? Why is that undesired? Is it the .., or the leading directory name?

    use File::Basename;
    my $name = basename($filename);
    

will remove leading directory names.

于 2012-10-19T12:16:22.303 回答
0

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

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

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

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

于 2012-10-19T12:17:57.717 回答