Bug 1568395 - Add more useful error messages to webrender_api. r=kamidphish

Differential Revision: https://phabricator.services.mozilla.com/D39236

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alexis Beingessner 2019-07-24 22:55:51 +00:00
parent 3bd09021a9
commit e64ad7178d
3 changed files with 19 additions and 10 deletions

View File

@ -85,7 +85,8 @@ fn derive_peek_from_for_enum(s: &mut Structure) -> TokenStream {
assert!(!is_struct(s)); assert!(!is_struct(s));
s.bind_with(|_| BindStyle::Move); s.bind_with(|_| BindStyle::Move);
let discriminant_size_type = get_discriminant_size_type(s.variants().len()); let num_variants = s.variants().len();
let discriminant_size_type = get_discriminant_size_type(num_variants);
let body = s let body = s
.variants() .variants()
.iter() .iter()
@ -119,13 +120,19 @@ fn derive_peek_from_for_enum(s: &mut Structure) -> TokenStream {
} }
}); });
let type_name = s.ast().ident.to_string();
let max_tag_value = num_variants - 1;
quote! { quote! {
#[inline(always)] #[inline(always)]
unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 { unsafe fn peek_from(bytes: *const u8, output: *mut Self) -> *const u8 {
let (variant, bytes) = peek_poke::peek_from_default::<#discriminant_size_type>(bytes); let (variant, bytes) = peek_poke::peek_from_default::<#discriminant_size_type>(bytes);
match variant { match variant {
#body #body
_ => unreachable!() out_of_range_tag => {
panic!("WRDL: memory corruption detected while parsing {} - enum tag should be <= {}, but was {}",
#type_name, #max_tag_value, out_of_range_tag);
}
} }
} }
} }

View File

@ -53,19 +53,19 @@ pub unsafe fn peek_from_default<T: Default + Peek>(bytes: *const u8) -> (T, *con
pub fn peek_from_slice<'a, T: Peek>(src: &'a [u8], dst: &mut T) -> &'a [u8] { pub fn peek_from_slice<'a, T: Peek>(src: &'a [u8], dst: &mut T) -> &'a [u8] {
unsafe { unsafe {
// If src.len() == T::max_size() then src is at the start of the red-zone. // If src.len() == T::max_size() then src is at the start of the red-zone.
assert!(T::max_size() < src.len()); assert!(T::max_size() < src.len(), "WRDL: unexpected end of display list");
let end_ptr = T::peek_from(src.as_ptr(), dst); let end_ptr = T::peek_from(src.as_ptr(), dst);
let len = end_ptr as usize - src.as_ptr() as usize; let len = end_ptr as usize - src.as_ptr() as usize;
// Did someone break the T::peek_from() can't read more than T::max_size() // Did someone break the T::peek_from() can't read more than T::max_size()
// bytes contract? // bytes contract?
assert!(len <= src.len()); assert!(len <= src.len(), "WRDL: Peek::max_size was wrong");
slice::from_raw_parts(end_ptr, src.len() - len) slice::from_raw_parts(end_ptr, src.len() - len)
} }
} }
/// Poke helper to insert a serialized version of `src` at the beginning for `dst`. /// Poke helper to insert a serialized version of `src` at the beginning for `dst`.
pub fn poke_inplace_slice<T: Poke>(src: &T, dst: &mut [u8]) { pub fn poke_inplace_slice<T: Poke>(src: &T, dst: &mut [u8]) {
assert!(T::max_size() <= dst.len()); assert!(T::max_size() <= dst.len(), "WRDL: buffer too small to write into");
unsafe { unsafe {
src.poke_into(dst.as_mut_ptr()); src.poke_into(dst.as_mut_ptr());
} }

View File

@ -430,7 +430,6 @@ impl<'a> BuiltDisplayListIter<'a> {
di::DisplayItem::PopStackingContext => depth -= 1, di::DisplayItem::PopStackingContext => depth -= 1,
_ => {} _ => {}
} }
debug_assert!(depth >= 0);
} }
} }
@ -590,12 +589,14 @@ impl Serialize for BuiltDisplayList {
item.iter.cur_filters.iter().collect() item.iter.cur_filters.iter().collect()
), ),
Real::SetFilterData => { Real::SetFilterData => {
debug_assert!(!item.iter.cur_filter_data.is_empty()); debug_assert!(!item.iter.cur_filter_data.is_empty(),
"next_raw should have populated cur_filter_data");
let temp_filter_data = &item.iter.cur_filter_data[item.iter.cur_filter_data.len()-1]; let temp_filter_data = &item.iter.cur_filter_data[item.iter.cur_filter_data.len()-1];
let func_types: Vec<di::ComponentTransferFuncType> = let func_types: Vec<di::ComponentTransferFuncType> =
temp_filter_data.func_types.iter().collect(); temp_filter_data.func_types.iter().collect();
debug_assert!(func_types.len() == 4); debug_assert!(func_types.len() == 4,
"someone changed the number of filter funcs without updating this code");
Debug::SetFilterData(di::FilterData { Debug::SetFilterData(di::FilterData {
func_r_type: func_types[0], func_r_type: func_types[0],
r_values: temp_filter_data.r_values.iter().collect(), r_values: temp_filter_data.r_values.iter().collect(),
@ -910,14 +911,15 @@ impl DisplayListBuilder {
poke_into_vec(&0usize, data); poke_into_vec(&0usize, data);
poke_into_vec(&len, data); poke_into_vec(&len, data);
let count = poke_extend_vec(iter, data); let count = poke_extend_vec(iter, data);
debug_assert_eq!(len, count); debug_assert_eq!(len, count, "iterator.len() returned two different values");
// Add red zone // Add red zone
ensure_red_zone::<I::Item>(data); ensure_red_zone::<I::Item>(data);
// Now write the actual byte_size // Now write the actual byte_size
let final_offset = data.len(); let final_offset = data.len();
debug_assert!(final_offset >= (byte_size_offset + mem::size_of::<usize>())); debug_assert!(final_offset >= (byte_size_offset + mem::size_of::<usize>()),
"space was never allocated for this array's byte_size");
let byte_size = final_offset - byte_size_offset - mem::size_of::<usize>(); let byte_size = final_offset - byte_size_offset - mem::size_of::<usize>();
poke_inplace_slice(&byte_size, &mut data[byte_size_offset..]); poke_inplace_slice(&byte_size, &mut data[byte_size_offset..]);
} }