【问题标题】:What happens when a Java String overflows?当 Java 字符串溢出时会发生什么?
【发布时间】:2020-03-19 11:02:13
【问题描述】:

据我了解,Java Strings 只是一个字符数组,最大长度为整数值。 如果我正确理解this answer,则可能会导致字符串溢出——尽管是在“不寻常的情况”中。

由于 Java 字符串基于 char 数组并且 Java 会自动检查数组边界,因此缓冲区溢出仅在不寻常的情况下才可能发生:

  1. 如果通过 JNI 调用本机代码
  2. 在 JVM 本身中(通常用 C++ 编写)
  3. 解释器或 JIT 编译器无法正常工作(Java 字节码强制边界检查)

如果我错了,请纠正我,但我相信这意味着您可以在数组边界之外写入,不会触发ArrayIndexOutOfBounds(或类似的)异常。

我在 C++ 中遇到过缓冲区溢出的问题,我可以找到很多关于 other languages 的建议,但没有人专门回答如果您使用 String(或任何其他数组类型)导致缓冲区溢出会发生什么Java。

我知道 Java 字符串是经过边界检查的,并且不能仅由本机 Java 代码溢出(除非编译器或 JVM 中存在问题,根据上面的第 2 点和第 3 点),但第一点意味着技术上有可能将 char[] 置于...不受欢迎的位置。

鉴于此,假设以上是正确的,我对 Java 中此类问题的行为有两个具体问题:

  1. 如果一个字符串可以溢出,当它溢出时会发生什么?
  2. 这种行为会产生什么影响?

提前致谢。

【问题讨论】:

  • 您不能仅使用 Java 代码溢出字符串。字符串是不可变的。
  • 即使内部表示也因version and runtime flags而异。 Java 摆脱了某些语言中存在的“正常”缓冲区溢出,因此如果您设法得到一个,可能很难确定究竟会发生什么。在大多数情况下,可能(半受过教育的猜测)是一个硬错误,而不是一个容易被利用的安全漏洞。

标签: java arrays string char overflow


【解决方案1】:

为了回答你的第一个问题,我很幸运实际上导致了这样的错误,并且执行刚刚停止抛出这些错误之一:

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

这就是我的情况,我不知道这是否代表安全问题,例如 C 和 C++ 中的缓冲区溢出。

【讨论】:

  • 大小为 Integer.MAX_VALUE 的 string/char[] 将需要大约。 8.6GB 的 RAM 可以完全填充,每个字符 2 位。如果您为 JVM 分配 9GB 以上的 RAM,您应该能够将更多数据放入数组中 - 将 -Xmx9G 添加到您的启动参数中。我认为默认是1GB左右?
【解决方案2】:

Java 中的 String 是不可变的,因此一旦创建,就不会写入 char 的底层数组或 byte 的数组(这取决于 Java 版本和 String 的内容是否使用其中一个或另一个)。好的,使用 JNI 可以避免这种情况,但是使用纯 Java,不可能离开数组的边界而不会导致 ArrayOutOfBoundsException 或类似的。

在字符串处理的上下文中导致某种溢出的唯一方法是创建一个太长的新字符串。确保您的 JVM 将有足够的堆(大约 36 GB),创建一个 Integer.MAX_VALUE - 1 的 char 数组,适当地填充它,使用该数组调用 new String( byte [] ),然后执行

var string = string.concat( new String( array ) );

但结果只是一个异常,告诉你它试图创建一个太大的数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2017-02-17
    相关资源
    最近更新 更多