-
Notifications
You must be signed in to change notification settings - Fork 10
Description
qbsdiff is a binary diff/patch library and tool that are compatible with bsdiff 4.0.
Its use of unsafe is for creating (or extending) Vec<u8>s with uninitialized content; this turns out to likely be undefined behaviour.
Sent fixes as hucsmn/qbsdiff#3 :
-
In one case (
qbsdiff), the unsafe vector was only used locally, and could be easily replaced with safe code without extra overhead (no extra allocations or writes); there were 2 extra benefits:- the safe version clears the vector after use, so it's obvious no data can leak when reusing it;
- might be faster and more readable as we eliminated complex iterator chains.
-
In the second case (
qbspatch), the unsafe vectors were shared across many functions (through aContextstruct), and it was easier to replace theunsafecode with safe versions that initialize the allocated space to 0, though I will try to remove that overhead.
I believe this is a generalisable pattern: it isn't the first time I run into uses of unsafe to create known-length byte arrays whose contents are uninitialized. They can usually be replaced with:
- construction with
Vec::with_capacity; - writing to the vector with
Vec::extendrather than using mutable slices; - using
Vec::clearto ensure data doesn't leak when reusing that buffer.
Would it be good idea to request a clippy lint for such code, given that many (wrongly) believe it to be UB-free:
let v = Vec::with_capacity(s)
unsafe {
v.set_length(s);
}