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

发布于 2024-12-23 10:07:16 字数 104 浏览 3 评论 0原文

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

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

In any C program, the command line argument argv[0] points to the name used to invoke the program. Is there any circumstance in which it will point to an empty string ""?

An example code snippet for such a case would be a good reference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你的他你的她 2024-12-30 10:07:16

它是实现定义的。 §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] 永远不会null 且始终指向字符串,但如果 n 为零,则 argv[0] 为 null。)

当然,在实践中,您只需要确保您的目标平台按照需要运行即可。

It's implementation defined. §5.1.2.2.1 abridged:

  • If the value of argc is greater than zero, the array members argv[0] through
    argv[argc-1] inclusive shall contain pointers to strings, which are given
    implementation-defined values by the host environment prior to program startup. The
    intent is to supply to the program information determined prior to program startup
    from elsewhere in the hosted environment. [...]

  • If the value of argc is greater than zero, the string pointed to by argv[0]
    represents the program name; argv[0][0] shall be the null character if the
    program name is not available from the host environment. [...]

So if argc is greater than zero, it's quite the intention that argv[0] never be an empty string, but it could happen. (Note that with argc equal to n, argv[0] through argv[n - 1] are never null and always point to a string. The string itself may be empty, though. If n is zero, argv[0] is null.)

In practice, of course, you just need to make sure the platforms your targetting behave as needed.

┾廆蒐ゝ 2024-12-30 10:07:16

是的。

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

argc 的值应为非负数。

argv[argc] 应为空指针。

[...]

如果argc的值大于零,则该字符串指向
其中argv[0]代表程序名称argv[0][0] 应为
如果主机无法提供程序名称,则为空字符
环境。如果 argc 的值大于 1,则字符串
argv[1]argv[argc-1] 指向的表示
程序参数

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

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

Yes.

The C language standard explicitly allows for the possibility that argv[0] can be a null pointer, or that it can point to an empty string (""). N1256 5.1.2.2.1p2:

The value of argc shall be nonnegative.

argv[argc] shall be a null pointer.

[...]

If the value of argc is greater than zero, the string pointed to
by argv[0] represents the program name; argv[0][0] shall be
the null character if the program name is not available from the host
environment. If the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent the
program parameters.

On Unix-like systems, programs are invoked by one of the exec() family of functions (execl(), execlp(), etc.), which allow the caller to specify exactly what arguments are passed to the main() function. (It's even possible to invoke a program in ways that violate the requirements imposed by the C standard.)

Note that the standard says that argv[0] (assuming it's neither null nor empty) "represents the program name". The standard is deliberately vague about how it represents the program name. In particular, it needn't provide a name by which the program can be invoked (since the standard doesn't even require that programs can be invoked by name).

千柳 2024-12-30 10:07:16

其他回复引用了 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"
$ 

第一次运行 argv0 设置echoargvargv[0] 为 NULL。
第二次运行使其成为空字符串。
第三次运行只是为了好玩:注意 argv[0] 不需要
与程序的实际名称有关的任何内容。

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

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

更好:

const char *program_name = "some default name"; /* (global) variable */
if (argv[0] && argv[0][0])
    program_name = argv[0];
printf("usage: %s [options] [FILE]...\n", program_name);

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

Other replies have quoted the C standard and shown that argv[0] and can be NULL or it can be the empty string (""). You should write your program with the assumption that this can happen, because otherwise you are creating a (small) security risk. It's easy to invoke your program and set argv to anything an attacker wants. As proof, consider the following two programs. The first one, echoargv.c prints out the contents of 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);
}

The second one, argv0, invokes any other program and lets the user specify the other program's 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);
}

(This is a Posix-specific version. Non-standard environments may need changes.)

Here's how to use them:

$ 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"
$ 

The first run of argv0 sets echoargv's argv[0] to be NULL.
The second run makes it be the empty string.
The third run is there just for fun: note how argv[0] doesn't need to have
anything to do with the actual name of the program.

How can this bite you? If, for example, you blindly print out the name of your program in a usage message:

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

Better:

const char *program_name = "some default name"; /* (global) variable */
if (argv[0] && argv[0][0])
    program_name = argv[0];
printf("usage: %s [options] [FILE]...\n", program_name);

If you don't do this, an attacker can cause your program to segfault at will, or might get your program to report entirely wrong things to the user.

新雨望断虹 2024-12-30 10:07:16

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

argv[0] can be null in C, for example if you directly invoke a main function (with some tricks can be done in C). I don't know if C++ allows direct main invocation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文