Perl 编程练习:测试污染
要成为一名优秀的程序员,就需要练习编程。
仅仅练习是不够的。你需要有效地、坚持不懈地练习。你需要探索那些吸引你注意力的分支、想法和组合。留出一些时间来尝试新的想法,看看你能学到什么,以及你能在常规编程中使用什么。
你如何找到新的想法?一种方式是通过 编程练习,这些是帮助你开始学习的简短代码片段。
本文是针对 Perl 程序员的一系列编程练习的第一篇。所有这些练习都是在编写 Perl 程序测试的背景下进行的。
为什么要在测试的背景下给出示例?首先,是为了推广编写测试的想法。编写优秀、简单和有效的软件的最佳技术之一是练习测试驱动开发。其次,编写好的测试是具有挑战性的。它经常迫使程序员找到解决难题的创造性解决方案。
污染测试练习 #1
Perl 最有用的特性之一是污染的概念。如果你启用污染模式,Perl 将用污染标志标记来自不安全来源的每一份数据,例如不安全的输入。如果你想以可能危险的方式使用污染数据,你必须通过验证来清除数据。
CGI::Untaint 模块系列使得在需要最大污染保护的网络程序中这个过程更加容易。有模块可以清除日期、电子邮件地址和信用卡号。
最近,我编写了 CGI::Untaint::boolean 来清除来自网络表单复选框的数据。这是一个简单的模块,用不到20行稀疏代码,它清除任何传入的数据,并将表单值 on
转换为真值,并将其他任何东西(包括不存在的参数)转换为假。
编写测试证明是稍微有点困难。我如何确保传递给模块的传入参数被正确地污染?我如何确保模块正确地清除它?
给定 CGI::Untaint::boolean 的代码,你将如何编写测试?
package CGI::Untaint::boolean;
use strict;
use base 'CGI::Untaint::object';
sub _untaint_re { qr/^(on)$/ }
sub is_valid
{
my $self = shift;
my $value = $self->value();
return unless $value and $value =~ $self->_untaint_re();
$self->value( $value eq 'on' ? 1 : 0 );
return 1;
}
1;
你的代码应该检查它是否传递了一个污染值,并且它接收到了一个清除值。你还应该验证从处理器提取的最终值,无论其先前状态如何,都不是污染的。
使用 Perl 的核心测试模块之一进行编写。我更喜欢 Test::Simple 和 Test::More,但如果你必须使用 Test,也可以。假设 Test::Harness 会尊重命令行上传递的 -T
标志。
除非你真的遇到了困难,否则不要阅读 CGI::Untaint::boolean 中的测试。下一节将进一步解释该技术。为了获得最佳结果,在查看提示之前,至少花30分钟独立完成这个练习。
提示、技巧、建议和一个解决方案
要正确测试污染,你必须理解其影响。当 Perl 看到标志 -T
或 -t
时,它会立即将一些数据和环境标记为污染。这包括环境变量 PATH
。
此外,污染是粘性的。如果你在表达式中使用一个污染数据,它将污染该表达式的结果。
这两个事实都使得找到污染源变得容易。CGI::Untaint::boolean 做以下事情来创建污染数据
my $tainted_on = substr( 'off' . $ENV{PATH}, 0, 3 );
将干净的字符串 off
与环境变量 PATH
的污染值连接起来产生一个污染字符串。然后,substr()
表达式返回原始字符串,并添加污染标志。
如何判断一个变量是否包含受污染的值?Perl FAQ 提供了一个解决方案,尝试对受污染的数据执行不安全的操作,但我更喜欢使用 Scalar::Util 模块的 tainted()
函数。这实际上是同一件事,但我不需要记住任何异常细节。
这项技术依赖于 Test::Harness 使用 -T
标志启动测试程序。如果这不是一个选择,测试程序本身可以使用该标志启动其他程序,使用 $^X
变量找到当前执行 Perl 的路径。在跳过其他测试或启动新进程并报告其结果之前检查 -T
标志是否起作用可能是值得的。
Test::Harness 所带的 prove
工具可能会很有用;使用 prove -T testfile.t
启动测试以在受污染模式下运行。有关更多信息,请参阅 perldoc prove
。
您还可以使用这种方法启动旨在在取消污染失败时中止的程序,并自动检查退出代码。虽然使用 Scalar::Util 似乎更容易。
结论
这应该会为您提供解决此问题的所有所需信息。请将您的代码与 CGI::Untaint::boolean 的测试进行对照。
如果您找到了另一种可行的方法,我很乐意听到您的意见。另外,如果您对另一个 kata(或想要撰写一个)有建议,请告诉我。
chromatic 是 Modern Perl 的作者。在业余时间,他一直在帮助新手了解股票和投资。[链接](https://trendshare.org/how-to-invest/)
标签
反馈
这篇文章有什么问题吗?请通过在 [GitHub](https://github.com/perladvent/perldotcom/blob/master/content/legacy/_pub_2004_10_21_taint_testing_kata.md) 上打开问题或拉取请求来帮助我们。