0.1.0 (current) Thoroughness: Medium Understanding: High
by HeroicKatora on 2019-10-31
This review is from Crev, a distributed system for code reviews. To add your review, set up cargo-crev
.
0.1.0 (current) Thoroughness: Medium Understanding: High
by HeroicKatora on 2019-10-31
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.
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 whenf
returnstrue
and some instantiation has|a,b| a==b
as this argument. Consequently, theincompatible
parameter is filled with the in-place branch in thefallback
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 tomap_vec(self, f)
(note: thef
here is from the parameters ofmap
). Themap_vec
function is anunsafe
function eventually doing the equivalent oflet (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: