问题标签 [integer-overflow]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
55413 浏览

c - 什么是 C 中的算术下溢和上溢?

C 编程中算术下溢和上溢是什么意思?

0 投票
4 回答
1908 浏览

c - 快速排序示例中的错误(K&R C 书)?

这种快速排序应该将“v[left]...v[right] 排序为升序”;从 K&R(第二版)的 The C Programming Language 复制(无注释):

我认为有一个错误

假设左 = INT_MAX - 1,右 = INT_MAX。由于整数溢出,这不会导致未定义的行为吗?

0 投票
4 回答
2625 浏览

c++ - 没有有用且可靠的方法来检测 C/C++ 中的整数溢出?

不,这不是如何检测整数溢出的副本?. 问题是一样的,但问题是不同的。


gcc 编译器可以优化溢出检查(使用 -O2),例如:

gcc 的人认为这不是一个错误。根据 C 标准,溢出是未定义的行为,它允许编译器执行任何操作。显然,任何事情都包括假设溢出永远不会发生。不幸的是,这允许编译器优化溢出检查。

最近的CERT 论文中描述了检查溢出的安全方法。本文建议在添加两个整数之前执行以下操作:

显然,当您想确保结果有效时,您必须在一系列计算中的每个 +、-、*、/ 和其他操作之前执行类似的操作。例如,如果您想确保数组索引没有超出范围。这太麻烦了,几乎没有人这样做。至少我从未见过系统地执行此操作的 C/C++ 程序。

现在,这是一个基本问题:

  • 在访问数组之前检查数组索引很有用,但不可靠。

  • 使用 CERT 方法检查一系列计算中的每个操作是可靠的,但没有用处。

  • 结论:在 C/C++ 中没有检查溢出的有用且可靠的方法!

我拒绝相信这是编写标准时的意图。

我知道有某些命令行选项可以解决问题,但这并不能改变我们对标准或对它的当前解释存在根本问题的事实。

现在我的问题是:当 gcc 允许他们优化溢出检查时,他们对“未定义行为”的解释是否太过分了,或者 C/C++ 标准是否被破坏?

补充说明: 对不起,您可能误解了我的问题。我不是在问如何解决这个问题——这已经在别处得到了回答。我在问一个关于 C 标准的更基本的问题。如果没有有用且可靠的方法来检查溢出,那么语言本身就是可疑的。例如,如果我创建一个带有边界检查的安全数组类,那么我应该是安全的,但如果边界检查可以被优化掉,我就不安全了。

如果标准允许这种情况发生,那么要么标准需​​要修订,要么标准的解释需要修订。

添加注释 2: 这里的人们似乎不愿意讨论“未定义行为”的可疑概念。C99 标准列出了 191 种不同类型的未定义行为(链接)这一事实表明标准草率。

许多程序员欣然接受“未定义的行为”允许做任何事情的声明,包括格式化你的硬盘。我认为标准将整数溢出归入与写入数组边界外相同的危险类别是一个问题。

为什么这两种“未定义行为”不同?因为:

  • 许多程序依赖于整数溢出是良性的,但是当你不知道那里有什么时,很少有程序依赖于写入数组边界之外的内容。

  • 实际上,在数组边界之外写入可能会造成与格式化硬盘一样糟糕的事情(至少在像 DOS 这样的未受保护的操作系统中),并且大多数程序员都知道这是危险的。

  • 当您将整数溢出放入危险的“任何事情发生”类别时,它允许编译器做任何事情,包括谎报它正在做的事情(在溢出检查被优化的情况下)

  • 使用调试器可以发现诸如写入超出数组边界之类的错误,但优化掉溢出检查的错误却不能,因为在调试时优化通常是关闭的。

  • 在整数溢出的情况下,gcc 编译器显然会避免“任何事情发生”的策略。在许多情况下,它会避免优化,例如循环,除非它可以验证溢出是不可能的。出于某种原因,gcc 人员已经认识到,如果他们在这里遵循“一切顺利”的政策,我们将会有太多错误,但他们对优化掉溢出检查的问题有不同的态度。

也许这里不适合讨论这些哲学问题。至少,这里的大多数答案都是离题的。有没有更好的地方来讨论这个?

0 投票
1 回答
1592 浏览

c# - 停止 ASP.NET 中的整数溢出

我们在工作中使用 Acunetix 对我们的应用程序进行安全扫描。最近我们在下面遇到了以下整数漏洞错误:

整数漏洞

据我所知,报告似乎告诉我们,我们没有阻止查询字符串中的整数溢出攻击。虽然我们确实使用了最终解析为整数的查询字符串,但它们首先被加密,然后Convert.ToInt32()在我们使用它们之前被解密并转换为 int。我知道我们应该TryParse()改用,但即使黑客输入一个高于最大值的整数值,他们在尝试解密甚至尝试转换为整数之前也会失败,我认为这就是整数溢出发生的地方。那是除非解密失败时发生错误?

我对此感到很困惑,谷歌搜索并没有太大帮助,因为大多数与非托管语言(如 c++)有关,而不是 c# 和 asp.net。任何帮助将非常感激。

0 投票
2 回答
288 浏览

c - 故意的价值溢出安全吗?

这个问题可能很愚蠢或偏执,但无论如何:-)。给定以下代码:

如果它知道hiRes周期性溢出并且这种情况得到妥善处理,那么这段代码有什么问题吗?

更新: 结果对我来说非常令人惊讶,因为答案取决于hiResC 标准定义的(有符号或无符号)类型(参见示例)。

0 投票
6 回答
26160 浏览

c++ - 如何在 unsigned int 和 int 之间安全地进行静态转换?

我有一个string代表十六进制数字的 8 个字符,我需要将其转换为int. 这种转换必须保留字符串"80000000"和更高的位模式,即这些数字应该是负数。不幸的是,天真的解决方案:

val > MAX_INT如果(返回值为 0)不适用于我的编译器。将 val 的类型更改为int也会导致更大的数字为 0。我已经从这里的各种答案中尝试了几种不同的解决方案,但还没有成功。

以下是我所知道的:

  • 我在 OpenVMS 上使用 HP 的 C++ 编译器(我相信使用的是安腾处理器)。
  • sizeof(int)在我的代码将运行的每个架构上至少有 4 个。
  • 从数字 > INT_MAX 转换为 int 是实现定义的。在我的机器上,它通常会导致 0,但有趣的是,当值太大时,转换 fromlongint导致结果。INT_MAX

很难正确地做到这一点,或者至少对我来说是这样。有谁知道这个的便携式解决方案?

更新:

更改static_castreinterpret_cast会导致编译器错误。一条评论提示我尝试 C 风格的转换:return (int)val在上面的代码中,它起作用了。 在这台机器上。 这在其他架构上仍然安全吗?

0 投票
5 回答
8004 浏览

python - 在 Python 中模拟整数溢出

Python 2 有两种整数数据类型intlong,并根据需要自动在它们之间进行转换,尤其是为了避免整数溢出。

我正在用 Python 模拟 C 函数,想知道是否有标准方法可以重新启用整数溢出。对于随机数,我用过

有没有更标准的方法来做同样的事情?

0 投票
3 回答
1139 浏览

php - PHP 未序列化整数从 64 位到 32 位

我一直试图在 32 位服务器上反序列化在 64 位服务器上序列化的对象。我已将我的问题隔离到对象中的一个整数。这是问题的一个小再现。

在 64 位机器上:

在 32 位机器上:

给出错误

现在我明白那些序列化方法不应该用于跨系统数据传输。但是,我们只是试图将数据迁移到另一个系统,而不是主动使用它进行传输。这是一次性的事情。

我认为这可能是由于整数溢出,但即使在 32 位服务器上,我也可以执行类似的操作

它会正常工作。我猜 PHP 整数类型可以扩展到一些 double 类型或类似的东西。但是为什么它在反序列化时不这样做呢?

如何反序列化这些对象?如果我不能,有什么办法可以将它们转换成别的东西?最后,有没有人在 PHP 本身中编写了反序列化方法?或者有关于协议的详细信息?我可以使用它并为这些整数提供一个自定义案例。

谢谢。

注意:我无法访问原始数据,只能访问序列化结果。

0 投票
3 回答
10628 浏览

c - 执行 argc=0 的进程

是否可以执行 argc = 0 的进程?我需要执行一个程序,但它的 argc 等于 0 非常重要。有没有办法做到这一点?我试图在命令行中放置 2^32 个参数,使其看起来好像 argc = 0 但参数数量有最大限制。

0 投票
6 回答
9244 浏览

c - 用 C 检测 uint64_t 整数的乘法溢出

是否有任何有效且可移植的方法来检查在 C 中使用 int64_t 或 uint64_t 操作数的乘法运算何时溢出?

例如,添加 uint64_t 我可以这样做:

但我无法得到类似的简单乘法表达式。

我所想到的就是将操作数分成高和低 uint32_t 部分,并在检查溢出的同时执行这些部分的乘法,这确实很丑陋,而且可能效率也很低。

更新 1:添加了一些实现多种方法的基准代码

更新 2:添加了 Jens Gustedt 方法

基准测试程序:

到目前为止,当假设溢出非常不寻常时,使用浮点过滤大多数情况的情况 4 是最快的,至少在我的计算机上它只比无操作情况慢两倍。

情况 5 比 4 慢 30%,但它始终执行相同的操作,没有任何特殊情况编号需要像 4 那样更慢的处理。