可以将null字符传递给字符串中间的argv吗?

问题描述 投票:0回答:1
#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中传递。我想确保这是操作系统的限制,但不是shell。因此,不可能在argv中的字符串中间传递空字符。有人可以证实吗?谢谢。

$ ./main.exe $'abc\000xyz' 7 | xxd
00000000: 6162 6300 3700 53                        abc.7.S
c linux exec argv
1个回答
0
投票

所有程序都是通过exec调用开始的,尽管有OS实现,让我们看看POSIX标准对exec functions的看法。

int execve(const char * path,char * const argv [],char * const envp []);

argv是传递给程序的参数,envp是环境变量。

argv和environ数组均由空指针终止。终止argv数组的空指针不计入argc。

参数argv是一个到​​以null结尾的字符串的字符指针数组。

因此,很容易得出结论:

  1. 空(零长度)字符串可以传递给argv
  2. NULL字符串不能传递给argv,它将终止argv,并丢弃所有后面的参数。
  3. argv中的任何字符串都不能包含\x0字符,\x0将终止当前参数字符串。

解释跑步时发生的事情

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 ...>

它表明xargs在调用\x0时可能将包含prog的参数分成两个参数。不是由shell完成的,不是由OS,libc完成的,而是由xargs完成的

© www.soinside.com 2019 - 2024. All rights reserved.