layout: Don't crash if quotes: none is specified and generated content

uses quotes.

Avoids a crash on The Verge.
This commit is contained in:
Patrick Walton 2015-08-24 11:43:43 -07:00
parent 524b02dbf7
commit 35c67b22e5
7 changed files with 36 additions and 23 deletions

View file

@ -213,11 +213,11 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
RenderingMode::All(&separator)); RenderingMode::All(&separator));
} }
GeneratedContentInfo::ContentItem(ContentItem::OpenQuote) => { GeneratedContentInfo::ContentItem(ContentItem::OpenQuote) => {
new_info = Some(render_text(self.traversal.layout_context, new_info = render_text(self.traversal.layout_context,
fragment.node, fragment.node,
fragment.pseudo, fragment.pseudo,
fragment.style.clone(), fragment.style.clone(),
self.quote(&*fragment.style, false))); self.quote(&*fragment.style, false));
self.traversal.quote += 1 self.traversal.quote += 1
} }
GeneratedContentInfo::ContentItem(ContentItem::CloseQuote) => { GeneratedContentInfo::ContentItem(ContentItem::CloseQuote) => {
@ -225,11 +225,11 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
self.traversal.quote -= 1 self.traversal.quote -= 1
} }
new_info = Some(render_text(self.traversal.layout_context, new_info = render_text(self.traversal.layout_context,
fragment.node, fragment.node,
fragment.pseudo, fragment.pseudo,
fragment.style.clone(), fragment.style.clone(),
self.quote(&*fragment.style, true))); self.quote(&*fragment.style, true));
} }
GeneratedContentInfo::ContentItem(ContentItem::NoOpenQuote) => { GeneratedContentInfo::ContentItem(ContentItem::NoOpenQuote) => {
self.traversal.quote += 1 self.traversal.quote += 1
@ -277,10 +277,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
self.traversal.counters.insert((*counter_name).clone(), counter); self.traversal.counters.insert((*counter_name).clone(), counter);
} }
for &(ref counter_name, value) in &fragment.style() for &(ref counter_name, value) in &fragment.style().get_counters().counter_increment.0 {
.get_counters()
.counter_increment
.0 {
if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) { if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
counter.increment(self.level, value); counter.increment(self.level, value);
continue continue
@ -296,7 +293,9 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
fn quote(&self, style: &ComputedValues, close: bool) -> String { fn quote(&self, style: &ComputedValues, close: bool) -> String {
let quotes = &style.get_list().quotes; let quotes = &style.get_list().quotes;
debug_assert!(!quotes.0.is_empty()); if quotes.0.is_empty() {
return String::new()
}
let &(ref open_quote, ref close_quote) = let &(ref open_quote, ref close_quote) =
if self.traversal.quote as usize >= quotes.0.len() { if self.traversal.quote as usize >= quotes.0.len() {
quotes.0.last().unwrap() quotes.0.last().unwrap()
@ -398,7 +397,7 @@ impl Counter {
if string.is_empty() { if string.is_empty() {
None None
} else { } else {
Some(render_text(layout_context, node, pseudo, style, string)) render_text(layout_context, node, pseudo, style, string)
} }
} }
} }
@ -427,7 +426,7 @@ fn render_text(layout_context: &LayoutContext,
pseudo: PseudoElementType<()>, pseudo: PseudoElementType<()>,
style: Arc<ComputedValues>, style: Arc<ComputedValues>,
string: String) string: String)
-> SpecificFragmentInfo { -> Option<SpecificFragmentInfo> {
let mut fragments = LinkedList::new(); let mut fragments = LinkedList::new();
let info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(string)); let info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(string));
fragments.push_back(Fragment::from_opaque_node_and_style(node, fragments.push_back(Fragment::from_opaque_node_and_style(node,
@ -437,9 +436,13 @@ fn render_text(layout_context: &LayoutContext,
info)); info));
// FIXME(pcwalton): This should properly handle multiple marker fragments. This could happen // FIXME(pcwalton): This should properly handle multiple marker fragments. This could happen
// due to text run splitting. // due to text run splitting.
let fragments = TextRunScanner::new().scan_for_runs(&mut layout_context.font_context(), fragments); let fragments = TextRunScanner::new().scan_for_runs(&mut layout_context.font_context(),
debug_assert!(fragments.len() >= 1); fragments);
fragments.fragments.into_iter().next().unwrap().specific if fragments.is_empty() {
None
} else {
Some(fragments.fragments.into_iter().next().unwrap().specific)
}
} }
/// Appends string that represents the value rendered using the system appropriate for the given /// Appends string that represents the value rendered using the system appropriate for the given

View file

@ -298,6 +298,7 @@ flaky_cpu == linebreak_simple_a.html linebreak_simple_b.html
== pre_with_tab.html pre_with_tab_ref.html == pre_with_tab.html pre_with_tab_ref.html
== pseudo_element_a.html pseudo_element_b.html == pseudo_element_a.html pseudo_element_b.html
== pseudo_inherit.html pseudo_inherit_ref.html == pseudo_inherit.html pseudo_inherit_ref.html
== quotes_none_a.html quotes_none_ref.html
== quotes_simple_a.html quotes_simple_ref.html == quotes_simple_a.html quotes_simple_ref.html
== root_height_a.html root_height_b.html == root_height_a.html root_height_b.html
== root_margin_collapse_a.html root_margin_collapse_b.html == root_margin_collapse_a.html root_margin_collapse_b.html

View file

@ -0,0 +1,7 @@
<!DOCTYPE html>
<style>
q {
quotes: none;
}
</style>
<q>Don't crash!

View file

@ -0,0 +1,2 @@
<!DOCTYPE html>
Don't crash!

View file

@ -1,3 +1,3 @@
[quotes-035.htm] [quotes-035.htm]
type: reftest type: reftest
expected: CRASH expected: FAIL

View file

@ -1,3 +1,3 @@
[quotes-035a.htm] [quotes-035a.htm]
type: reftest type: reftest
expected: CRASH expected: FAIL

View file

@ -1,3 +1,3 @@
[quotes-036.htm] [quotes-036.htm]
type: reftest type: reftest
expected: CRASH expected: FAIL