0

我想在 Perl 中的二进制文件上使用 binmode。那么我怎么知道手头的文件是二进制文件还是文本文件呢?

这意味着首先我会读取完整文件以了解它是二进制文件还是文本文件,然后如果它是二进制文件,则使用设置 binmode 倒回 FP。

由于 Perl -B/-T 只检查文本的开始块,它通常将 pdf 分类为文本文件(源代码可以隐藏在任何扩展名中,如 .gif、.pdf 等)。所以我需要读取完整的文件数据来决定它是二进制文件还是文本文件。

我听说任何源代码文件(.pl、.c、.php 等)都不会包含 0x0-0x1f 和 0xff 等不可见字符。

我可以检查每个字节都在这个范围内以声明它是否是源代码文件吗?

4

3 回答 3

2

如果它是文本文件,您真的需要以文本模式读取文件吗?你可以binmode无条件使用。

如果您有一段处理文本文件的代码,它可以过滤掉任何无关的回车符 (0D)。如果你没有这样的一段代码,那么回车是否留在里面肯定没关系。

于 2012-10-11T06:18:01.440 回答
2

如果您对安全性有疑虑,只需确保将可执行文件与数据分开即可。binmode对此无济于事:它可用于克服 DOS 和后代上的行尾恐惧,并可用于指定透明编码。

出于您的考虑,所有用户上传的文件都是敌对的。没有“安全”格式,因此将“二进制”与“文本”文件分开是没有用的。不要相信简单的启发式方法。(例如 Perl 允许在变量名中使用控制字符!)

在处理用户数据时,您应该确保没有未经检查的输入到达 Perl 的几个关键部分:

  1. 正则表达式——任意代码可以通过(?{}) and (??{}).
  2. system, exec, qx(), 反引号——不言自明
  3. eval— 插入变量时要小心。
  4. 其他有趣的点是open,glob和 C-ish 字符串函数的参数。

binmode不在其中。

如果您必须提供用户指定的数据,请尝试将其传递给未处理的数据。例如,对于用户定义的样式表,它属于 php 无法解释的目录。如果是图像,您可以尝试在收到文件后转换文件并保存等效但可能安全的变体。

于 2012-10-10T16:37:23.967 回答
1

问题是在现代 POSIX 系统上,二进制文件和文本文件没有区别。一个字节是一个字节是一个字节。

我宁愿尝试另一种方法。如果您使用 Linux / Unix,您可以直接利用file使用“魔术”的实用程序来查看文件的第一个字节(或在某些情况下更远)并确定其类型;在 Windows 中,您必须先安装它。该实用程序使捕获可执行文件、zip 文件等变得相对简单。

在 Perl 中,您可以通过模块File::Type使用它。

于 2012-10-10T16:12:59.033 回答