在 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
代替 gets
,snprintf
代替 sprintf
,strsep
代替 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" 并不能解决所有问题。)
作为 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
代替 gets
,snprintf
代替 sprintf
,strsep
代替 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" 并不能解决所有问题。)