mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Don't leak FlowRef
s to the flexbox layout code.
This can cause memory safety problems. Comments have been added to `flow_list.rs` to prevent this from happening again.
This commit is contained in:
parent
179547b68f
commit
d990a7eb84
2 changed files with 100 additions and 76 deletions
|
@ -5,10 +5,17 @@
|
|||
use flow::Flow;
|
||||
use flow_ref::{self, FlowRef};
|
||||
use std::collections::{LinkedList, linked_list};
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
// This needs to be reworked now that we have dynamically-sized types in Rust.
|
||||
// Until then, it's just a wrapper around LinkedList.
|
||||
|
||||
/// This needs to be reworked now that we have dynamically-sized types in Rust.
|
||||
/// Until then, it's just a wrapper around LinkedList.
|
||||
///
|
||||
/// SECURITY-NOTE(pcwalton): It is very important that `FlowRef` values not leak directly to
|
||||
/// layout. Layout code must only interact with `&Flow` or `&mut Flow` values. Otherwise, layout
|
||||
/// could stash `FlowRef` values in random places unknown to the system and thereby cause data
|
||||
/// races. Those data races can lead to memory safety problems, potentially including arbitrary
|
||||
/// remote code execution! In general, do not add new methods to this file (e.g. new ways of
|
||||
/// iterating over flows) unless you are *very* sure of what you are doing.
|
||||
pub struct FlowList {
|
||||
flows: LinkedList<FlowRef>,
|
||||
}
|
||||
|
@ -52,13 +59,19 @@ impl FlowList {
|
|||
}
|
||||
}
|
||||
|
||||
/// Provide a forward iterator
|
||||
/// Provide a forward iterator.
|
||||
///
|
||||
/// SECURITY-NOTE(pcwalton): This does not hand out `FlowRef`s by design. Do not add a method
|
||||
/// to do so! See the comment above in `FlowList`.
|
||||
#[inline]
|
||||
pub fn iter<'a>(&'a self) -> impl DoubleEndedIterator<Item = &'a Flow> {
|
||||
self.flows.iter().map(|flow| &**flow)
|
||||
}
|
||||
|
||||
/// Provide a forward iterator with mutable references
|
||||
///
|
||||
/// SECURITY-NOTE(pcwalton): This does not hand out `FlowRef`s by design. Do not add a method
|
||||
/// to do so! See the comment above in `FlowList`.
|
||||
#[inline]
|
||||
pub fn iter_mut(&mut self) -> MutFlowListIterator {
|
||||
MutFlowListIterator {
|
||||
|
@ -66,13 +79,6 @@ impl FlowList {
|
|||
}
|
||||
}
|
||||
|
||||
/// Provide a forward iterator with FlowRef items
|
||||
#[inline]
|
||||
pub fn iter_flow_ref_mut<'a>(&'a mut self)
|
||||
-> impl DoubleEndedIterator<Item = &'a mut FlowRef> {
|
||||
self.flows.iter_mut()
|
||||
}
|
||||
|
||||
/// O(1)
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
|
@ -93,6 +99,21 @@ impl FlowList {
|
|||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for FlowList {
|
||||
/// FIXME(pcwalton): O(n)!
|
||||
type Output = Flow;
|
||||
fn index(&self, index: usize) -> &Flow {
|
||||
&**self.flows.iter().nth(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<usize> for FlowList {
|
||||
/// FIXME(pcwalton): O(n)!
|
||||
fn index_mut(&mut self, index: usize) -> &mut Flow {
|
||||
self.iter_mut().nth(index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DoubleEndedIterator for MutFlowListIterator<'a> {
|
||||
fn next_back(&mut self) -> Option<&'a mut Flow> {
|
||||
self.it.next_back().map(flow_ref::deref_mut)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue