我想在Perl中的二进制文件上使用binmode。那么我怎么知道手边的文件是二进制还是文本?
这意味着首先我要读完整个文件,知道它是二进制文本还是文本,然后使用binmode设置回放FP,如果它是二进制文件。
由于Perl -B / -T仅检查文本的起始块,因此它通常将pdf分类为文本文件(源代码可能隐藏在任何扩展名中,如.gif,.pdf等)。因此,我需要读取完整的文件数据,以确定它是二进制文件还是文本文件。
我听说任何源代码文件(.pl,.c,.php等)都不会包含0x0-0x1f和0xff之类的不可见字符。
我是否可以检查此范围内的每个字节以声明它是否是源代码文件?
答案 0 :(得分:2)
如果您对安全性感到偏执,只需确保从数据中分离可执行文件即可。 binmode
对此没有帮助:它可用于克服DOS和后代上的行结束恐怖,并可用于指定透明编码。
对于您的顾虑,所有用户上传的文件 都是恶意的。没有“安全”格式,因此从“文本”文件中分离“二进制”是没用的。不要相信简单的启发式方法。 (例如Perl允许control characters in variable names!)
处理用户数据时,Perl的一些关键部分应确保没有未经检查的输入:
(?{}) and (??{})
执行正则表达式任意代码。system
,exec
,qx()
,反对自我解释eval
- 插入变量时要小心。open
,glob
和C-ish字符串函数的参数。 binmode
不属于这些。
如果您必须提供用户指定的数据,请尝试将其传递给未处理的数据。例如。在用户定义的样式表的情况下,属于php不解释的目录。如果是图像,您可以尝试在收到文件后进行转换并保存等效但可能安全的变体。
答案 1 :(得分:2)
如果是文本文件,你真的需要在文本模式下读取文件吗?您可以无条件地使用binmode
。
如果您有一段处理文本文件的代码,它可以过滤掉任何无关的回车(0D)。如果你没有这样的代码,那么回车是否留下来肯定无关紧要。
答案 2 :(得分:1)
问题是在现代POSIX系统上,二进制文件和文本文件之间没有区别;一个字节是一个字节是一个字节。
我宁愿尝试另一种方法。如果您使用Linux / Unix,则可以直接利用file
实用程序使用“magic”来查看文件的第一个字节(或者在某些情况下),并确定其类型;在Windows中,您必须先安装它。该实用程序使得捕获可执行文件,zip文件等变得相对简单。
在Perl中,您可以通过模块File::Type使用它。