Repository: GuillaumeGomez/sysinfo (language: rust)

Issue:
Endless loop in `get_user_groups`
**Describe the bug**

`get_user_groups` will end up in an endless loop when the number of groups exceeds `groups.capacity()`.
https://github.com/GuillaumeGomez/sysinfo/blob/927a04b4baba2bb7d624cb468e9d25576bbea689/src/unix/users.rs#L83-L97

The reason for that is that the mechanism to increase the size of `groups` (via `groups.reserve(256)`) is not working as intended.
This is because [`reserve`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.reserve) checks `len()` to avoid reserving new space when there is enough remaining space available as mentioned on the docs:
> After calling reserve, capacity will be greater than or equal to `self.len() + additional`. Does nothing if capacity is already sufficient.

The only modification that affects `groups.len()` when set explicitly on line 97.
https://github.com/GuillaumeGomez/sysinfo/blob/927a04b4baba2bb7d624cb468e9d25576bbea689/src/unix/users.rs#L97

Thus, `groups.len()` will stay `0` when `getgrouplist` returns `-1` and `groups.reserve(256);` will do nothing.

**To Reproduce**
The easiest way to reproduce this is to set the initial capacity as well as the value to increase the size to a very low value (e.g. `1`) and just run it.
https://github.com/GuillaumeGomez/sysinfo/blob/927a04b4baba2bb7d624cb468e9d25576bbea689/src/unix/users.rs#L83
https://github.com/GuillaumeGomez/sysinfo/blob/927a04b4baba2bb7d624cb468e9d25576bbea689/src/unix/users.rs#L94

**The fix**
One possible fix for this would be to call `groups.set_len(nb_groups as _)` before `groups.reserve(256)`.


Discussion / hints:
Thanks for the report and the very detailed explanations, greatly appreciated!

Fix patch:
diff --git a/src/unix/users.rs b/src/unix/users.rs
index e8ef32d07..db5f6bbe4 100644
--- a/src/unix/users.rs
+++ b/src/unix/users.rs
@@ -91,6 +91,9 @@ pub(crate) unsafe fn get_user_groups(
             &mut nb_groups as *mut _ as *mut _,
         ) == -1
         {
+            // Ensure the length matches the number of returned groups.
+            // Needs to be updated for `Vec::reserve` to actually add additional capacity.
+            groups.set_len(nb_groups as _);
             groups.reserve(256);
             continue;
         }


Test patch: