数据溢出安全

参考网页:

“整数溢出”(integer overflow)在某些时候是一个 BUG,但是在其他时候也可能是一种 Trick,熟悉 C/C++ 的程序员可能会经常利用整数溢出能带来的便利操作,例如在一个 struct 或者 union 里面使用整数溢出来达到某些目的,因此,整数溢出更像是一种现象 —— 不过,大多数时候,它对大多数人而言,是 Unsafe 的操作。

Rust 作为一门内存安全的语言,将整数溢出分成了以下两种情况进行处理:

  1. debug 编译下,编译器将对所有运算进行溢出检查,一旦发生 overflow 就马上 panic 退出程序;
  2. release 编译下,为了提高运行速度,编译器不插入检查代码,一旦发生 overflow,其将舍弃高位。

同时,还可以使用编译参数 -C overflow-checks=yes-C overflow-checks=no 来开启或者关闭溢出检查。

除此之外,Rust 还提供了 debugrelease 下通用的溢出检查方式:手动溢出检查chekc_*saturating_*wrapping_*,其中 * 代表的是各种运算,例如 muladd 等。

  • check_* 系列函数的返回值是一个 Option,发生溢出时则返回 None

  • saturating_* 系列函数的返回值是一个整数,发生溢出时则返回该类型的极值,分别代表上溢和下溢;

  • wrapping_* 系列函数则是用来消除 debug 模式下的警告,即返回抛弃掉最高位后的运算结果。