3 ms·
Rust has a checked_add function for this purpose. Also, by default, Rust's integer operations trap on overflow, so if you wrote the obvious comparator (x-y) th
by hedora 3y ago
Rust has a checked_add function for this purpose.
Also, by default, Rust's integer operations trap on overflow, so if you wrote the obvious comparator (x-y) the program would panic instead of exhibiting undefined behavior.
- adrian_b 3y agoBy default, i.e. in release builds, Rust's integer operations do not trap on overflow. I do not consider that the behavior of a debug build can be considered as "default". I consider the disabling of the overflow traps a very bad practice, which is justified only for specific functions or code sequences that have been analyzed carefully to prove that overflows are impossible. For example, the chain of exploits that have been used to gain complete remote control of any iPhone without detection during many years has included some that were based on integer overflows in the Apple system software.
- trealira 3y ago> For example, the chain of exploits that have been used to gain complete remote control of any iPhone without detection during many years has included some that were based on integer overflows in the Apple system software. For those interested, I found a blog post that covers an iMessage-based zero-click exploit, which was caused by unchecked integer overflow, and a lack of bounds checking done on allocated buffers: https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-into-nso-zero-click.html https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-i...
- tialaramex 3y agoIf you wrote this code as Rust, the resulting bounds miss traps and the exploit doesn't work (but the messaging application fails which is pretty annoying) If you wrote this code in WUFFS it won't compile.
- trealira 3y agoInteresting, I hadn't heard of WUFFS before now. Thanks for telling me about it.
- Arnavion 3y agoFor this specific case, saturating_sub would work fine. The checked_sub way would need an additional `.unwrap_or(-1)` Though of course you wouldn't need to do either because the usual way to write a Rust API that takes comparators is for that comparator to return std::cmp::Ordering, not a signed integer. And if you do make a PartialOrd / Ord impl that isn't transitive, it is guaranteed by the sorting fns in libstd that sorting may be incorrect, but it won't be undefined behavior.