可以将空字符传递给字符串中间的 argv 吗? [英] Can the null character to be passed to argv in the middle of a string?
问题描述
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
write(STDOUT_FILENO, argv[1], atoi(argv[2]));
return 0;
}
以下输出(在 Ubuntu 上以 bash 运行)显示 'xyz' 未在 argv 中传递.我想确保这是操作系统的限制,而不是外壳的限制.因此,不可能在 argv 中的字符串中间传递空字符.有人可以确认吗?谢谢.
The following output (run in bash on Ubuntu) shows that 'xyz' is not passed in argv. I want to make sure that this is the limitation of the OS but not the shell. So it would not be possible to pass a null character in the middle of a string in argv. Could anybody confirm? Thanks.
$ ./main.exe $'abc\000xyz' 7 | xxd
00000000: 6162 6300 3700 53 abc.7.S
推荐答案
所有程序都由 exec
调用开始,尽管有操作系统实现,让我们看看 POSIX 标准对 exec
函数.
All program start by exec
calls, despite OS implementations, lets see what does POSIX standard says about exec
functions.
int execve(const char *path, char *const argv[], char *const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);
argv
是传递给程序的参数,envp
是环境变量.
argv
are arguments passed to the program, envp
are environment variables.
argv 和environ 数组均以空指针终止.终止argv数组的空指针不计入argc.
The argv and environ arrays are each terminated by a null pointer. The null pointer terminating the argv array is not counted in argc.
参数 argv 是一个指向空终止字符串的字符指针数组.
The argument argv is an array of character pointers to null-terminated strings.
所以,很容易得出结论:
So, it is very easy to conclude:
- 空(零长度)字符串可以传递给
argv
NULL
字符串不能传递给 argv,它会终止argv
,并丢弃所有后面的参数.argv
中的任何字符串都不能包含\x0
字符,\x0
将终止当前的参数字符串.
- Empty (zero length) string can be passed to
argv
NULL
string can't be passed to argv, it will terminateargv
, and discard all following arguments.- any string in
argv
can't contain\x0
character,\x0
will terminate the current parameter string.
解释运行时发生了什么
python -c 'print "\x30\x00\x31"' | xargs --null prog
试试:
python -c 'print "\x30\x00\x31"' | strace -f xargs --null echo
我们可以找到:
...
...
...
read(0, "0\0001\n", 4096) = 4
...
...
...
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f09f46d9850) = 21232
strace: Process 21232 attached
...
...
...
[pid 21232] execve("/bin/echo", ["echo", "0", "1\n"], 0x7ffe5ccd7638 /* 74 vars */ <unfinished ...>
这表明在调用 prog
时,xargs
可能将包含 \x0
的参数分成两个参数.不是由 shell 完成的,不是由 OS、libc 完成的,而是 xargs
It shows that xargs
potentially separate argument containing \x0
into two arguments when calling prog
. Not done by shell, not done by OS, libc, but xargs
这篇关于可以将空字符传递给字符串中间的 argv 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!