在 C 中使用 getenv_s 来处理 CONTENT_LENGTH

Working with getenv_s in C to process CONTENT_LENGTH

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

Handling POST data sent by html form in CGI C

我正在尝试清理 CONTENT_LENGTH 和 message-body(stdin) 在我的例子中。也就是这里的objective。

所以为了限制上限(防止格式错误 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。谁能告诉我一个安全可靠的使用方法?避免下溢、溢出等

首先,不要使用任何 _s 功能。它们是 C11 的一个 optional 特性,据我所知,从未被任何人完全实现,即使是发明它们的 Microsoft 也没有,并且有人提议再次删除它们;更重要的是,他们实际上并没有解决他们声称要解决的问题。 (目的是为危险的与字符串相关的函数提供一堆替代品,但事实证明那是行不通的;修复 C 程序中与字符串相关的安全漏洞需要经过深思熟虑的实际重新设计。真正无法安全使用的功能已经有了可移植的替代品,例如 fgets 代替 getssnprintf 代替 sprintfstrsep 代替 strtok -- 有时替代品不在 ISO C 中,但它通常足够普遍不用担心,或者您可以从 gnulib.)

获得垫片实现

getenv 保证 return 一个有效的以 NUL 结尾的 C 字符串(或空指针),但该字符串可以是任意长的。在用 C 编写的 CGI 程序的上下文中,"sanitize" 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;
}

strtol 调用之后的 if 语句中的四个子句中的每一个都检查不同的 class 格式错误的输入。你必须在调用之前明确地清除 errno ,因为当它报告溢出时的值 strtol return 也是一个值它可以 return 当没有溢出时,所以区分的唯一方法是查看 errno,但是 errno 可能有一些早期操作的陈旧非零值。

请注意,即使 CONTENT_LENGTH 在句法上有效,也可能 不可信 。也就是说,您可用的实际数据量 POST 可能少于或多于 CONTENT_LENGTH。请务必注意 return 由 read 编辑的数字。 (这是一个例子,说明将字符串函数换成 "hardened" 并不能解决所有问题。)