diff options
Diffstat (limited to '')
-rw-r--r-- | src/tools/clippy/src/docs/uninit_vec.txt | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/tools/clippy/src/docs/uninit_vec.txt b/src/tools/clippy/src/docs/uninit_vec.txt new file mode 100644 index 000000000..cd50afe78 --- /dev/null +++ b/src/tools/clippy/src/docs/uninit_vec.txt @@ -0,0 +1,41 @@ +### What it does +Checks for `set_len()` call that creates `Vec` with uninitialized elements. +This is commonly caused by calling `set_len()` right after allocating or +reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`. + +### Why is this bad? +It creates a `Vec` with uninitialized data, which leads to +undefined behavior with most safe operations. Notably, uninitialized +`Vec<u8>` must not be used with generic `Read`. + +Moreover, calling `set_len()` on a `Vec` created with `new()` or `default()` +creates out-of-bound values that lead to heap memory corruption when used. + +### Known Problems +This lint only checks directly adjacent statements. + +### Example +``` +let mut vec: Vec<u8> = Vec::with_capacity(1000); +unsafe { vec.set_len(1000); } +reader.read(&mut vec); // undefined behavior! +``` + +### How to fix? +1. Use an initialized buffer: + ```rust,ignore + let mut vec: Vec<u8> = vec![0; 1000]; + reader.read(&mut vec); + ``` +2. Wrap the content in `MaybeUninit`: + ```rust,ignore + let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000); + vec.set_len(1000); // `MaybeUninit` can be uninitialized + ``` +3. If you are on 1.60.0 or later, `Vec::spare_capacity_mut()` is available: + ```rust,ignore + let mut vec: Vec<u8> = Vec::with_capacity(1000); + let remaining = vec.spare_capacity_mut(); // `&mut [MaybeUninit<u8>]` + // perform initialization with `remaining` + vec.set_len(...); // Safe to call `set_len()` on initialized part + ```
\ No newline at end of file |