有没有一种安全的方法来使用eval在Perl中解开Data :: Dumper输出?

时间:2010-01-07 22:25:13

标签: perl coding-style data-dumper

我有一个使用冻结数据的对象:

sub frozen_data {
    my $self = shift;

    $Data::Dumper::Indent = 0;
    $Data::Dumper::Terse  = 1;
    return Data::Dumper->Dump( [ $self->{_DATA}, ] );
}

和相应的解冻:

sub thaw_data {
    my ($self) = @_;

    $self->{_DATA} = eval $self->{DATA};
}

这似乎运作良好,有什么问题吗?我也试过通过perlcritic来运行它,我得到了这个:

Expression form of "eval" at line 69, column 22.  See page 161 of PBP.  (Severity: 5)

写这个的更好方法是什么?

5 个答案:

答案 0 :(得分:8)

你可以告诉Perl Critic STFU:)

 $self->{_DATA} = eval $self->{DATA}; ## no critic

有时你需要做的事情只是一般一个坏习惯。

答案 1 :(得分:5)

如果你正在解冻Data :: Dumper的输出,那就没办法了。另一种选择是Storable

如果您接受不受信任的输入并将其未经检查交给eval,则应立即重新设计此机制,因为它会使前门敞开。对于编组内部数据,我不会说出警告。

答案 2 :(得分:5)

只要您知道该数据的唯一来源是您自己使用Dumper创建的冻结数据,那就没关系。

另一种方法是使用Dumper以外的其他东西,例如Storable

答案 3 :(得分:5)

决定您要允许或禁止的内容并设置Safe分区并使用其重估方法。

答案 4 :(得分:0)

对于任何看过这个并且想知道是否推出自己的序列化的人来说,通过查看这篇博客文章可以获得一些好处,该帖子比较了几个现有序列化程序的列表,并给出了每个序列化程序的优点和缺点:

http://blogs.perl.org/users/steven_haryanto/2010/09/comparison-of-perl-serialization-modules.html

他提到了Data :: Dumper,Storable,YAML :: XS,Data :: Dump,XML :: Dumper,JSON :: XS,JSYNC和FreezeThaw。他的结论是,所有这些功能都缺失了:

  

总之,选择是好的,但我还没有找到完美的将军   序列化模块呢。我最喜欢的两个是Storable和YAML :: XS。   如果JSYNC [更快]并且支持Regexp,或者如果YAML :: XS或YAML :: Syck   [可以]输出内联/紧凑YAML,这将像我一样接近完美   我想要它。

另见人们在评论中提出的要点。获得之前遇到过问题的人的观点等等,这是很好的。

如果你正在推行自己的序列化,你可能想看看那里提到的优点和缺点(速度,处理正则表达式和循环引用等事情的能力)。如果您没有意识到自己可能遇到这种问题,这可能会为您解决问题。

此外,当您使用Dumper进行序列化时,最好了解Data :: Dumper为您提供输出的所有选项。

是否会进入一个数据库,在未来的某个时间,有人会想要用LIKE模式进行SQL查询?如果是这样,你会很高兴你使用了Sortkeys,因为你可以做LIKE'%akey = front%ckey = front_of_c%'而你只需要一个排序来担心而不是n阶乘。

举个例子,这是我的一个朋友用Dumper序列化的原因:

my $deflated = Data::Dumper->new([$data])->Purity(1)->Terse(1)->Deepcopy(1)->Sortkeys(1)->Indent(1)->Dump;

我建议您阅读Dumper的文档,以便了解这些选项所做的修改。