Bug 1363201 - fix the impl of WrVecU8, r=jrmuizel
Two bugs:
* We were failing to (re)initialize the length to 0, leading to segfaults on Rust processing "empty" lists.
* We were setting the pointer of empty Vec's to null, which is technically UB in Rust because Vec tells Rust its pointer is non-null (this is why Option<Vec<T>> has the same size as Vec<T>). align_of::<T> is what it uses to as a non-null junk pointer, which in this case is 1.
MozReview-Commit-ID: Gzy1NtKlSV7
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -419,40 +419,43 @@ static inline WrExternalImage NativeText
aHandle, u0, v0, u1, v1,
nullptr, 0
};
}
struct VecU8 {
WrVecU8 inner;
VecU8() {
- inner.data = nullptr;
- inner.capacity = 0;
+ SetEmpty();
}
VecU8(VecU8&) = delete;
VecU8(VecU8&& src) {
inner = src.inner;
- src.inner.data = nullptr;
- src.inner.capacity = 0;
+ src.SetEmpty();
}
VecU8&
operator=(VecU8&& src) {
inner = src.inner;
- src.inner.data = nullptr;
- src.inner.capacity = 0;
+ src.SetEmpty();
return *this;
}
WrVecU8
Extract() {
WrVecU8 ret = inner;
- inner.data = nullptr;
+ SetEmpty();
+ return ret;
+ }
+
+ void
+ SetEmpty() {
+ inner.data = (uint8_t*)1;
inner.capacity = 0;
- return ret;
+ inner.length = 0;
}
~VecU8() {
if (inner.data) {
wr_vec_u8_free(inner);
}
}
};