作为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。任何人都可以告诉我一种安全的摇滚方式吗?避免下溢,溢出等
首先,不要使用任何_s
函数。它们是C11的一个可选功能,据我所知,它从未被任何人完全实现,甚至微软也没有完全实现它们,并且已经提议将它们再次删除;更重要的是,他们实际上并没有解决他们声称要解决的问题。 (目的是为了与危险的字符串相关的函数进行一系列替换,但事实证明这不起作用;在C程序中修复与字符串相关的安全漏洞需要对其进行实际的重新设计。真正无法安全使用的功能已经有便携式替换,例如fgets
而不是gets
,snprintf
而不是sprintf
,strsep
而不是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
返回的数字。 (这是一个如何交换“强化”字符串函数不能解决所有问题的示例。)