argv [0]可以包含空字符串吗?

时间:2011-12-29 08:19:56

标签: c argv

在任何C程序中,命令行参数argv[0]指向用于调用程序的名称。是否有任何情况会指向空字符串""

这种情况的示例代码段将是一个很好的参考。

4 个答案:

答案 0 :(得分:9)

它是实现定义的。 §5.1.2.2.1删节:

  
      
  • 如果argc的值大于零,则数组成员argv[0]通过   argv[argc-1]包含应包含指向字符串的指针   程序启动前主机环境实现定义的值。该   意图是在程序启动之前为程序提供信息   来自托管环境中的其他地方。 [...]

  •   
  • 如果argc的值大于零,则argv[0]指向的字符串   代表程序名称; argv[0][0]如果是,则为空字符   程序名称不能从主机环境中获得。 [...]

  •   

因此,如果argc大于零,那么意图 argv[0]永远不会是空字符串,但它可能会发生。 (请注意,当argc等于n时,argv[0]argv[n - 1]永远不会为空且始终指向字符串。但字符串本身可能为空。如果{{{} 1}}为零,n为空。)

在实践中,当然,您只需要确保目标平台的行为符合要求。

答案 1 :(得分:7)

C语言标准明确允许argv[0]可以是空指针,,它可以指向空字符串("")。 N1256 5.1.2.2.1p2:

  

argc 的值应为非负值。

     

argv [argc] 应为空指针。

     

[...]

     

如果 argc 的值大于零,则指向该字符串   通过 argv [0] 表示程序名称; argv [0] [0] 应该是   如果程序名称不可从主机获得,则为null字符   环境。如果 argc 的值大于1,则为字符串    argv [1] 指向 argv [argc-1] 代表   程序参数

在类Unix系统上,程序由exec()函数族之一(execl()execlp()等)调用,这允许调用者准确指定哪些参数传递给main()函数。 (甚至可以以违反C标准要求的方式调用程序。)

请注意,标准表示argv[0](假设它既不为空也不为空)“表示程序名称”。该标准故意模糊如何它代表程序名称。特别是,它不需要提供一个可以调用程序的名称(因为标准甚至不要求可以通过名称调用程序)。

答案 2 :(得分:5)

其他回复引用了C标准并显示argv[0]并且可以是NULL,或者它可以是空字符串("")。您应该在假设可能发生这种情况的情况下编写程序,否则您将产生(小)安全风险。调用程序并将argv设置为攻击者想要的任何内容都很容易。作为证据,请考虑以下两个程序。第一个echoargv.c打印出argv的内容:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    int i;
    for (i = 0; i < argc; ++i)
        printf("argv[%d] = \"%s\"\n", i, argv[i]);
    exit(0);
}

第二个,argv0,调用任何其他程序,让用户指定其他程序的argv:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {
    (void) execv(argv[1], argv+2);
    perror("execv");
    exit(1);
}

(这是特定于Posix的版本。非标准环境可能需要更改。)

以下是如何使用它们:

$ gcc -o echoargv echoargv.c 
$ gcc -o argv0 argv0.c 
$ ./argv0 ./echoargv 
$ ./argv0 ./echoargv ''
argv[0] = ""
$ ./argv0 ./echoargv 'this is fun' 'it is fun indeed'
argv[0] = "this is fun"
argv[1] = "it is fun indeed"
$ 

第一轮argv0echoargv的{​​{1}}设置为NULL。 第二次运行使它成为空字符串。 第三次运行只是为了好玩:注意argv[0]不需要如何 与程序的实际名称有关。

这怎么能咬你?例如,如果您在使用消息中盲目打印出程序名称:

argv[0]

更好:

printf("usage: %s [options] [FILE]...\n", argv[0]);

如果您不这样做,攻击者可能会导致您的程序出现段错误,或者可能让您的程序向用户报告完全错误的内容。

答案 3 :(得分:1)

argv [0]在C中可以为null,例如,如果直接调用main函数(可以在C中完成一些技巧)。我不知道C ++是否允许直接主调用。