从命令行运行时,我们可以强制perl总是使用三个参数形式的open吗?

前端之家收集整理的这篇文章主要介绍了从命令行运行时,我们可以强制perl总是使用三个参数形式的open吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
从命令行运行perl one-liners有 security implications.

问题是选项-n / -p触发菱形运算符<&gt ;,它使用open的两个参数形式,因此对于文件名包含特殊字符,perl不能按预期工作:

$perl -pe '' 'uname|'
Linux

或者当文件名以>开头时更危险,例如>文件.在这种情况下,文件将被截断.

解决此问题,我们可以:

>使用CPAN的ARGV::readonly模块.
>通过自己实现像ARGV :: readonly模块这样的功能

perl -pe 'BEGIN{$_.="\0" for @ARGV} ...' ./*

>使用-i选项,因为perl将在处理之前检查文件是否存在.
>使用-T选项启用污染模式.

我认为所有解决方案都可以解决这个问题,但也会产生副作用.如果我们可以强制perl总是使用open的参数形式,那将是一个更好的解决方案.

我想我们可以做到这一点,强迫perl总是使用开放的论证形式?

注意

这个问题仅适用于从命令行运行perl一个内联的情况,因为(当然)我们总是可以在Perl脚本中使用open的三个参数形式.

解决方法

在我之前的回答中,我假设ARGV文件句法魔术模拟了2参数打开,但实际上并没有通过Perl的内置开放函数.所以我对它进行了更多调查,我想我想出了一个解决这个问题的实际方法.

doio.c中的函数Perl_nextargv是perl围绕ARGV文件句柄执行I / O的地方.

在该函数的while循环中,有两种打开文件句柄的调用.当LIKELY(PL_inplace)为真时(即,当使用-i开关运行perl时),调用是do_open_raw.当LIKELY(PL_inplace)为false时,调用是do_open6.后一个调用能够打开外部命令的管道,这通常是OP不想要的.

所以这是解决方案:在源文件doio.c中,用do_open_raw替换Perl_nextargv中的do_open6调用,并从源代码重建perl.对于perl-5.22.0,原始代码看起来像

if (LIKELY(!PL_inplace)) {
        if (nomagicopen
                ? do_open6(gv,"<",1,NULL,&GvSV(gv),1)
                : do_open6(gv,PL_oldname,oldlen,0)
           ) {
            return IoIFP(GvIOp(gv));
        }
    }

并且修改后的代码看起来像

if (LIKELY(!PL_inplace)) {
        if (do_open_raw(gv,O_RDONLY,0)) {
            return IoIFP(GvIOp(gv));
        }
    }

(当您使用the new <<>> syntax from perl 5.22.0时,nomagicopen参数为true.我想我们可以在函数顶部将其设置为true,而不必更改任何其他内容,但上面的更改是旧perl的一般解决方案).

样本输出

$original-perl -pe '' a b c 'date|'
Can't open a: No such file or directory
Can't open b: No such file or directory.
Can't open c: No such file or directory.
Mon Sep 21 18:41:37 PDT 2015

$modified-perl -pe '' a b c 'date|'
Can't open a: No such file or directory.
Can't open b: No such file or directory.
Can't open c: No such file or directory.
Can't open date|: No such file or directory.
原文链接:https://www.f2er.com/Perl/172231.html

猜你在找的Perl相关文章