Coc*_*tch 6 shell bash dash null
因为这就是他们中的一些人正在做的事情。
> echo echo Hallo, Baby! | iconv -f utf-8 -t utf-16le > /tmp/hallo
> chmod 755 /tmp/hallo
> dash /tmp/hallo
Hallo, Baby!
> bash /tmp/hallo
/tmp/hallo: /tmp/hallo: cannot execute binary file
> (echo '#'; echo echo Hallo, Baby! | iconv -f utf-8 -t utf-16le) > /tmp/hallo
> bash /tmp/hallo
Hallo, Baby!
> mksh /tmp/hallo
Hallo, Baby!
> cat -v /tmp/hallo
#
e^@c^@h^@o^@ ^@H^@a^@l^@l^@o^@,^@ ^@B^@a^@b^@y^@!^@
^@
Run Code Online (Sandbox Code Playgroud)
这是标准实际要求的一些兼容性问题吗?因为它看起来相当危险和出乎意料。
Sté*_*las 11
根据POSIX,
输入文件应为文本文件,但行长不受限制¹
输入中的 NUL 字符²使其成为 non-text,因此就 POSIX 而言,行为未指定,因此sh实现可以做任何他们想做的事情(并且符合 POSIX 的脚本不能包含 NUL)。
有一些 shell 会扫描前几个字节是否为 0,并假设您尝试错误地执行非脚本文件而拒绝运行脚本。
这是因为是非常有用exec*p()的功能,env命令sh,find -exec......都需要调用一个shell来解释命令,如果在与ENOEXEC系统返回execve(),因此,如果您尝试为错误的架构执行命令,这是更好地得到一个亿韩元'不要从 shell执行二进制文件错误,而不是 shell 试图将其理解为 shell 脚本。
这是 POSIX 允许的:
如果可执行文件不是文本文件,shell 可能会绕过此命令执行。
在标准的下一次修订中将更改为:
shell 可以应用启发式检查来确定要执行的文件是否可以是脚本,并且如果它确定该文件不能是脚本,则可以绕过此命令执行。在这种情况下,它将写入一条错误消息,并返回 126 的退出状态。
注意:拒绝不是脚本的文件的常见启发式方法是在固定长度的 <newline> 字节之前定位 NUL 字节文件的前缀。由于 sh 需要接受具有无限行长的输入文件,因此启发式检查不能基于行长。
这种行为可能会妨碍 shell 自解压档案,尽管其中包含一个 shell 标头,后跟二进制数据¹。
该zsh外壳支持NUL在其输入,但需要注意的是完全无效,不能放在一个参数传递execve(),所以你只能在争论或名称中使用它内置的命令或功能:
$ printf '\0() echo zero; \0\necho \0\n' | zsh | hd
00000000 7a 65 72 6f 0a 00 0a |zero...|
00000007
Run Code Online (Sandbox Code Playgroud)
(这里定义和调用一个以 NUL 为名称的函数,并将一个 NUL 字符作为参数传递给内置echo命令)。
有些人会剥掉它们,这也是明智的做法。NULs 有时用作填充。例如,它们被终端忽略(它们有时被发送到终端以给它们时间来处理复杂的控制序列(如回车(字面意思))。文件中的漏洞似乎被 NUL 等填充。
请注意,非文本不限于 NUL 字节。它也是在语言环境中不能形成有效字符的字节序列。例如,0xc1 字节值不能出现在 UTF-8 编码文本中。因此,在使用 UTF-8 作为字符编码的语言环境中,包含此类字节的文件不是有效的文本文件,因此不是有效的sh脚本³。
在实践中,这yash是我所知道的唯一一个会抱怨这种无效输入的 shell。
¹ 在标准的下一次修订中,它将更改为
输入文件可以是任何类型,但根据 shell 语法(XREF 到 XSH 2.10.2 Shell 语法规则)解析的文件的初始部分应由字符组成,并且不应包含 NUL 字符。外壳不应强制执行任何行长度限制。
明确要求 shell 支持以没有 NUL 字节的语法有效部分开头的输入,即使其余部分包含 NUL,以说明自解压存档。
² 和字符意味着按照语言环境的字符编码进行解码(请参阅 的输出locale charmap),并且在 POSIX 系统上,NUL 字符(其编码始终为字节 0)是唯一编码包含字节 0 的字符。在其他换句话说,UTF-16 不是可用于 POSIX 语言环境的字符编码之一。
³然而,存在的区域设置的脚本内改变的问题(如当LANG/ LC_CTYPE/ LC_ALL/LOCPATH变量被分配),并在该点处改变花费的壳解释输入效果。
| 归档时间: |
|
| 查看次数: |
1019 次 |
| 最近记录: |