在C中使用getenv_s来处理CONTENT_LENGTH

问题描述 投票:-1回答:1

作为C的新手,我刚刚遇到了C11添加getenv_s。这是我实际上要做的事情:

Handling POST data sent by html form in CGI C

在我的情况下,我正在尝试清理CONTENT_LENGTH和message-body(stdin)。这就是目标。

所以为了限制上限(反对格式错误的CONTENT_LENGTH,试图导致溢出),我尝试使用数组而不是指针,如下所示:

char some[512];
some = getenv("CONTENT_LENGTH");

它自然引发了一个错误(从char *类型中分配char [512]类型时不兼容的类型)。所以我假设,

Q1。 getenv已经是一个字符串?

然后我遇到了“getenv_s” http://en.cppreference.com/w/c/program/getenv

Q2。任何人都可以告诉我一种安全的摇滚方式吗?避免下溢,溢出等

c security buffer overflow
1个回答
2
投票

首先,不要使用任何_s函数。它们是C11的一个可选功能,据我所知,它从未被任何人完全实现,甚至微软也没有完全实现它们,并且已经提议将它们再次删除;更重要的是,他们实际上并没有解决他们声称要解决的问题。 (目的是为了与危险的字符串相关的函数进行一系列替换,但事实证明这不起作用;在C程序中修复与字符串相关的安全漏洞需要对其进行实际的重新设计。真正无法安全使用的功能已经有便携式替换,例如fgets而不是getssnprintf而不是sprintfstrsep而不是strtok - 有时替换不是在ISO C但它通常足够广泛而不用担心,或者你可以从gnulib获得一个shim实现。)

保证getenv返回有效的NUL终止的C字符串(或空指针),但字符串可能是任意长的。在用C语言编写的CGI程序的上下文中,“清理”CONTENT_LENGTH环境变量值的正确方法是将其提供给strtol并仔细检查错误:

/* Returns a valid content_length, or -1 on error.  */
long get_content_length(void)
{
    char *content_length, *endp;
    long rv;

    content_length = getenv("CONTENT_LENGTH");
    if (!content_length) return -1;
    errno = 0;
    rv = strtol(content_length, &endp, 10);
    if (endp == content_length || *endp || errno || rv <= 0)
        return -1;
    return rv;
}

if调用之后,strtol声明中的四个条款中的每一个都检查了不同类型的错误输入。你必须在调用之前明确地清除errno,因为strtol在报告溢出时返回的值也是一个值,它可以在没有溢出时返回,所以区分的唯一方法是查看errno,但是errno可能有一个来自某些早期操作的陈旧非零值。

请注意,即使CONTENT_LENGTH在语法上有效,它也可能不值得信任。也就是说,您可用的实际POST数据量可能小于或大于CONTENT_LENGTH。一定要注意read返回的数字。 (这是一个如何交换“强化”字符串函数不能解决所有问题的示例。)

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