加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl模糊的命令行选项,以及使用-i的eval的安全含义?

发布时间:2020-12-15 22:05:34 所属栏目:大数据 来源:网络整理
导读:我知道这是不正确的.我只是想知道perl如何解析它. 所以,我正在玩perl,我想要的是perl -ne我输入的是perl – 我的行为很有趣,我想知道发生了什么. $echo 1 | perl -ie'next unless /g/i' 所以perl Aborted(核心倾销)就此.阅读perl –help我看到-i需要一个备份
我知道这是不正确的.我只是想知道perl如何解析它.

所以,我正在玩perl,我想要的是perl -ne我输入的是perl – 我的行为很有趣,我想知道发生了什么.

$echo 1 | perl -ie'next unless /g/i'

所以perl Aborted(核心倾销)就此.阅读perl –help我看到-i需要一个备份扩展.

-i[extension]     edit <> files in place (makes backup if extension supplied)

对于那些不知道的人来说 – 只是eval.所以我想三件事中的一件可能发生了,或者被解析为

> perl -i -e’next除非/ g / i’我得到undef,其余的作为参数e
> perl -ie’next除非/ g / i’我得到参数e,其余的就像文件名一样悬挂
> perl -i“-e’next除非/ g / i’”整件事作为我的论据

我跑的时候

$echo 1 | perl -i -e'next unless /g/i'

该计划不会中止.这让我相信’下一个除非/ g / i’没有被解析为-e的文字参数.毫不含糊地将上述方法解析,并且它具有不同的结果.

那是什么?好好玩一点,我得到了

$echo 1 | perl -ie'foo bar'
Unrecognized switch: -bar  (-h will show valid options).

$echo 1 | perl -ie'foo w w w'
... works fine guess it reads it as `perl -ie'foo' -w -w -w`

玩弄以上,我试试这个……

$echo 1 | perl -ie'foo e eval q[warn "bar"]'
bar at (eval 1) line 1.

现在我真的很困惑..那么Perl如何解析这个呢?最后,似乎你实际上可以从-i中获得Perl eval命令.这有安全隐患吗?

$perl -i'foo e eval "warn q[bar]" '

解决方法

快速回答

Shell报价处理正在崩溃并连接它认为是一个论点.你的调用相当于

$perl '-ienext unless /g/i'

它立即中止,因为perl将此参数解析为包含-u,这会触发核心转储,从而开始执行代码.这是一个曾经用于创建伪可执行文件的旧功能,但它现在在性质上是退化的.

似乎是对eval的调用是对-e’s / g / i的误解.

第一个线索

B::Deparse可以是你的朋友,只要你碰巧在没有dump支持的系统上运行.

$echo 1 | perl -MO=Deparse,-p -ie'next unless /g/i'
dump is not supported.
BEGIN { $^I = "enext"; }
BEGIN { $/ = "n"; $ = "n"; }
LINE: while (defined(($_ = <ARGV>))) {
    chomp($_);
    (('ss' / 'g') / 'i');
}

那为什么unle消失了?如果你正在运行Linux,你甚至可能没有达到我的目标.上面的输出来自Cygwin上的Perl,并且关于dump不支持的错误是一个线索.

下一个线索

值得注意的是perlrun documentation:

-u

This switch causes Perl to dump core after compiling your program. You can then in theory take this core dump and turn it into an executable file by using the undump program (not supplied). This speeds startup at the expense of some disk space (which you can minimize by stripping the executable). (Still,a “hello world” executable comes out to about 200K on my machine.) If you want to execute a portion of your program before dumping,use the dump operator instead. Note: availability of undump is platform specific and may not be available for a specific port of Perl.

工作假设和确认

Perl的参数处理将整个块视为单个选项集,因为它以破折号开头. -i选项使用下一个单词(enext),正如我们在implementation for -i processing中看到的那样.

case 'i':
    Safefree(PL_inplace);
    [Cygwin-specific code elided -geb]
    {
        const char * const start = ++s;
        while (*s && !isSPACE(*s))
            ++s;

        PL_inplace = savepvn(start,s - start);
    }
    if (*s) {
        ++s;
        if (*s == '-')      /* Additional switches on #! line. */
            s++;
    }
    return s;

对于备份文件的扩展名,perl.c上面的代码消耗最多的第一个空格字符或字符串结尾,以先到者为准.如果字符仍然存在,则第一个必须是空格,然后跳过它,如果下一个是破折号,则跳过它.在Perl中,您可以将此逻辑编写为

if ($$s =~ s/i(S+)(?:s-)//) {
  my $extension = $1;
  return $extension;
}

然后,所有-u,-n,-l和-e都是有效的Perl选项,因此参数处理会占用它们并使其无意义

ss /g/i

作为-e的参数,perl将其解析为一系列分歧.但是在执行甚至开始之前,古老的-u会导致perl转储核心.

意外的行为

更奇怪的是,如果你在next和之间放置两个空格

$perl -ie'next  unless /g/i'

程序试图运行. Back in the main option-processing loop我们看到了

case '*':
case ' ':
    while( *s == ' ' )
      ++s;
    if (s[0] == '-')        /* Additional switches on #! line. */
        return s+1;
    break;

额外空间终止对该参数的选项解析.见证人:

$perl -ie'next  nonsense -garbage --foo' -e die
Died at -e line 1.

但没有我们看到的额外空间

$perl -ie'next nonsense -garbage --foo' -e die
Unrecognized switch: -onsense -garbage --foo  (-h will show valid options).

但是,如果有额外的空间和破折号,

$perl -ie'next  -unless /g/i'
dump is not supported.

设计动机

正如评论所指出的那样,逻辑是为了harsh shebang (#!) line constraints,perl尽力解决.

Interpreter scripts

An interpreter script is a text file that has execute permission enabled and whose first line is of the form:

060010

The interpreter must be a valid pathname for an executable which is not itself a script. If the filename argument of execve specifies an interpreter script,then interpreter will be invoked with the following arguments:

060011

where arg… is the series of words pointed to by the argv argument of execve.

For portable use,optional-arg should either be absent,or be specified as a single word (i.e.,it should not contain white space) …

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读