This review is from Crev, a distributed system for code reviews. To add your review, set up cargo-crev.

0.1.0 (current) Rating: Negative Thoroughness: Medium Understanding: High

by HeroicKatora on 2019-10-31

Has unsoundness in a major, safe interface.

The main utility for Vec can reuse an allocation of differing element size thus violating the explicit requirements of Vec::from_raw_parts and in particular the allocator contract, potentially leading to memory corruption on drop of the resulting Vec.

The interface affected are (maybe not complete):

  • MapVecInPlace::map
  • MapVecInPlace::map_in_place
  • MapVecInPlace::filter_map
  • MapVecInPlace::filter_map_in_place

An analysis of the code to show the issue:

In a macro, this code checks for various size and alignment constraints on deciding whether to execute an in-place branch or a fallback (that may panic in some variants).

unsafe { if size!($a) == 0 || size!($b) == 0 { $zero } else if align!($a) != align!($b) { $alignment } else if $f(size!($a),size!($b)) { $incompatible } else { $ok } }

Already a naming issue appears, as the $incompatible branch is actually taken when f returns true and some instantiation has |a,b| a==b as this argument. Consequently, the incompatible parameter is filled with the in-place branch in the fallback branch where the parameter is $ok:expr

Note that the check for map is |a,b| a%b==0 and it invokes $fallback with the $ok:expr argument set to map_vec(self, f) (note: the f here is from the parameters of map). The map_vec function is an unsafe function eventually doing the equivalent of

let (ptr, len, cap) = /* The obvious */; // Some transformation code on raw. Vec::from_raw_parts(ptr, len, cap)

This violates very clearly the contract which states:

ptr's T needs to have the same size and alignment as it was allocated with


Crates in the crates.io registry are tarball snapshots uploaded by crates' publishers. The registry is not using crates' git repositories. There is absolutely no guarantee that the repository URL declared by the crate belongs to the crate, or that the code in the repository is the code inside the published tarball.

To review the actual code of the crate, it's best to use cargo crev open map_in_place. Alternatively, you can download the tarball of map_in_place v0.1.0 or view the source online.