使VLA比ARGV [1]安全吗?

发布于 2025-02-02 13:11:34 字数 832 浏览 3 评论 0原文

示例代码,将argv [1]作为文件路径,用.png替换其扩展名,或者如果没有发现,则将其附加:

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    if (argc != 2)
        return 1;

    char *lastdot = strrchr(argv[1], '.');
    size_t len = lastdot ? (lastdot - argv[1]) : strlen(argv[1]);

    char outpath[len + sizeof(".png")];
    // ^ this is the important part

    memcpy(outpath, argv[1], len);
    memcpy(outpath + len, ".png", sizeof(".png"));

    printf("%s\n", outpath);
}

我的主要关注点是argv [1]可能只有足够小而不会导致OS本身错误,但是随后由> “。png”添加的额外4个字节串联会导致堆栈溢出分配VLA?

问题在于,我不确定argv或VLA的成员的大小如何受到限制。

显然,诸如path_max之类的常数不受静态数组大小的信任,因此要么是malloc

Example code, treats argv[1] as a file path, replacing its extension with .png or appending it if none is found:

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    if (argc != 2)
        return 1;

    char *lastdot = strrchr(argv[1], '.');
    size_t len = lastdot ? (lastdot - argv[1]) : strlen(argv[1]);

    char outpath[len + sizeof(".png")];
    // ^ this is the important part

    memcpy(outpath, argv[1], len);
    memcpy(outpath + len, ".png", sizeof(".png"));

    printf("%s\n", outpath);
}

My main concern here is that argv[1] may be just small enough to not cause an error from the OS itself, but then the extra 4 bytes added by the ".png" concatenation will cause a stack overflow when allocating the VLA?

The problem is that I'm not really sure how the sizes of either a member of argv or a VLA are limited.

Apparently constants such as PATH_MAX aren't to be trusted for static array sizes, so it's either this or malloc.

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

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

发布评论

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

评论(1

不弃不离 2025-02-09 13:11:34

您的关心是真实的:C标准中没有任何内容可以保证您程序可用的堆栈空间足以分配一个大型VLA,以提供很长的命令线参数加4个字节。在实践中,在现代操作系统上,堆栈空间通常至少1兆字节,命令行的参数仅限于100 kb ...因此您应该安全。

还要注意一些编译器根本不支持VLA,因此从堆分配是一种更便携的方法。

顺便说一下,您可以修改程序以完全避免此问题:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 2)
        return 1;

    char *lastdot = strrchr(argv[1], '.');
    int len = lastdot ? lastdot - argv[1] : strlen(argv[1]);

    printf("%.*s.png\n", len, argv[1]);
    return 0;
}

Your concern is genuine: nothing in the C Standard guarantees that the stack space available to your program will be sufficient to allocate a large VLA for a very long command line argument plus 4 bytes. In practice, on modern operating systems, the stack space is typically at least 1 megabyte and command line arguments are limited to about 100 KB... so you should be safe.

Also beware that some compilers do not support VLAs at all, so allocating from the heap is a more portable approach.

Incidentally, you can modify your program to avoid this issue completely:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 2)
        return 1;

    char *lastdot = strrchr(argv[1], '.');
    int len = lastdot ? lastdot - argv[1] : strlen(argv[1]);

    printf("%.*s.png\n", len, argv[1]);
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文