Des*_*tor 60 c++ unsigned-integer
我正在看这个视频.Bjarne Stroustrup说无符号整数容易出错并导致错误.所以,你应该只在你真正需要的时候使用它们.我还读过有关Stack Overflow的问题之一(但我不记得哪一个)使用无符号整数会导致安全漏洞.
它们如何导致安全漏洞?有人可以通过给出一个合适的例子来清楚地解释它
Ami*_*ory 49
一个可能的方面是无符号整数可能导致循环中有些难以发现的问题,因为下溢会导致大量数据.我无法计算(即使使用无符号整数!)我做了多少次这个bug的变种
for(size_t i = foo.size(); i >= 0; --i)
...
Run Code Online (Sandbox Code Playgroud)
请注意,根据定义,i >= 0
始终为真.(是什么原因导致这首先是,如果i
签订,编译器会警告与一个可能溢出size_t
的size()
).
还有其他原因提到危险 - 这里使用的是无符号类型!在我看来,其中最强大的是签名和未签名之间的隐式类型转换.
Bau*_*gen 36
一个重要因素是它使循环逻辑变得更难:想象一下,你想迭代除了数组的最后一个元素(在现实世界中确实发生).所以你写下你的功能:
void fun (const std::vector<int> &vec) {
for (std::size_t i = 0; i < vec.size() - 1; ++i)
do_something(vec[i]);
}
Run Code Online (Sandbox Code Playgroud)
看起来不错,不是吗?它甚至可以用非常高的警告级别进行干净编译!(实时)所以你把它放在你的代码中,所有的测试运行顺利,你忘了它.
现在,稍后,有人来了一个空的通行证vector
到你的功能.现在有一个带符号的整数,你希望你会注意到符号比较编译器警告,引入了适当的强制转换,而不是首先发布了错误代码.
但是在使用无符号整数的实现中,您将换行并且循环条件变为i < SIZE_T_MAX
.灾难,UB,最有可能崩溃!
我想知道他们是如何导致安全漏洞的?
这也是一个安全问题,特别是它是一个缓冲区溢出.可能利用这种方法的一种方法是,如果do_something
能做一些攻击者可以观察到的事情.他或许可以找到输入的内容do_something
,而攻击者无法访问的数据会从您的内存中泄露出来.这将是一个类似于Heartbleed bug的场景.(感谢棘轮怪人在评论中指出这一点.)
Mik*_*our 23
我不会只是为了回答问题而观看视频,但有一个问题是如果混合使用有符号和无符号值,可能会发生令人困惑的转换.例如:
#include <iostream>
int main() {
unsigned n = 42;
int i = -42;
if (i < n) {
std::cout << "All is well\n";
} else {
std::cout << "ARITHMETIC IS BROKEN!\n";
}
}
Run Code Online (Sandbox Code Playgroud)
促销规则意味着i
转换unsigned
为比较,给出大的正数和惊人的结果.
Mar*_*o13 11
虽然它可能只被视为现有答案的变体:参考Scott Meyers 1995年9月的"接口中的签名和无符号类型",C++报告,避免接口中的无符号类型尤为重要.
问题是,无法检测到界面客户端可能产生的某些错误(如果他们能够制作它们,他们就会制作它们).
给出的例子是:
Run Code Online (Sandbox Code Playgroud)template <class T> class Array { public: Array(unsigned int size); ...
以及此类的可能实例化
Run Code Online (Sandbox Code Playgroud)int f(); // f and g are functions that return int g(); // ints; what they do is unimportant Array<double> a(f()-g()); // array size is f()-g()
值的差异返回的f()
和g()
可能是负的,对于原因一个可怕的数字.Array
类的构造函数将接收此差异作为隐式转换为的值 unsigned
.因此,作为Array
类的实现者,人们无法区分错误传递的值-1
和非常大的数组分配.
unsigned int 的一个大问题是,如果你从 unsigned int 0 中减去 1,结果不是负数,结果不小于你开始的数字,但结果是最大可能的 unsigned int 值。
unsigned int x = 0;
unsigned int y = x - 1;
if (y > x) printf ("What a surprise! \n");
Run Code Online (Sandbox Code Playgroud)
这就是 unsigned int 容易出错的原因。当然,unsigned int 的工作方式与设计时完全相同。如果您知道自己在做什么并且不犯错误,那么绝对安全。但大多数人都会犯错误。
如果你使用一个好的编译器,你会打开编译器产生的所有警告,当你做了可能是错误的危险事情时,它会告诉你。